snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
260
identity/credentials_test.go
Normal file
260
identity/credentials_test.go
Normal file
@@ -0,0 +1,260 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package identity
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/mohae/deepcopy"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ory/x/sqlxx"
|
||||
)
|
||||
|
||||
func TestCredentialsEqual(t *testing.T) {
|
||||
original := map[CredentialsType]Credentials{
|
||||
"foo": {Type: "foo", Identifiers: []string{"bar"}, Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`)},
|
||||
}
|
||||
|
||||
derived := deepcopy.Copy(original).(map[CredentialsType]Credentials)
|
||||
assert.EqualValues(t, original, derived)
|
||||
derived["foo"].Identifiers[0] = "baz"
|
||||
assert.NotEqual(t, original, derived)
|
||||
}
|
||||
|
||||
func TestAALOrder(t *testing.T) {
|
||||
assert.True(t, NoAuthenticatorAssuranceLevel < AuthenticatorAssuranceLevel1)
|
||||
assert.True(t, AuthenticatorAssuranceLevel1 < AuthenticatorAssuranceLevel2)
|
||||
}
|
||||
|
||||
func TestParseCredentialsType(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
input string
|
||||
expected CredentialsType
|
||||
}{
|
||||
{"password", CredentialsTypePassword},
|
||||
{"oidc", CredentialsTypeOIDC},
|
||||
{"totp", CredentialsTypeTOTP},
|
||||
{"webauthn", CredentialsTypeWebAuthn},
|
||||
{"deviceauthn", CredentialsTypeDeviceAuthn},
|
||||
{"lookup_secret", CredentialsTypeLookup},
|
||||
{"link_recovery", CredentialsTypeRecoveryLink},
|
||||
{"code_recovery", CredentialsTypeRecoveryCode},
|
||||
} {
|
||||
t.Run("case="+tc.input, func(t *testing.T) {
|
||||
actual, ok := ParseCredentialsType(tc.input)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, tc.expected, actual)
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("case=unknown", func(t *testing.T) {
|
||||
_, ok := ParseCredentialsType("unknown")
|
||||
require.False(t, ok)
|
||||
})
|
||||
}
|
||||
|
||||
func TestCredentials_Hash(t *testing.T) {
|
||||
baseID := uuid.Must(uuid.NewV4())
|
||||
baseNID := uuid.Must(uuid.NewV4())
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
cred1 Credentials
|
||||
cred2 Credentials
|
||||
expectEqual bool
|
||||
description string
|
||||
}{
|
||||
{
|
||||
name: "same json with different whitespace",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar","baz":"qux"}`),
|
||||
Version: 1,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{
|
||||
"foo": "bar",
|
||||
"baz": "qux"
|
||||
}`),
|
||||
Version: 1,
|
||||
},
|
||||
expectEqual: true,
|
||||
description: "hashes should be equal for same JSON with different whitespace",
|
||||
},
|
||||
{
|
||||
name: "same json with different key order",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeCodeAuth,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"addresses":[{"address":"test@example.com","channel":"email"}]}`),
|
||||
Version: 1,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeCodeAuth,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"addresses":[{"channel":"email","address":"test@example.com"}]}`),
|
||||
Version: 1,
|
||||
},
|
||||
expectEqual: true,
|
||||
description: "hashes should be equal for same JSON with different key order",
|
||||
},
|
||||
{
|
||||
name: "nested json with different key order",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeWebAuthn,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"credentials":[{"id":"abc","public_key":"xyz","type":"webauthn"}]}`),
|
||||
Version: 1,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeWebAuthn,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"credentials":[{"type":"webauthn","public_key":"xyz","id":"abc"}]}`),
|
||||
Version: 1,
|
||||
},
|
||||
expectEqual: true,
|
||||
description: "hashes should be equal for nested JSON with different key order",
|
||||
},
|
||||
{
|
||||
name: "same identifiers in different order",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"a@example.com", "b@example.com", "c@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{}`),
|
||||
Version: 1,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"c@example.com", "a@example.com", "b@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{}`),
|
||||
Version: 1,
|
||||
},
|
||||
expectEqual: true,
|
||||
description: "hashes should be equal for same identifiers in different order",
|
||||
},
|
||||
{
|
||||
name: "different json config",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"different"}`),
|
||||
Version: 1,
|
||||
},
|
||||
expectEqual: false,
|
||||
description: "hashes should be different for different JSON content",
|
||||
},
|
||||
{
|
||||
name: "different types",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypePassword,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
},
|
||||
expectEqual: false,
|
||||
description: "hashes should be different for different types",
|
||||
},
|
||||
{
|
||||
name: "different identifiers",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test1@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test2@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
},
|
||||
expectEqual: false,
|
||||
description: "hashes should be different for different identifiers",
|
||||
},
|
||||
{
|
||||
name: "different versions",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 2,
|
||||
},
|
||||
expectEqual: false,
|
||||
description: "hashes should be different for different versions",
|
||||
},
|
||||
{
|
||||
name: "different identity IDs",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
IdentityID: baseID,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
IdentityID: uuid.Must(uuid.NewV4()),
|
||||
},
|
||||
expectEqual: false,
|
||||
description: "hashes should be different for different identity IDs",
|
||||
},
|
||||
{
|
||||
name: "different NIDs",
|
||||
cred1: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
NID: baseNID,
|
||||
},
|
||||
cred2: Credentials{
|
||||
Type: CredentialsTypeOIDC,
|
||||
Identifiers: []string{"test@example.com"},
|
||||
Config: sqlxx.JSONRawMessage(`{"foo":"bar"}`),
|
||||
Version: 1,
|
||||
NID: uuid.Must(uuid.NewV4()),
|
||||
},
|
||||
expectEqual: false,
|
||||
description: "hashes should be different for different NIDs",
|
||||
},
|
||||
} {
|
||||
t.Run("case="+tc.name, func(t *testing.T) {
|
||||
hash1 := tc.cred1.Signature()
|
||||
hash2 := tc.cred2.Signature()
|
||||
|
||||
if tc.expectEqual {
|
||||
assert.Equal(t, hash1, hash2, tc.description)
|
||||
} else {
|
||||
assert.NotEqual(t, hash1, hash2, tc.description)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user