Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 253 additions & 0 deletions internal/storetest/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
package storetest

import (
"context"
"testing"

"github.com/stretchr/testify/require"

"github.com/meigma/authkit"
)

// runContextCancellationSuite verifies that every store method honors
// `ctx.Err()` and returns `context.Canceled` (or a wrapping error) when called
// with an already-cancelled context. It deliberately spans every domain so a
// new method that forgets the cancellation check shows up here.
//
//nolint:funlen // Cross-domain sweep over every store method; adding new methods is expected to lengthen this list.
func runContextCancellationSuite(t *testing.T, newStore func(t *testing.T) Store) {
t.Helper()

t.Run("returns context error", func(t *testing.T) {
store := newStore(t)
principal := createPrincipal(t, store)
_, err := store.LinkIdentity(context.Background(), authkit.LinkIdentityRequest{
Provider: testProvider,
Subject: testSubject,
PrincipalID: principal.ID,
})
require.NoError(t, err)
token := tokenFixture(fixedStoreTime(), principal.ID)
require.NoError(t, store.CreateToken(context.Background(), token))
registration := passkeyRegistration(principal.ID, "credential-1")
_, err = store.CreateRegistration(context.Background(), registration)
require.NoError(t, err)

ctx, cancel := context.WithCancel(context.Background())
cancel()

tests := []struct {
name string
run func() error
}{
{
name: "create principal",
run: func() error {
_, runErr := store.CreatePrincipal(ctx, authkit.CreatePrincipalRequest{
Kind: authkit.PrincipalKindUser,
})

return runErr
},
},
{
name: "find principal",
run: func() error {
_, runErr := store.FindPrincipal(ctx, principal.ID)

return runErr
},
},
{
name: "list principals",
run: func() error {
_, runErr := store.ListPrincipals(ctx)

return runErr
},
},
{
name: "unassign principal role",
run: func() error {
return store.UnassignPrincipalRole(ctx, authkit.UnassignPrincipalRoleRequest{
PrincipalID: principal.ID,
RoleID: testRoleID,
})
},
},
{
name: "list principal role assignments",
run: func() error {
_, runErr := store.ListPrincipalRoleAssignments(ctx, principal.ID)

return runErr
},
},
{
name: "link identity",
run: func() error {
_, runErr := store.LinkIdentity(ctx, authkit.LinkIdentityRequest{
Provider: "api-token",
Subject: "token-123",
PrincipalID: principal.ID,
})

return runErr
},
},
{
name: "resolve identity",
run: func() error {
_, runErr := store.ResolveIdentity(ctx, authkit.Identity{
Provider: testProvider,
Subject: testSubject,
})

return runErr
},
},
{
name: "provision identity",
run: func() error {
_, runErr := store.ProvisionIdentity(ctx, provisionRequest())

return runErr
},
},
{
name: "create token",
run: func() error {
return store.CreateToken(ctx, tokenFixture(fixedStoreTime(), principal.ID))
},
},
{
name: "find token",
run: func() error {
_, runErr := store.FindToken(ctx, token.ID)

return runErr
},
},
{
name: "list principal token metadata",
run: func() error {
_, runErr := store.ListPrincipalTokenMetadata(ctx, principal.ID)

return runErr
},
},
{
name: "update token last used",
run: func() error {
return store.UpdateTokenLastUsed(ctx, token.ID, fixedStoreTime())
},
},
{
name: "revoke token",
run: func() error {
return store.RevokeToken(ctx, token.ID, fixedStoreTime())
},
},
{
name: "trust provider",
run: func() error {
_, runErr := store.TrustProvider(ctx, providerFixture())

return runErr
},
},
{
name: "create provisioning rule",
run: func() error {
_, runErr := store.CreateProvisioningRule(ctx, provisioningRuleRequest())

return runErr
},
},
{
name: "update provisioning rule",
run: func() error {
_, runErr := store.UpdateProvisioningRule(ctx, authkit.UpdateProvisioningRuleRequest{
ID: testProvisioningRuleID,
})

return runErr
},
},
{
name: "delete provisioning rule",
run: func() error {
return store.DeleteProvisioningRule(ctx, testProvisioningRuleID)
},
},
{
name: "find provisioning rule",
run: func() error {
_, runErr := store.FindProvisioningRule(ctx, testProvisioningRuleID)

return runErr
},
},
{
name: "list provisioning rules",
run: func() error {
_, runErr := store.ListProvisioningRules(ctx)

return runErr
},
},
{
name: "find provider",
run: func() error {
_, runErr := store.FindProvider(ctx, "https://issuer.example")

return runErr
},
},
{
name: "find passkey user by principal",
run: func() error {
_, runErr := store.FindUserByPrincipal(ctx, registration.User.RPID, principal.ID)

return runErr
},
},
{
name: "find passkey user by handle",
run: func() error {
_, runErr := store.FindUserByHandle(ctx, registration.User.RPID, registration.User.Handle)

return runErr
},
},
{
name: "list passkey credentials",
run: func() error {
_, runErr := store.ListCredentials(ctx, registration.User.RPID, registration.User.Handle)

return runErr
},
},
{
name: "create passkey registration",
run: func() error {
_, runErr := store.CreateRegistration(ctx, passkeyRegistration(principal.ID, "credential-2"))

return runErr
},
},
{
name: "update passkey credential after login",
run: func() error {
return store.UpdateCredentialAfterLogin(ctx, registration.Credential)
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require.ErrorIs(t, tt.run(), context.Canceled)
})
}
})
}
Loading