Files
upstream-ory-kratos/identity/credentials_test.go
upstream-mirror c60cc7ca75
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
snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
2026-09-15 21:19:12 +05:00

261 lines
7.6 KiB
Go

// 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)
}
})
}
}