-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: unit testing, mocks, and code cleanup
tests: added unit testing, mocks, and general code improvement
- Loading branch information
Showing
37 changed files
with
1,076 additions
and
150 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
with-expecter: true | ||
dir: "{{.InterfaceDir}}/mocks" | ||
outpkg: mocks | ||
packages: | ||
github.com/spiretechnology/go-webauthn: | ||
config: | ||
dir: "internal/mocks" | ||
interfaces: | ||
Challenges: | ||
Credentials: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package webauthn | ||
|
||
// AuthType defines a set of methods of authentication (eg. hardware key, biometric, etc). | ||
type AuthType uint8 | ||
|
||
const ( | ||
// HardwareKey is a hardware authenticator. | ||
HardwareKey = AuthType(1 << iota) | ||
// Biometric is a fingerprint or face scan. | ||
Biometric | ||
// AllAuthTypes is a bitmask of all auth types. | ||
AllAuthTypes = AuthType(0xFF) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package webauthn_test | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"testing" | ||
|
||
"github.com/spiretechnology/go-webauthn" | ||
"github.com/spiretechnology/go-webauthn/internal/testutil" | ||
"github.com/stretchr/testify/mock" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestCreateAuthentication(t *testing.T) { | ||
ctx := context.Background() | ||
for _, tc := range testCases { | ||
tcChallenge := tc.AuthenticationChallenge() | ||
|
||
t.Run(tc.Name, func(t *testing.T) { | ||
t.Run("user has no credentials", func(t *testing.T) { | ||
w, credentials, challenges := setupMocks(nil) | ||
credentials.On("GetCredentials", ctx, tc.User).Return([]webauthn.Credential{}, nil).Once() | ||
|
||
challenge, err := w.CreateAuthentication(ctx, tc.User) | ||
require.Nil(t, challenge, "challenge should be nil") | ||
require.ErrorIs(t, err, webauthn.ErrNoCredentials, "error should be ErrNoCredentials") | ||
|
||
credentials.AssertExpectations(t) | ||
challenges.AssertExpectations(t) | ||
}) | ||
|
||
t.Run("storing challenge fails", func(t *testing.T) { | ||
w, credentials, challenges := setupMocks(nil) | ||
credentials.On("GetCredentials", ctx, tc.User).Return([]webauthn.Credential{*tc.Credential()}, nil).Once() | ||
challenges.On("StoreChallenge", mock.Anything, tc.User, mock.Anything).Return(errors.New("test error")).Once() | ||
|
||
challenge, err := w.CreateAuthentication(ctx, tc.User) | ||
require.Nil(t, challenge, "challenge should be nil") | ||
require.Error(t, err, "error should not be nil") | ||
|
||
credentials.AssertExpectations(t) | ||
challenges.AssertExpectations(t) | ||
}) | ||
|
||
t.Run("creates authentication successfully", func(t *testing.T) { | ||
w, credentials, challenges := setupMocks(&webauthn.Options{ | ||
ChallengeFunc: func() ([32]byte, error) { | ||
return tcChallenge, nil | ||
}, | ||
}) | ||
credentials.On("GetCredentials", ctx, tc.User).Return([]webauthn.Credential{*tc.Credential()}, nil).Once() | ||
challenges.On("StoreChallenge", mock.Anything, tc.User, mock.Anything).Return(nil).Once() | ||
|
||
challenge, err := w.CreateAuthentication(ctx, tc.User) | ||
require.NotNil(t, challenge, "challenge should not be nil") | ||
require.Nil(t, err, "error should be nil") | ||
|
||
require.Equal(t, testutil.Encode(tcChallenge[:]), challenge.Challenge, "challenge should match") | ||
require.Equal(t, testRP.ID, challenge.RPID, "relying party should match") | ||
require.Equal(t, 1, len(challenge.AllowCredentials), "allow credentials should match") | ||
|
||
credentials.AssertExpectations(t) | ||
challenges.AssertExpectations(t) | ||
}) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package webauthn_test | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/spiretechnology/go-webauthn" | ||
"github.com/stretchr/testify/mock" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestVerifyAuthentication(t *testing.T) { | ||
ctx := context.Background() | ||
for _, tc := range testCases { | ||
tcChallenge := tc.AuthenticationChallenge() | ||
|
||
t.Run(tc.Name, func(t *testing.T) { | ||
t.Run("challenge doesn't exist", func(t *testing.T) { | ||
w, credentials, challenges := setupMocks(nil) | ||
challenges.On("HasChallenge", mock.Anything, tc.User, tcChallenge).Return(false, nil).Once() | ||
|
||
result, err := w.VerifyAuthentication(ctx, tc.User, tc.AuthenticationResponse()) | ||
require.Nil(t, result, "result should be nil") | ||
require.ErrorIs(t, err, webauthn.ErrUnrecognizedChallenge, "error should be errTest") | ||
|
||
credentials.AssertExpectations(t) | ||
challenges.AssertExpectations(t) | ||
}) | ||
|
||
t.Run("verifies registration successfully", func(t *testing.T) { | ||
w, credentials, challenges := setupMocks(&webauthn.Options{ | ||
ChallengeFunc: func() ([32]byte, error) { | ||
return tcChallenge, nil | ||
}, | ||
}) | ||
challenges.On("HasChallenge", mock.Anything, tc.User, tcChallenge).Return(true, nil).Once() | ||
challenges.On("RemoveChallenge", mock.Anything, tc.User, tcChallenge).Return(nil).Once() | ||
credentials.On("GetCredential", mock.Anything, tc.User, mock.Anything).Return(tc.Credential(), nil).Once() | ||
|
||
result, err := w.VerifyAuthentication(ctx, tc.User, tc.AuthenticationResponse()) | ||
require.Nil(t, err, "error should be nil") | ||
require.NotNil(t, result, "result should not be nil") | ||
|
||
credentials.AssertExpectations(t) | ||
challenges.AssertExpectations(t) | ||
}) | ||
|
||
// t.Run("fails with invalid public key alg", func(t *testing.T) { | ||
// w, users, credentials, challenges := setupMocks(&webauthn.Options{ | ||
// ChallengeFunc: func() ([32]byte, error) { | ||
// return tcChallenge, nil | ||
// }, | ||
// }) | ||
// challenges.On("HasChallenge", mock.Anything, tc.User, tcChallenge).Return(true, nil).Once() | ||
// challenges.On("RemoveChallenge", mock.Anything, tc.User, tcChallenge).Return(nil).Once() | ||
// users.On("GetUser", ctx, tc.User).Return(&tc.User, nil).Once() | ||
|
||
// // Switch to an unsupported public key alg | ||
// res := tc.AuthenticationResponse() | ||
// res.PublicKeyAlg = 0 | ||
|
||
// result, err := w.VerifyAuthentication(ctx, tc.User, res) | ||
// require.Nil(t, result, "result should be nil") | ||
// require.Error(t, err, "error should not be nil") | ||
|
||
// users.AssertExpectations(t) | ||
// challenges.AssertExpectations(t) | ||
// credentials.AssertExpectations(t) | ||
// }) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,22 @@ | ||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= | ||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= | ||
github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= | ||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= | ||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= | ||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= | ||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | ||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | ||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= | ||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= | ||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | ||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= |
Oops, something went wrong.