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:
194
identity/credentials_migrate_test.go
Normal file
194
identity/credentials_migrate_test.go
Normal file
@@ -0,0 +1,194 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package identity
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"testing"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ory/x/snapshotx"
|
||||
)
|
||||
|
||||
//go:embed stub/webauthn/v0.json
|
||||
var webAuthnV0 []byte
|
||||
|
||||
//go:embed stub/webauthn/v1.json
|
||||
var webAuthnV1 []byte
|
||||
|
||||
func TestUpgradeCredentials(t *testing.T) {
|
||||
t.Run("empty credentials", func(t *testing.T) {
|
||||
i := &Identity{}
|
||||
|
||||
err := UpgradeCredentials(i)
|
||||
require.NoError(t, err)
|
||||
wc := WithCredentialsAndAdminMetadataInJSON(*i)
|
||||
snapshotx.SnapshotTExcept(t, &wc, nil)
|
||||
})
|
||||
|
||||
run := func(t *testing.T, identifiers []string, config string, version int, credentialsType CredentialsType, expectedVersion int) {
|
||||
if identifiers == nil {
|
||||
identifiers = []string{"hi@example.org"}
|
||||
}
|
||||
i := &Identity{
|
||||
ID: uuid.FromStringOrNil("4d64fa08-20fc-450d-bebd-ebd7c7b6e249"),
|
||||
Credentials: map[CredentialsType]Credentials{
|
||||
credentialsType: {
|
||||
Identifiers: identifiers,
|
||||
Type: credentialsType,
|
||||
Version: version,
|
||||
Config: []byte(config),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, UpgradeCredentials(i))
|
||||
wc := WithCredentialsAndAdminMetadataInJSON(*i)
|
||||
snapshotx.SnapshotT(t, &wc)
|
||||
assert.Equal(t, expectedVersion, i.Credentials[credentialsType].Version)
|
||||
}
|
||||
|
||||
t.Run("type=code", func(t *testing.T) {
|
||||
t.Run("from=v0 with email empty space value", func(t *testing.T) {
|
||||
t.Run("with one identifier", func(t *testing.T) {
|
||||
run(t, nil, `{"address_type": "email ", "used_at": {"Time": "0001-01-01T00:00:00Z", "Valid": false}}`, 0, CredentialsTypeCodeAuth, 1)
|
||||
})
|
||||
|
||||
t.Run("with two identifiers", func(t *testing.T) {
|
||||
run(t, []string{"foo@example.org", "bar@example.org"}, `{"address_type": "email ", "used_at": {"Time": "0001-01-01T00:00:00Z", "Valid": false}}`, 0, CredentialsTypeCodeAuth, 1)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("from=v0 with empty value", func(t *testing.T) {
|
||||
run(t, nil, `{"address_type": "", "used_at": {"Time": "0001-01-01T00:00:00Z", "Valid": false}}`, 0, CredentialsTypeCodeAuth, 1)
|
||||
})
|
||||
|
||||
t.Run("from=v0 with correct value", func(t *testing.T) {
|
||||
run(t, nil, `{"address_type": "email", "used_at": {"Time": "0001-01-01T00:00:00Z", "Valid": false}}`, 0, CredentialsTypeCodeAuth, 1)
|
||||
})
|
||||
|
||||
t.Run("from=v0 with unknown value", func(t *testing.T) {
|
||||
run(t, nil, `{"address_type": "other", "used_at": {"Time": "0001-01-01T00:00:00Z", "Valid": false}}`, 0, CredentialsTypeCodeAuth, 1)
|
||||
})
|
||||
|
||||
t.Run("from=v2 with empty value", func(t *testing.T) {
|
||||
run(t, []string{"foo@example.org", "+12341234"}, `{"addresses": [{"address":"foo@example.org","channel":"email"},{"address":"+12341234","channel":"sms"}]}`, 1, CredentialsTypeCodeAuth, 1)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("type=webauthn", func(t *testing.T) {
|
||||
t.Run("from=v0", func(t *testing.T) {
|
||||
run(t, []string{"4d64fa08-20fc-450d-bebd-ebd7c7b6e249"}, string(webAuthnV0), 0, CredentialsTypeWebAuthn, 1)
|
||||
})
|
||||
|
||||
t.Run("from=v1", func(t *testing.T) {
|
||||
run(t, []string{}, string(webAuthnV1), 1, CredentialsTypeWebAuthn, 1)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("type=password", func(t *testing.T) {
|
||||
t.Run("from=v0 with phone number", func(t *testing.T) {
|
||||
i := &Identity{
|
||||
ID: uuid.FromStringOrNil("4d64fa08-20fc-450d-bebd-ebd7c7b6e249"),
|
||||
Credentials: map[CredentialsType]Credentials{
|
||||
CredentialsTypePassword: {
|
||||
Identifiers: []string{"+49 176 671 11 638"},
|
||||
Type: CredentialsTypePassword,
|
||||
Version: 0,
|
||||
Config: []byte(`{}`),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, UpgradeCredentials(i))
|
||||
wc := WithCredentialsAndAdminMetadataInJSON(*i)
|
||||
snapshotx.SnapshotT(t, &wc)
|
||||
assert.Equal(t, 1, i.Credentials[CredentialsTypePassword].Version)
|
||||
|
||||
// Verify only normalized identifier is present
|
||||
identifiers := i.Credentials[CredentialsTypePassword].Identifiers
|
||||
assert.Contains(t, identifiers, "+4917667111638", "Should contain E.164 normalized phone number")
|
||||
})
|
||||
|
||||
t.Run("from=v0 with email", func(t *testing.T) {
|
||||
i := &Identity{
|
||||
ID: uuid.FromStringOrNil("4d64fa08-20fc-450d-bebd-ebd7c7b6e249"),
|
||||
Credentials: map[CredentialsType]Credentials{
|
||||
CredentialsTypePassword: {
|
||||
Identifiers: []string{" Test@Example.ORG "},
|
||||
Type: CredentialsTypePassword,
|
||||
Version: 0,
|
||||
Config: []byte(`{}`),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, UpgradeCredentials(i))
|
||||
wc := WithCredentialsAndAdminMetadataInJSON(*i)
|
||||
snapshotx.SnapshotT(t, &wc)
|
||||
assert.Equal(t, 1, i.Credentials[CredentialsTypePassword].Version)
|
||||
|
||||
// Verify only normalized identifier is present
|
||||
identifiers := i.Credentials[CredentialsTypePassword].Identifiers
|
||||
assert.Contains(t, identifiers, "test@example.org", "Should contain normalized email")
|
||||
})
|
||||
|
||||
t.Run("from=v0 with already normalized phone", func(t *testing.T) {
|
||||
i := &Identity{
|
||||
ID: uuid.FromStringOrNil("4d64fa08-20fc-450d-bebd-ebd7c7b6e249"),
|
||||
Credentials: map[CredentialsType]Credentials{
|
||||
CredentialsTypePassword: {
|
||||
Identifiers: []string{"+4917667111638"},
|
||||
Type: CredentialsTypePassword,
|
||||
Version: 0,
|
||||
Config: []byte(`{}`),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, UpgradeCredentials(i))
|
||||
wc := WithCredentialsAndAdminMetadataInJSON(*i)
|
||||
snapshotx.SnapshotT(t, &wc)
|
||||
assert.Equal(t, 1, i.Credentials[CredentialsTypePassword].Version)
|
||||
|
||||
// Verify no duplicate is created when already normalized
|
||||
identifiers := i.Credentials[CredentialsTypePassword].Identifiers
|
||||
assert.Len(t, identifiers, 1, "Should not create duplicate when already normalized")
|
||||
assert.Contains(t, identifiers, "+4917667111638", "Should contain the normalized phone number")
|
||||
})
|
||||
|
||||
t.Run("from=v0 with mixed identifiers", func(t *testing.T) {
|
||||
i := &Identity{
|
||||
ID: uuid.FromStringOrNil("4d64fa08-20fc-450d-bebd-ebd7c7b6e249"),
|
||||
Credentials: map[CredentialsType]Credentials{
|
||||
CredentialsTypePassword: {
|
||||
Identifiers: []string{"+49 176 671 11 638", " Test@Example.ORG ", "username123"},
|
||||
Type: CredentialsTypePassword,
|
||||
Version: 0,
|
||||
Config: []byte(`{}`),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, UpgradeCredentials(i))
|
||||
wc := WithCredentialsAndAdminMetadataInJSON(*i)
|
||||
snapshotx.SnapshotT(t, &wc)
|
||||
assert.Equal(t, 1, i.Credentials[CredentialsTypePassword].Version)
|
||||
|
||||
// Verify only normalized identifiers are present
|
||||
identifiers := i.Credentials[CredentialsTypePassword].Identifiers
|
||||
assert.Contains(t, identifiers, "+4917667111638", "Should contain normalized phone")
|
||||
assert.Contains(t, identifiers, "test@example.org", "Should contain normalized email")
|
||||
assert.Contains(t, identifiers, "username123", "Should contain original username")
|
||||
})
|
||||
|
||||
t.Run("from=v1", func(t *testing.T) {
|
||||
run(t, []string{"+4917667111638"}, `{}`, 1, CredentialsTypePassword, 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user