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

This commit is contained in:
upstream-mirror
2026-09-15 21:19:12 +05:00
commit c60cc7ca75
8092 changed files with 394160 additions and 0 deletions

View File

@@ -0,0 +1,237 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0
package sql
import (
"context"
"embed"
"io/fs"
"slices"
"time"
"github.com/gofrs/uuid"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/ory/kratos/driver/config"
"github.com/ory/kratos/identity"
"github.com/ory/kratos/persistence"
"github.com/ory/kratos/persistence/sql/devices"
idpersistence "github.com/ory/kratos/persistence/sql/identity"
gomigrations "github.com/ory/kratos/persistence/sql/migrations/go"
"github.com/ory/kratos/schema"
"github.com/ory/kratos/session"
"github.com/ory/pop/v6"
"github.com/ory/x/clock"
"github.com/ory/x/contextx"
"github.com/ory/x/fsx"
"github.com/ory/x/logrusx"
"github.com/ory/x/networkx"
"github.com/ory/x/otelx"
"github.com/ory/x/popx"
)
var _ persistence.Persister = new(Persister)
//go:embed migrations/sql/*.sql
var Migrations embed.FS
type (
persisterDependencies interface {
logrusx.Provider
config.Provider
clock.Provider
contextx.Provider
otelx.Provider
schema.IdentitySchemaProvider
identity.ValidationProvider
}
Persister struct {
nid uuid.UUID
c *pop.Connection
mb *popx.MigrationBox
mbs popx.MigrationStatuses
r persisterDependencies
identity.PrivilegedPool
session.DevicePersister
}
)
type options struct {
extraMigrations []fs.FS
extraGoMigrations popx.Migrations
disableLogging bool
}
type Option = func(o *options)
func WithExtraMigrations(fss ...fs.FS) Option {
return func(o *options) {
o.extraMigrations = fss
}
}
func WithExtraGoMigrations(ms ...popx.Migration) Option {
return func(o *options) {
o.extraGoMigrations = ms
}
}
func WithDisabledLogging(v bool) Option {
return func(o *options) {
o.disableLogging = v
}
}
func NewPersister(r persisterDependencies, c *pop.Connection, opts ...Option) (*Persister, error) {
o := &options{}
for _, f := range opts {
f(o)
}
logger := r.Logger()
if o.disableLogging {
logger.Logrus().SetLevel(logrus.WarnLevel)
}
m, err := popx.NewMigrationBox(
fsx.Merge(append([]fs.FS{Migrations, networkx.Migrations}, o.extraMigrations...)...),
c, logger,
popx.WithGoMigrations(slices.Concat(gomigrations.All, o.extraGoMigrations)),
)
if err != nil {
return nil, err
}
return &Persister{
c: c,
mb: m,
r: r,
PrivilegedPool: idpersistence.NewPersister(r, c),
DevicePersister: devices.NewPersister(r, c),
}, nil
}
func (p *Persister) NetworkID(ctx context.Context) uuid.UUID {
return p.r.Contextualizer().Network(ctx, p.nid)
}
func (p Persister) WithNetworkID(nid uuid.UUID) persistence.Persister {
p.nid = nid
if pp, ok := p.PrivilegedPool.(interface {
WithNetworkID(uuid.UUID) identity.PrivilegedPool
}); ok {
p.PrivilegedPool = pp.WithNetworkID(nid)
}
if dp, ok := p.DevicePersister.(interface {
WithNetworkID(uuid.UUID) session.DevicePersister
}); ok {
p.DevicePersister = dp.WithNetworkID(nid)
}
return &p
}
func (p *Persister) DetermineNetwork(ctx context.Context) (*networkx.Network, error) {
return networkx.Determine(p.Connection(ctx))
}
func (p *Persister) Connection(ctx context.Context) *pop.Connection {
return p.c.WithContext(ctx)
}
func (p *Persister) MigrationStatus(ctx context.Context) (_ popx.MigrationStatuses, err error) {
ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.MigrationStatus")
defer otelx.End(span, &err)
if p.mbs != nil {
return p.mbs, nil
}
status, err := p.mb.Status(ctx)
if err != nil {
return nil, errors.WithStack(err)
}
if !status.HasPending() {
p.mbs = status
}
return status, nil
}
func (p *Persister) MigrateDown(ctx context.Context, steps int) error {
return p.mb.Down(ctx, steps)
}
func (p *Persister) MigrateUp(ctx context.Context) error {
return p.mb.Up(ctx)
}
func (p *Persister) MigrationBox() *popx.MigrationBox {
return p.mb
}
func (p *Persister) Close(ctx context.Context) error {
return errors.WithStack(p.GetConnection(ctx).Close())
}
func (p *Persister) Ping(ctx context.Context) error {
return errors.WithStack(p.c.Store.SQLDB().PingContext(ctx))
}
func (p *Persister) CleanupDatabase(ctx context.Context, wait time.Duration, older time.Duration, batchSize int) error {
currentTime := time.Now().Add(-older)
p.r.Logger().Printf("Cleaning up records older than %s\n", currentTime)
p.r.Logger().Println("Cleaning up expired sessions")
if err := p.DeleteExpiredSessions(ctx, currentTime, batchSize); err != nil {
return err
}
time.Sleep(wait)
p.r.Logger().Println("Cleaning up expired continuity containers")
if err := p.DeleteExpiredContinuitySessions(ctx, currentTime, batchSize); err != nil {
return err
}
time.Sleep(wait)
p.r.Logger().Println("Cleaning up expired login flows")
if err := p.DeleteExpiredLoginFlows(ctx, currentTime, batchSize); err != nil {
return err
}
time.Sleep(wait)
p.r.Logger().Println("Cleaning up expired recovery flows")
if err := p.DeleteExpiredRecoveryFlows(ctx, currentTime, batchSize); err != nil {
return err
}
time.Sleep(wait)
p.r.Logger().Println("Cleaning up expired registration flows")
if err := p.DeleteExpiredRegistrationFlows(ctx, currentTime, batchSize); err != nil {
return err
}
time.Sleep(wait)
p.r.Logger().Println("Cleaning up expired settings flows")
if err := p.DeleteExpiredSettingsFlows(ctx, currentTime, batchSize); err != nil {
return err
}
time.Sleep(wait)
p.r.Logger().Println("Cleaning up expired verification flows")
if err := p.DeleteExpiredVerificationFlows(ctx, currentTime, batchSize); err != nil {
return err
}
time.Sleep(wait)
p.r.Logger().Println("Cleaning up expired session token exchangers")
if err := p.DeleteExpiredExchangers(ctx, currentTime, batchSize); err != nil {
return err
}
time.Sleep(wait)
p.r.Logger().Println("Successfully cleaned up the latest batch of the SQL database! " +
"This should be re-run periodically, to be sure that all expired data is purged.")
return nil
}