Skip to content

Commit

Permalink
feat: add webauthn to list of identifiers
Browse files Browse the repository at this point in the history
This patch adds the key `webauthn` to the list of possible identifiers in the Identity JSON Schema. Use this key to specify what field is used to find the WebAuthn credentials on passwordless login flows.
  • Loading branch information
aeneasr committed Mar 7, 2022
1 parent 4dbe0ea commit 1a8b256
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 2 deletions.
17 changes: 17 additions & 0 deletions identity/extension_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func NewSchemaExtensionCredentials(i *Identity) *SchemaExtensionCredentials {
func (r *SchemaExtensionCredentials) Run(_ jsonschema.ValidationContext, s schema.ExtensionConfig, value interface{}) error {
r.l.Lock()
defer r.l.Unlock()

if s.Credentials.Password.Identifier {
cred, ok := r.i.GetCredentials(CredentialsTypePassword)
if !ok {
Expand All @@ -39,6 +40,22 @@ func (r *SchemaExtensionCredentials) Run(_ jsonschema.ValidationContext, s schem
cred.Identifiers = r.v
r.i.SetCredentials(CredentialsTypePassword, *cred)
}

if s.Credentials.WebAuthn.Identifier {
cred, ok := r.i.GetCredentials(CredentialsTypeWebAuthn)
if !ok {
cred = &Credentials{
Type: CredentialsTypeWebAuthn,
Identifiers: []string{},
Config: sqlxx.JSONRawMessage{},
}
}

r.v = stringslice.Unique(append(r.v, strings.ToLower(fmt.Sprintf("%s", value))))
cred.Identifiers = r.v
r.i.SetCredentials(CredentialsTypeWebAuthn, *cred)
}

return nil
}

Expand Down
23 changes: 21 additions & 2 deletions identity/extension_credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,19 @@ func TestSchemaExtensionCredentials(t *testing.T) {
doc string
expect []string
existing *identity.Credentials
ct identity.CredentialsType
}{
{
doc: `{"email":"[email protected]"}`,
schema: "file://./stub/extension/credentials/schema.json",
expect: []string{"[email protected]"},
ct: identity.CredentialsTypePassword,
},
{
doc: `{"emails":["[email protected]","[email protected]","[email protected]"], "username": "foobar"}`,
schema: "file://./stub/extension/credentials/multi.schema.json",
expect: []string{"[email protected]", "[email protected]", "foobar"},
ct: identity.CredentialsTypePassword,
},
{
doc: `{"emails":["[email protected]","[email protected]"], "username": "foobar"}`,
Expand All @@ -43,6 +46,22 @@ func TestSchemaExtensionCredentials(t *testing.T) {
existing: &identity.Credentials{
Identifiers: []string{"[email protected]"},
},
ct: identity.CredentialsTypePassword,
},
{
doc: `{"email":"[email protected]"}`,
schema: "file://./stub/extension/credentials/webauthn.schema.json",
expect: []string{"[email protected]"},
ct: identity.CredentialsTypeWebAuthn,
},
{
doc: `{"email":"[email protected]"}`,
schema: "file://./stub/extension/credentials/webauthn.schema.json",
expect: []string{"[email protected]"},
existing: &identity.Credentials{
Identifiers: []string{"[email protected]"},
},
ct: identity.CredentialsTypeWebAuthn,
},
} {
t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) {
Expand All @@ -53,7 +72,7 @@ func TestSchemaExtensionCredentials(t *testing.T) {
i := new(identity.Identity)
e := identity.NewSchemaExtensionCredentials(i)
if tc.existing != nil {
i.SetCredentials(identity.CredentialsTypePassword, *tc.existing)
i.SetCredentials(tc.ct, *tc.existing)
}

runner.AddRunner(e).Register(c)
Expand All @@ -63,7 +82,7 @@ func TestSchemaExtensionCredentials(t *testing.T) {
}
require.NoError(t, e.Finish())

credentials, ok := i.GetCredentials(identity.CredentialsTypePassword)
credentials, ok := i.GetCredentials(tc.ct)
require.True(t, ok)
assert.ElementsMatch(t, tc.expect, credentials.Identifiers)
})
Expand Down
19 changes: 19 additions & 0 deletions identity/stub/extension/credentials/webauthn.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email",
"ory.sh/kratos": {
"credentials": {
"password": {
"identifier": true
},
"webauthn": {
"identifier": true
}
}
}
}
}
}
3 changes: 3 additions & 0 deletions schema/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ type (
Password struct {
Identifier bool `json:"identifier"`
} `json:"password"`
WebAuthn struct {
Identifier bool `json:"identifier"`
} `json:"webauthn"`
TOTP struct {
AccountName bool `json:"account_name"`
} `json:"totp"`
Expand Down

0 comments on commit 1a8b256

Please sign in to comment.