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:
51
selfservice/sessiontokenexchange/persistence.go
Normal file
51
selfservice/sessiontokenexchange/persistence.go
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package sessiontokenexchange
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
type Codes struct {
|
||||
InitCode string
|
||||
ReturnToCode string
|
||||
}
|
||||
|
||||
type Exchanger struct {
|
||||
ID uuid.UUID `db:"id"`
|
||||
NID uuid.UUID `db:"nid"`
|
||||
FlowID uuid.UUID `db:"flow_id"`
|
||||
SessionID uuid.NullUUID `db:"session_id"`
|
||||
|
||||
InitCode string `db:"init_code"`
|
||||
ReturnToCode string `db:"return_to_code"`
|
||||
|
||||
// CreatedAt is a helper struct field for gobuffalo.pop.
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
|
||||
// UpdatedAt is a helper struct field for gobuffalo.pop.
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
func (Exchanger) TableName() string { return "session_token_exchanges" }
|
||||
|
||||
type (
|
||||
Persister interface {
|
||||
CreateSessionTokenExchanger(ctx context.Context, flowID uuid.UUID) (e *Exchanger, err error)
|
||||
GetExchangerFromCode(ctx context.Context, initCode string, returnToCode string) (*Exchanger, error)
|
||||
GetExchangerFromCodeAllowPending(ctx context.Context, initCode string, returnToCode string) (*Exchanger, error)
|
||||
UpdateSessionOnExchanger(ctx context.Context, flowID uuid.UUID, sessionID uuid.UUID) error
|
||||
CodeForFlow(ctx context.Context, flowID uuid.UUID) (codes *Codes, found bool, err error)
|
||||
MoveToNewFlow(ctx context.Context, oldFlow, newFlow uuid.UUID) error
|
||||
|
||||
DeleteExpiredExchangers(context.Context, time.Time, int) error
|
||||
}
|
||||
|
||||
PersistenceProvider interface {
|
||||
SessionTokenExchangePersister() Persister
|
||||
}
|
||||
)
|
||||
207
selfservice/sessiontokenexchange/test/persistence.go
Normal file
207
selfservice/sessiontokenexchange/test/persistence.go
Normal file
@@ -0,0 +1,207 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ory/kratos/persistence"
|
||||
"github.com/ory/kratos/pkg/testhelpers"
|
||||
"github.com/ory/kratos/selfservice/sessiontokenexchange"
|
||||
"github.com/ory/x/randx"
|
||||
)
|
||||
|
||||
type testParams struct {
|
||||
flowID, sessionID uuid.UUID
|
||||
initCode, returnToCode string
|
||||
}
|
||||
|
||||
func newParams() testParams {
|
||||
return testParams{
|
||||
flowID: uuid.Must(uuid.NewV4()),
|
||||
sessionID: uuid.Must(uuid.NewV4()),
|
||||
initCode: randx.MustString(64, randx.AlphaNum),
|
||||
returnToCode: randx.MustString(64, randx.AlphaNum),
|
||||
}
|
||||
}
|
||||
func (t *testParams) setCodes(e *sessiontokenexchange.Exchanger) {
|
||||
t.initCode = e.InitCode
|
||||
t.returnToCode = e.ReturnToCode
|
||||
}
|
||||
|
||||
func TestPersister(ctx context.Context, p interface {
|
||||
persistence.Persister
|
||||
}) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
nid, p := testhelpers.NewNetworkUnlessExisting(t, ctx, p)
|
||||
|
||||
t.Run("suite=create-update-get", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
params := newParams()
|
||||
|
||||
t.Run("step=create", func(t *testing.T) {
|
||||
e, err := p.CreateSessionTokenExchanger(ctx, params.flowID)
|
||||
require.NoError(t, err)
|
||||
params.setCodes(e)
|
||||
codes, ok, err := p.CodeForFlow(ctx, params.flowID)
|
||||
assert.True(t, ok)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, params.initCode, codes.InitCode)
|
||||
assert.Equal(t, params.returnToCode, codes.ReturnToCode)
|
||||
})
|
||||
t.Run("step=update", func(t *testing.T) {
|
||||
require.NoError(t, p.UpdateSessionOnExchanger(ctx, params.flowID, params.sessionID))
|
||||
})
|
||||
t.Run("step=get", func(t *testing.T) {
|
||||
e, err := p.GetExchangerFromCode(ctx, params.initCode, params.returnToCode)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, params.sessionID, e.SessionID.UUID)
|
||||
assert.Equal(t, nid, e.NID)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("suite=CodeForFlow", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("case=returns false for non-existing flow", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, ok, err := p.CodeForFlow(ctx, uuid.Must(uuid.NewV4()))
|
||||
assert.False(t, ok)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("suite=MoveToNewFlow", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("case=move to new flow", func(t *testing.T) {
|
||||
params := newParams()
|
||||
other := newParams()
|
||||
|
||||
e, err := p.CreateSessionTokenExchanger(ctx, params.flowID)
|
||||
require.NoError(t, err)
|
||||
params.setCodes(e)
|
||||
require.NoError(t, p.MoveToNewFlow(ctx, params.flowID, other.flowID))
|
||||
require.NoError(t, p.UpdateSessionOnExchanger(ctx, other.flowID, params.sessionID))
|
||||
|
||||
e, err = p.GetExchangerFromCode(ctx, params.initCode, params.returnToCode)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, params.sessionID, e.SessionID.UUID)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("suite=GetExchangerFromCodeAllowPending", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("case=returns exchanger without session", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
params := newParams()
|
||||
|
||||
e, err := p.CreateSessionTokenExchanger(ctx, params.flowID)
|
||||
require.NoError(t, err)
|
||||
params.setCodes(e)
|
||||
|
||||
e, err = p.GetExchangerFromCodeAllowPending(ctx, params.initCode, params.returnToCode)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, params.flowID, e.FlowID)
|
||||
assert.False(t, e.SessionID.Valid)
|
||||
})
|
||||
|
||||
t.Run("case=returns exchanger with session", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
params := newParams()
|
||||
|
||||
e, err := p.CreateSessionTokenExchanger(ctx, params.flowID)
|
||||
require.NoError(t, err)
|
||||
params.setCodes(e)
|
||||
require.NoError(t, p.UpdateSessionOnExchanger(ctx, params.flowID, params.sessionID))
|
||||
|
||||
e, err = p.GetExchangerFromCodeAllowPending(ctx, params.initCode, params.returnToCode)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, params.flowID, e.FlowID)
|
||||
assert.Equal(t, params.sessionID, e.SessionID.UUID)
|
||||
})
|
||||
|
||||
t.Run("case=errors if code is invalid", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
other := newParams()
|
||||
|
||||
e, err := p.GetExchangerFromCodeAllowPending(ctx, other.initCode, other.returnToCode)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, e)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("suite=GetExchangerFromCode", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("case=errors if session not found", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
params := newParams()
|
||||
|
||||
e, err := p.CreateSessionTokenExchanger(ctx, params.flowID)
|
||||
require.NoError(t, err)
|
||||
params.setCodes(e)
|
||||
|
||||
e, err = p.GetExchangerFromCode(ctx, params.initCode, params.returnToCode)
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, e)
|
||||
})
|
||||
|
||||
t.Run("case=errors if code is invalid", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
params := newParams()
|
||||
other := newParams()
|
||||
|
||||
e, err := p.CreateSessionTokenExchanger(ctx, params.flowID)
|
||||
require.NoError(t, err)
|
||||
params.setCodes(e)
|
||||
|
||||
require.NoError(t, p.UpdateSessionOnExchanger(ctx, params.flowID, params.sessionID))
|
||||
e, err = p.GetExchangerFromCode(ctx, other.initCode, other.returnToCode)
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, e)
|
||||
})
|
||||
|
||||
t.Run("case=errors if code is empty", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
params := newParams()
|
||||
|
||||
e, err := p.CreateSessionTokenExchanger(ctx, params.flowID)
|
||||
require.NoError(t, err)
|
||||
params.setCodes(e)
|
||||
|
||||
require.NoError(t, p.UpdateSessionOnExchanger(ctx, params.flowID, params.sessionID))
|
||||
e, err = p.GetExchangerFromCode(ctx, "", "")
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, e)
|
||||
})
|
||||
|
||||
t.Run("case=errors if other network ID", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
params := newParams()
|
||||
otherNID := uuid.Must(uuid.NewV4())
|
||||
|
||||
e, err := p.CreateSessionTokenExchanger(ctx, params.flowID)
|
||||
require.NoError(t, err)
|
||||
params.setCodes(e)
|
||||
|
||||
require.NoError(t, p.UpdateSessionOnExchanger(ctx, params.flowID, params.sessionID))
|
||||
e, err = p.WithNetworkID(otherNID).GetExchangerFromCode(ctx, params.initCode, params.returnToCode)
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, e)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user