From 802ae872e2531ef9c30152337fb3a4e5632c5b68 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Thu, 9 Feb 2023 18:19:13 +0100 Subject: [PATCH 01/24] chore: factor out identity persister --- driver/registry_default.go | 4 +- identity/pool.go | 3 + internal/driver.go | 3 + .../sql/{ => identity}/persister_identity.go | 206 +++++++++++++++--- persistence/sql/persister.go | 26 +-- persistence/sql/persister_hmac_test.go | 13 +- persistence/sql/persister_session.go | 6 +- persistence/sql/persister_settings.go | 2 +- 8 files changed, 197 insertions(+), 66 deletions(-) rename persistence/sql/{ => identity}/persister_identity.go (71%) diff --git a/driver/registry_default.go b/driver/registry_default.go index d199a4f901a1..d8d3ad11b86b 100644 --- a/driver/registry_default.go +++ b/driver/registry_default.go @@ -72,6 +72,7 @@ import ( "github.com/ory/kratos/driver/config" "github.com/ory/kratos/identity" + idpersistence "github.com/ory/kratos/persistence/sql/identity" "github.com/ory/kratos/selfservice/errorx" password2 "github.com/ory/kratos/selfservice/strategy/password" "github.com/ory/kratos/session" @@ -612,7 +613,7 @@ func (m *RegistryDefault) Init(ctx context.Context, ctxer contextx.Contextualize m.Logger().WithError(err).Warnf("Unable to open database, retrying.") return errors.WithStack(err) } - p, err := sql.NewPersister(ctx, m, c) + p, err := sql.NewPersister(ctx, m, idpersistence.NewPersister(m, c), c) if err != nil { m.Logger().WithError(err).Warnf("Unable to initialize persister, retrying.") return err @@ -643,6 +644,7 @@ func (m *RegistryDefault) Init(ctx context.Context, ctxer contextx.Contextualize return err } + p.PrivilegedPool.(*idpersistence.IdentityPersister).SetNetworkID(net.ID) m.persister = p.WithNetworkID(net.ID) return nil }, bc) diff --git a/identity/pool.go b/identity/pool.go index 2109890fc481..296c93d064bc 100644 --- a/identity/pool.go +++ b/identity/pool.go @@ -77,5 +77,8 @@ type ( // HydrateIdentityAssociations hydrates the associations of an identity. HydrateIdentityAssociations(ctx context.Context, i *Identity, expandables Expandables) error + + // TODO: description + InjectTraitsSchemaURL(ctx context.Context, i *Identity) error } ) diff --git a/internal/driver.go b/internal/driver.go index 101fe85cbba8..2aa405bb87f9 100644 --- a/internal/driver.go +++ b/internal/driver.go @@ -23,6 +23,8 @@ import ( "github.com/ory/kratos/driver" "github.com/ory/kratos/driver/config" + "github.com/ory/kratos/persistence/sql" + idpersistence "github.com/ory/kratos/persistence/sql/identity" "github.com/ory/kratos/selfservice/hook" "github.com/ory/kratos/x" ) @@ -87,6 +89,7 @@ func NewRegistryDefaultWithDSN(t *testing.T, dsn string) (*config.Config, *drive actual, err := reg.Persister().DetermineNetwork(context.Background()) require.NoError(t, err) reg.SetPersister(reg.Persister().WithNetworkID(actual.ID)) + reg.Persister().(*sql.Persister).PrivilegedPool.(*idpersistence.IdentityPersister).SetNetworkID(actual.ID) require.EqualValues(t, reg.Persister().NetworkID(context.Background()), actual.ID) require.NotEqual(t, uuid.Nil, reg.Persister().NetworkID(context.Background())) diff --git a/persistence/sql/persister_identity.go b/persistence/sql/identity/persister_identity.go similarity index 71% rename from persistence/sql/persister_identity.go rename to persistence/sql/identity/persister_identity.go index 6d46986961ea..87929b158846 100644 --- a/persistence/sql/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -1,7 +1,7 @@ // Copyright © 2023 Ory Corp // SPDX-License-Identifier: Apache-2.0 -package sql +package identity import ( "context" @@ -10,7 +10,9 @@ import ( "strings" "time" + "github.com/ory/x/contextx" "github.com/ory/x/pointerx" + "github.com/ory/x/popx" "golang.org/x/sync/errgroup" @@ -21,24 +23,69 @@ import ( "github.com/ory/jsonschema/v3" "github.com/ory/x/sqlxx" + "github.com/ory/kratos/driver/config" + "github.com/ory/kratos/identity" "github.com/ory/kratos/otp" + "github.com/ory/kratos/schema" "github.com/ory/kratos/x" "github.com/gobuffalo/pop/v6" + "github.com/gobuffalo/pop/v6/columns" "github.com/gofrs/uuid" "github.com/pkg/errors" "github.com/ory/herodot" "github.com/ory/x/errorsx" "github.com/ory/x/sqlcon" - - "github.com/ory/kratos/identity" ) -var _ identity.Pool = new(Persister) -var _ identity.PrivilegedPool = new(Persister) +var _ identity.Pool = new(IdentityPersister) +var _ identity.PrivilegedPool = new(IdentityPersister) + +type dependencies interface { + schema.IdentityTraitsProvider + identity.ValidationProvider + x.LoggingProvider + config.Provider + contextx.Provider + x.TracingProvider +} -func (p *Persister) ListVerifiableAddresses(ctx context.Context, page, itemsPerPage int) (a []identity.VerifiableAddress, err error) { +type IdentityPersister struct { + r dependencies + c *pop.Connection + nid uuid.UUID +} + +func NewPersister(r dependencies, c *pop.Connection) *IdentityPersister { + return &IdentityPersister{ + c: c, + r: r, + } +} + +func (p *IdentityPersister) NetworkID(ctx context.Context) uuid.UUID { + return p.r.Contextualizer().Network(ctx, p.nid) +} + +func (p *IdentityPersister) SetNetworkID(sid uuid.UUID) *IdentityPersister { + p.nid = sid + return p +} + +func WithTransaction(ctx context.Context, tx *pop.Connection) context.Context { + return popx.WithTransaction(ctx, tx) +} + +func (p *IdentityPersister) Transaction(ctx context.Context, callback func(ctx context.Context, connection *pop.Connection) error) error { + return popx.Transaction(ctx, p.c.WithContext(ctx), callback) +} + +func (p *IdentityPersister) GetConnection(ctx context.Context) *pop.Connection { + return popx.GetConnection(ctx, p.c.WithContext(ctx)) +} + +func (p *IdentityPersister) ListVerifiableAddresses(ctx context.Context, page, itemsPerPage int) (a []identity.VerifiableAddress, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.ListVerifiableAddresses") defer span.End() @@ -49,7 +96,7 @@ func (p *Persister) ListVerifiableAddresses(ctx context.Context, page, itemsPerP return a, err } -func (p *Persister) ListRecoveryAddresses(ctx context.Context, page, itemsPerPage int) (a []identity.RecoveryAddress, err error) { +func (p *IdentityPersister) ListRecoveryAddresses(ctx context.Context, page, itemsPerPage int) (a []identity.RecoveryAddress, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.ListRecoveryAddresses") defer span.End() @@ -64,7 +111,7 @@ func stringToLowerTrim(match string) string { return strings.ToLower(strings.TrimSpace(match)) } -func (p *Persister) normalizeIdentifier(ct identity.CredentialsType, match string) string { +func (p *IdentityPersister) normalizeIdentifier(ct identity.CredentialsType, match string) string { switch ct { case identity.CredentialsTypeLookup: // lookup credentials are case-sensitive @@ -83,7 +130,7 @@ func (p *Persister) normalizeIdentifier(ct identity.CredentialsType, match strin return match } -func (p *Persister) FindByCredentialsIdentifier(ctx context.Context, ct identity.CredentialsType, match string) (*identity.Identity, *identity.Credentials, error) { +func (p *IdentityPersister) FindByCredentialsIdentifier(ctx context.Context, ct identity.CredentialsType, match string) (*identity.Identity, *identity.Credentials, error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.FindByCredentialsIdentifier") defer span.End() @@ -135,7 +182,7 @@ WHERE ici.identifier = ? return i.CopyWithoutCredentials(), creds, nil } -func (p *Persister) findIdentityCredentialsType(ctx context.Context, ct identity.CredentialsType) (*identity.CredentialsTypeTable, error) { +func (p *IdentityPersister) findIdentityCredentialsType(ctx context.Context, ct identity.CredentialsType) (*identity.CredentialsTypeTable, error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.findIdentityCredentialsType") defer span.End() @@ -146,7 +193,7 @@ func (p *Persister) findIdentityCredentialsType(ctx context.Context, ct identity return &m, nil } -func (p *Persister) createIdentityCredentials(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) createIdentityCredentials(ctx context.Context, i *identity.Identity) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.createIdentityCredentials") defer span.End() @@ -196,7 +243,7 @@ func (p *Persister) createIdentityCredentials(ctx context.Context, i *identity.I return nil } -func (p *Persister) createVerifiableAddresses(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) createVerifiableAddresses(ctx context.Context, i *identity.Identity) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.createVerifiableAddresses") defer span.End() @@ -210,7 +257,7 @@ func (p *Persister) createVerifiableAddresses(ctx context.Context, i *identity.I func updateAssociation[T interface { Hash() string -}](ctx context.Context, p *Persister, i *identity.Identity, inID []T) error { +}](ctx context.Context, p *IdentityPersister, i *identity.Identity, inID []T) error { var inDB []T if err := p.GetConnection(ctx). Where("identity_id = ? AND nid = ?", i.ID, p.NetworkID(ctx)). @@ -252,12 +299,12 @@ func updateAssociation[T interface { return nil } -func (p *Persister) normalizeAllAddressess(ctx context.Context, id *identity.Identity) { +func (p *IdentityPersister) normalizeAllAddressess(ctx context.Context, id *identity.Identity) { p.normalizeRecoveryAddresses(ctx, id) p.normalizeVerifiableAddresses(ctx, id) } -func (p *Persister) normalizeVerifiableAddresses(ctx context.Context, id *identity.Identity) { +func (p *IdentityPersister) normalizeVerifiableAddresses(ctx context.Context, id *identity.Identity) { for k := range id.VerifiableAddresses { v := id.VerifiableAddresses[k] @@ -282,7 +329,7 @@ func (p *Persister) normalizeVerifiableAddresses(ctx context.Context, id *identi } } -func (p *Persister) normalizeRecoveryAddresses(ctx context.Context, id *identity.Identity) { +func (p *IdentityPersister) normalizeRecoveryAddresses(ctx context.Context, id *identity.Identity) { for k := range id.RecoveryAddresses { id.RecoveryAddresses[k].IdentityID = id.ID id.RecoveryAddresses[k].NID = p.NetworkID(ctx) @@ -291,7 +338,7 @@ func (p *Persister) normalizeRecoveryAddresses(ctx context.Context, id *identity } } -func (p *Persister) createRecoveryAddresses(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) createRecoveryAddresses(ctx context.Context, i *identity.Identity) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.createRecoveryAddresses") defer span.End() @@ -303,7 +350,7 @@ func (p *Persister) createRecoveryAddresses(ctx context.Context, i *identity.Ide return nil } -func (p *Persister) CountIdentities(ctx context.Context) (int64, error) { +func (p *IdentityPersister) CountIdentities(ctx context.Context) (int64, error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.CountIdentities") defer span.End() @@ -314,7 +361,7 @@ func (p *Persister) CountIdentities(ctx context.Context) (int64, error) { return int64(count), nil } -func (p *Persister) CreateIdentity(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) CreateIdentity(ctx context.Context, i *identity.Identity) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.CreateIdentity") defer span.End() @@ -334,7 +381,7 @@ func (p *Persister) CreateIdentity(ctx context.Context, i *identity.Identity) er i.Traits = identity.Traits("{}") } - if err := p.injectTraitsSchemaURL(ctx, i); err != nil { + if err := p.InjectTraitsSchemaURL(ctx, i); err != nil { return err } @@ -361,7 +408,7 @@ func (p *Persister) CreateIdentity(ctx context.Context, i *identity.Identity) er }) } -func (p *Persister) HydrateIdentityAssociations(ctx context.Context, i *identity.Identity, expand identity.Expandables) (err error) { +func (p *IdentityPersister) HydrateIdentityAssociations(ctx context.Context, i *identity.Identity, expand identity.Expandables) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.HydrateIdentityAssociations") defer otelx.End(span, &err) @@ -374,10 +421,10 @@ func (p *Persister) HydrateIdentityAssociations(ctx context.Context, i *identity return err } - return p.injectTraitsSchemaURL(ctx, i) + return p.InjectTraitsSchemaURL(ctx, i) } -func (p *Persister) ListIdentities(ctx context.Context, params identity.ListIdentityParameters) (res []identity.Identity, err error) { +func (p *IdentityPersister) ListIdentities(ctx context.Context, params identity.ListIdentityParameters) (res []identity.Identity, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.ListIdentities") defer otelx.End(span, &err) span.SetAttributes( @@ -425,7 +472,7 @@ func (p *Persister) ListIdentities(ctx context.Context, params identity.ListIden if u, ok := schemaCache[i.SchemaID]; ok { i.SchemaURL = u } else { - if err := p.injectTraitsSchemaURL(ctx, i); err != nil { + if err := p.InjectTraitsSchemaURL(ctx, i); err != nil { return nil, err } schemaCache[i.SchemaID] = i.SchemaURL @@ -437,7 +484,7 @@ func (p *Persister) ListIdentities(ctx context.Context, params identity.ListIden return is, nil } -func (p *Persister) UpdateIdentity(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) UpdateIdentity(ctx context.Context, i *identity.Identity) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.UpdateIdentity") defer span.End() @@ -479,14 +526,14 @@ func (p *Persister) UpdateIdentity(ctx context.Context, i *identity.Identity) er })) } -func (p *Persister) DeleteIdentity(ctx context.Context, id uuid.UUID) error { +func (p *IdentityPersister) DeleteIdentity(ctx context.Context, id uuid.UUID) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteIdentity") defer span.End() return p.delete(ctx, new(identity.Identity), id) } -func (p *Persister) GetIdentity(ctx context.Context, id uuid.UUID, expand identity.Expandables) (res *identity.Identity, err error) { +func (p *IdentityPersister) GetIdentity(ctx context.Context, id uuid.UUID, expand identity.Expandables) (res *identity.Identity, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.GetIdentity") defer otelx.End(span, &err) @@ -571,21 +618,21 @@ func (p *Persister) GetIdentity(ctx context.Context, id uuid.UUID, expand identi return nil, err } - if err := p.injectTraitsSchemaURL(ctx, &i); err != nil { + if err := p.InjectTraitsSchemaURL(ctx, &i); err != nil { return nil, err } return &i, nil } -func (p *Persister) GetIdentityConfidential(ctx context.Context, id uuid.UUID) (res *identity.Identity, err error) { +func (p *IdentityPersister) GetIdentityConfidential(ctx context.Context, id uuid.UUID) (res *identity.Identity, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.GetIdentityConfidential") defer otelx.End(span, &err) return p.GetIdentity(ctx, id, identity.ExpandEverything) } -func (p *Persister) FindVerifiableAddressByValue(ctx context.Context, via identity.VerifiableAddressType, value string) (*identity.VerifiableAddress, error) { +func (p *IdentityPersister) FindVerifiableAddressByValue(ctx context.Context, via identity.VerifiableAddressType, value string) (*identity.VerifiableAddress, error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.FindVerifiableAddressByValue") defer span.End() @@ -597,7 +644,7 @@ func (p *Persister) FindVerifiableAddressByValue(ctx context.Context, via identi return &address, nil } -func (p *Persister) FindRecoveryAddressByValue(ctx context.Context, via identity.RecoveryAddressType, value string) (*identity.RecoveryAddress, error) { +func (p *IdentityPersister) FindRecoveryAddressByValue(ctx context.Context, via identity.RecoveryAddressType, value string) (*identity.RecoveryAddress, error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.FindRecoveryAddressByValue") defer span.End() @@ -609,7 +656,7 @@ func (p *Persister) FindRecoveryAddressByValue(ctx context.Context, via identity return &address, nil } -func (p *Persister) VerifyAddress(ctx context.Context, code string) error { +func (p *IdentityPersister) VerifyAddress(ctx context.Context, code string) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.VerifyAddress") defer span.End() newCode, err := otp.New() @@ -641,7 +688,7 @@ func (p *Persister) VerifyAddress(ctx context.Context, code string) error { return nil } -func (p *Persister) UpdateVerifiableAddress(ctx context.Context, address *identity.VerifiableAddress) error { +func (p *IdentityPersister) UpdateVerifiableAddress(ctx context.Context, address *identity.VerifiableAddress) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.UpdateVerifiableAddress") defer span.End() @@ -650,7 +697,7 @@ func (p *Persister) UpdateVerifiableAddress(ctx context.Context, address *identi return p.update(ctx, address) } -func (p *Persister) validateIdentity(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) validateIdentity(ctx context.Context, i *identity.Identity) error { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.validateIdentity") defer span.End() @@ -664,8 +711,8 @@ func (p *Persister) validateIdentity(ctx context.Context, i *identity.Identity) return nil } -func (p *Persister) injectTraitsSchemaURL(ctx context.Context, i *identity.Identity) error { - ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.injectTraitsSchemaURL") +func (p *IdentityPersister) InjectTraitsSchemaURL(ctx context.Context, i *identity.Identity) error { + ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.InjectTraitsSchemaURL") defer span.End() ss, err := p.r.IdentityTraitsSchemas(ctx) @@ -680,3 +727,90 @@ func (p *Persister) injectTraitsSchemaURL(ctx context.Context, i *identity.Ident i.SchemaURL = s.SchemaURL(p.r.Config().SelfPublicURL(ctx)).String() return nil } + +type quotable interface { + Quote(key string) string +} + +type node interface { + GetID() uuid.UUID + GetNID() uuid.UUID +} + +func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...string) error { + ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.update") + defer span.End() + + c := p.GetConnection(ctx) + quoter, ok := c.Dialect.(quotable) + if !ok { + return errors.Errorf("store is not a quoter: %T", p.c.Store) + } + + model := pop.NewModel(v, ctx) + tn := model.TableName() + + cols := columns.Columns{} + if len(columnNames) > 0 && tn == model.TableName() { + cols = columns.NewColumnsWithAlias(tn, model.As, model.IDField()) + cols.Add(columnNames...) + } else { + cols = columns.ForStructWithAlias(v, tn, model.As, model.IDField()) + } + + // #nosec + stmt := fmt.Sprintf("SELECT COUNT(id) FROM %s AS %s WHERE %s.id = ? AND %s.nid = ?", + quoter.Quote(model.TableName()), + model.Alias(), + model.Alias(), + model.Alias(), + ) + + var count int + if err := c.Store.GetContext(ctx, &count, c.Dialect.TranslateSQL(stmt), v.GetID(), v.GetNID()); err != nil { + return sqlcon.HandleError(err) + } else if count == 0 { + return errors.WithStack(sqlcon.ErrNoRows) + } + + // #nosec + stmt = fmt.Sprintf("UPDATE %s AS %s SET %s WHERE %s AND %s.nid = :nid", + quoter.Quote(model.TableName()), + model.Alias(), + cols.Writeable().QuotedUpdateString(quoter), + model.WhereNamedID(), + model.Alias(), + ) + + if _, err := c.Store.NamedExecContext(ctx, stmt, v); err != nil { + return sqlcon.HandleError(err) + } + return nil +} + +func (p *IdentityPersister) delete(ctx context.Context, v interface{}, id uuid.UUID) error { + ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.delete") + defer span.End() + + nid := p.NetworkID(ctx) + + tabler, ok := v.(interface { + TableName(ctx context.Context) string + }) + if !ok { + return errors.Errorf("expected model to have TableName signature but got: %T", v) + } + + /* #nosec G201 TableName is static */ + count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf("DELETE FROM %s WHERE id = ? AND nid = ?", tabler.TableName(ctx)), + id, + nid, + ).ExecWithCount() + if err != nil { + return sqlcon.HandleError(err) + } + if count == 0 { + return errors.WithStack(sqlcon.ErrNoRows) + } + return nil +} diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index d9fccea5be6f..dcca5fb3ce1f 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -26,7 +26,6 @@ import ( "github.com/ory/kratos/driver/config" "github.com/ory/kratos/identity" "github.com/ory/kratos/persistence" - "github.com/ory/kratos/schema" "github.com/ory/kratos/x" ) @@ -37,25 +36,23 @@ var migrations embed.FS type ( persisterDependencies interface { - schema.IdentityTraitsProvider - identity.ValidationProvider x.LoggingProvider config.Provider contextx.Provider x.TracingProvider } Persister struct { - nid uuid.UUID - c *pop.Connection - mb *popx.MigrationBox - mbs popx.MigrationStatuses - r persisterDependencies - p *networkx.Manager - isSQLite bool + nid uuid.UUID + c *pop.Connection + mb *popx.MigrationBox + mbs popx.MigrationStatuses + r persisterDependencies + p *networkx.Manager + identity.PrivilegedPool } ) -func NewPersister(ctx context.Context, r persisterDependencies, c *pop.Connection) (*Persister, error) { +func NewPersister(ctx context.Context, r persisterDependencies, pool identity.PrivilegedPool, c *pop.Connection) (*Persister, error) { m, err := popx.NewMigrationBox(fsx.Merge(migrations, networkx.Migrations), popx.NewMigrator(c, r.Logger(), r.Tracer(ctx), 0)) if err != nil { return nil, err @@ -63,8 +60,11 @@ func NewPersister(ctx context.Context, r persisterDependencies, c *pop.Connectio m.DumpMigrations = false return &Persister{ - c: c, mb: m, r: r, isSQLite: c.Dialect.Name() == "sqlite3", - p: networkx.NewManager(c, r.Logger(), r.Tracer(ctx)), + c: c, + mb: m, + r: r, + PrivilegedPool: pool, + p: networkx.NewManager(c, r.Logger(), r.Tracer(ctx)), }, nil } diff --git a/persistence/sql/persister_hmac_test.go b/persistence/sql/persister_hmac_test.go index f87f1e7269c5..e281d6fa262c 100644 --- a/persistence/sql/persister_hmac_test.go +++ b/persistence/sql/persister_hmac_test.go @@ -13,9 +13,6 @@ import ( "github.com/ory/x/configx" "github.com/ory/x/otelx" - "github.com/ory/kratos/identity" - "github.com/ory/kratos/schema" - "github.com/gobuffalo/pop/v6" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -39,14 +36,6 @@ func (l *logRegistryOnly) Contextualizer() contextx.Contextualizer { panic("implement me") } -func (l *logRegistryOnly) IdentityTraitsSchemas(ctx context.Context) (schema.Schemas, error) { - panic("implement me") -} - -func (l *logRegistryOnly) IdentityValidator() *identity.Validator { - panic("implement me") -} - func (l *logRegistryOnly) Logger() *logrusx.Logger { if l.l == nil { l.l = logrusx.New("kratos", "testing") @@ -70,7 +59,7 @@ func TestPersisterHMAC(t *testing.T) { conf.MustSet(ctx, config.ViperKeySecretsDefault, []string{"foobarbaz"}) c, err := pop.NewConnection(&pop.ConnectionDetails{URL: "sqlite://foo?mode=memory"}) require.NoError(t, err) - p, err := NewPersister(context.Background(), &logRegistryOnly{c: conf}, c) + p, err := NewPersister(context.Background(), &logRegistryOnly{c: conf}, nil, c) require.NoError(t, err) assert.True(t, p.hmacConstantCompare(context.Background(), "hashme", p.hmacValue(context.Background(), "hashme"))) diff --git a/persistence/sql/persister_session.go b/persistence/sql/persister_session.go index c1a8b5efd50f..e97cf90fb07e 100644 --- a/persistence/sql/persister_session.go +++ b/persistence/sql/persister_session.go @@ -57,7 +57,7 @@ func (p *Persister) GetSession(ctx context.Context, sid uuid.UUID, expandables s if expandables.Has(session.ExpandSessionIdentity) { // This is needed because of how identities are fetched from the store (if we use eager not all fields are // available!). - i, err := p.GetIdentity(ctx, s.IdentityID, identity.ExpandDefault) + i, err := p.PrivilegedPool.GetIdentity(ctx, s.IdentityID, identity.ExpandDefault) if err != nil { return nil, err } @@ -116,7 +116,7 @@ func (p *Persister) ListSessions(ctx context.Context, active *bool, paginatorOpt if s[k].Identity == nil { continue } - if err := p.injectTraitsSchemaURL(ctx, s[k].Identity); err != nil { + if err := p.InjectTraitsSchemaURL(ctx, s[k].Identity); err != nil { return nil, 0, nil, err } } @@ -279,7 +279,7 @@ func (p *Persister) GetSessionByToken(ctx context.Context, token string, expand // available!). if expand.Has(session.ExpandSessionIdentity) { eg.Go(func() (err error) { - i, err = p.GetIdentity(ctx, s.IdentityID, identityExpand) + i, err = p.PrivilegedPool.GetIdentity(ctx, s.IdentityID, identityExpand) return err }) } diff --git a/persistence/sql/persister_settings.go b/persistence/sql/persister_settings.go index a511831334d7..c75be85c6d9e 100644 --- a/persistence/sql/persister_settings.go +++ b/persistence/sql/persister_settings.go @@ -39,7 +39,7 @@ func (p *Persister) GetSettingsFlow(ctx context.Context, id uuid.UUID) (*setting return nil, sqlcon.HandleError(err) } - r.Identity, err = p.GetIdentity(ctx, r.IdentityID, identity.ExpandDefault) + r.Identity, err = p.PrivilegedPool.GetIdentity(ctx, r.IdentityID, identity.ExpandDefault) if err != nil { return nil, err } From 19589c2427126f8107caa55a1e4574822b64d793 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Thu, 9 Feb 2023 22:40:07 +0100 Subject: [PATCH 02/24] fix: add limit clause in FindByCredentialsIdentifier --- .../sql/identity/persister_identity.go | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index 87929b158846..2a02718b00d5 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -111,7 +111,7 @@ func stringToLowerTrim(match string) string { return strings.ToLower(strings.TrimSpace(match)) } -func (p *IdentityPersister) normalizeIdentifier(ct identity.CredentialsType, match string) string { +func NormalizeIdentifier(ct identity.CredentialsType, match string) string { switch ct { case identity.CredentialsTypeLookup: // lookup credentials are case-sensitive @@ -141,22 +141,21 @@ func (p *IdentityPersister) FindByCredentialsIdentifier(ctx context.Context, ct } // Force case-insensitivity and trimming for identifiers - match = p.normalizeIdentifier(ct, match) - - // #nosec G201 - if err := p.GetConnection(ctx).RawQuery(fmt.Sprintf(`SELECT - ic.identity_id -FROM %s ic - INNER JOIN %s ict on ic.identity_credential_type_id = ict.id - INNER JOIN %s ici on ic.id = ici.identity_credential_id AND ici.identity_credential_type_id = ict.id -WHERE ici.identifier = ? - AND ic.nid = ? - AND ici.nid = ? - AND ict.name = ?`, - "identity_credentials", - "identity_credential_types", - "identity_credential_identifiers", - ), + match = NormalizeIdentifier(ct, match) + + if err := p.GetConnection(ctx).RawQuery(` + SELECT + ic.identity_id + FROM identity_credentials ic + INNER JOIN identity_credential_types ict + ON ic.identity_credential_type_id = ict.id + INNER JOIN identity_credential_identifiers ici + ON ic.id = ici.identity_credential_id AND ici.identity_credential_type_id = ict.id + WHERE ici.identifier = ? + AND ic.nid = ? + AND ici.nid = ? + AND ict.name = ? + LIMIT 1`, // pop doesn't understand how to add a limit clause to this query match, nid, nid, @@ -221,7 +220,7 @@ func (p *IdentityPersister) createIdentityCredentials(ctx context.Context, i *id for _, ids := range cred.Identifiers { // Force case-insensitivity and trimming for identifiers - ids = p.normalizeIdentifier(cred.Type, ids) + ids = NormalizeIdentifier(cred.Type, ids) if len(ids) == 0 { return errors.WithStack(herodot.ErrInternalServerError.WithReasonf("Unable to create identity credentials with missing or empty identifier.")) From f251cba344a17cb11e85744f9a1592fc1fe4c21e Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Sun, 12 Feb 2023 21:49:35 +0100 Subject: [PATCH 03/24] feat: refactor --- .../sql/identity/persister_identity.go | 143 ++++++++---------- selfservice/flow/login/hook.go | 16 +- selfservice/flow/registration/hook.go | 2 +- session/manager_http.go | 3 +- session/session.go | 4 +- 5 files changed, 82 insertions(+), 86 deletions(-) diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index 2a02718b00d5..fb19b00b8435 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -411,11 +411,70 @@ func (p *IdentityPersister) HydrateIdentityAssociations(ctx context.Context, i * ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.HydrateIdentityAssociations") defer otelx.End(span, &err) - con := p.GetConnection(ctx) - if err := con.Load(i, expand.ToEager()...); err != nil { + var ( + con = p.GetConnection(ctx) + nid = p.NetworkID(ctx) + credentials []identity.Credentials + verifiableAddresses []identity.VerifiableAddress + recoveryAddresses []identity.RecoveryAddress + ) + + eg, ctx := errgroup.WithContext(ctx) + if expand.Has(identity.ExpandFieldRecoveryAddresses) { + eg.Go(func() error { + // We use WithContext to get a copy of the connection struct, which solves the race detector + // from complaining incorrectly. + // + // https://github.com/gobuffalo/pop/issues/723 + if err := con.WithContext(ctx). + Where("identity_id = ? AND nid = ?", i.ID, nid). + Order("id ASC"). + All(&recoveryAddresses); err != nil { + return sqlcon.HandleError(err) + } + return nil + }) + } + + if expand.Has(identity.ExpandFieldVerifiableAddresses) { + eg.Go(func() error { + // We use WithContext to get a copy of the connection struct, which solves the race detector + // from complaining incorrectly. + // + // https://github.com/gobuffalo/pop/issues/723 + if err := con.WithContext(ctx). + Order("id ASC"). + Where("identity_id = ? AND nid = ?", i.ID, nid).All(&verifiableAddresses); err != nil { + return sqlcon.HandleError(err) + } + return nil + }) + } + + if expand.Has(identity.ExpandFieldCredentials) { + eg.Go(func() error { + // We use WithContext to get a copy of the connection struct, which solves the race detector + // from complaining incorrectly. + // + // https://github.com/gobuffalo/pop/issues/723 + if err := con.WithContext(ctx). + EagerPreload("IdentityCredentialType", "CredentialIdentifiers"). + Where("identity_id = ? AND nid = ?", i.ID, nid). + All(&credentials); err != nil { + return sqlcon.HandleError(err) + } + return nil + }) + } + + if err := eg.Wait(); err != nil { return err } + i.VerifiableAddresses = verifiableAddresses + i.RecoveryAddresses = recoveryAddresses + i.InternalCredentials = credentials + if err := i.AfterEagerFind(con); err != nil { return err } @@ -447,7 +506,7 @@ func (p *IdentityPersister) ListIdentities(ctx context.Context, params identity. if match := params.CredentialsIdentifier; len(match) > 0 { // When filtering by credentials identifier, we most likely are looking for a username or email. It is therefore // important to normalize the identifier before querying the database. - match = p.normalizeIdentifier(identity.CredentialsTypePassword, match) + match = NormalizeIdentifier(identity.CredentialsTypePassword, match) query = query. InnerJoin("identity_credentials ic", "ic.identity_id = identities.id"). InnerJoin("identity_credential_types ict", "ict.id = ic.identity_credential_type_id"). @@ -532,7 +591,7 @@ func (p *IdentityPersister) DeleteIdentity(ctx context.Context, id uuid.UUID) er return p.delete(ctx, new(identity.Identity), id) } -func (p *IdentityPersister) GetIdentity(ctx context.Context, id uuid.UUID, expand identity.Expandables) (res *identity.Identity, err error) { +func (p *IdentityPersister) GetIdentity(ctx context.Context, id uuid.UUID, expand identity.Expandables) (_ *identity.Identity, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.GetIdentity") defer otelx.End(span, &err) @@ -542,82 +601,12 @@ func (p *IdentityPersister) GetIdentity(ctx context.Context, id uuid.UUID, expan attribute.String("network.id", p.NetworkID(ctx).String()), ) - nid := p.NetworkID(ctx) - con := p.GetConnection(ctx) - query := con.Where("id = ? AND nid = ?", id, nid) - - var ( - i identity.Identity - credentials []identity.Credentials - verifiableAddresses []identity.VerifiableAddress - recoveryAddresses []identity.RecoveryAddress - ) - - if err := query.First(&i); err != nil { + var i identity.Identity + if err := p.GetConnection(ctx).Where("id = ? AND nid = ?", id, p.NetworkID(ctx)).First(&i); err != nil { return nil, sqlcon.HandleError(err) } - eg, ctx := errgroup.WithContext(ctx) - if expand.Has(identity.ExpandFieldRecoveryAddresses) { - eg.Go(func() error { - // We use WithContext to get a copy of the connection struct, which solves the race detector - // from complaining incorrectly. - // - // https://github.com/gobuffalo/pop/issues/723 - if err := con.WithContext(ctx). - Where("identity_id = ? AND nid = ?", i.ID, nid). - Order("id ASC"). - All(&recoveryAddresses); err != nil { - return sqlcon.HandleError(err) - } - return nil - }) - } - - if expand.Has(identity.ExpandFieldVerifiableAddresses) { - eg.Go(func() error { - // We use WithContext to get a copy of the connection struct, which solves the race detector - // from complaining incorrectly. - // - // https://github.com/gobuffalo/pop/issues/723 - if err := con.WithContext(ctx). - Order("id ASC"). - Where("identity_id = ? AND nid = ?", i.ID, nid).All(&verifiableAddresses); err != nil { - return sqlcon.HandleError(err) - } - return nil - }) - } - - if expand.Has(identity.ExpandFieldCredentials) { - eg.Go(func() error { - // We use WithContext to get a copy of the connection struct, which solves the race detector - // from complaining incorrectly. - // - // https://github.com/gobuffalo/pop/issues/723 - if err := con.WithContext(ctx). - EagerPreload("IdentityCredentialType", "CredentialIdentifiers"). - Where("identity_id = ? AND nid = ?", i.ID, nid). - All(&credentials); err != nil { - return sqlcon.HandleError(err) - } - return nil - }) - } - - if err := eg.Wait(); err != nil { - return nil, err - } - - i.VerifiableAddresses = verifiableAddresses - i.RecoveryAddresses = recoveryAddresses - i.InternalCredentials = credentials - - if err := i.AfterEagerFind(con); err != nil { - return nil, err - } - - if err := p.InjectTraitsSchemaURL(ctx, &i); err != nil { + if err := p.HydrateIdentityAssociations(ctx, &i, expand); err != nil { return nil, err } diff --git a/selfservice/flow/login/hook.go b/selfservice/flow/login/hook.go index 0346b976fb30..7517a0107f64 100644 --- a/selfservice/flow/login/hook.go +++ b/selfservice/flow/login/hook.go @@ -22,6 +22,7 @@ import ( "github.com/ory/kratos/ui/node" "github.com/ory/kratos/x" "github.com/ory/x/httpx" + "github.com/ory/x/otelx" "github.com/ory/x/otelx/semconv" ) @@ -49,6 +50,7 @@ type ( x.CSRFTokenGeneratorProvider x.WriterProvider x.LoggingProvider + x.TracingProvider HooksProvider } @@ -110,7 +112,12 @@ func (e *HookExecutor) handleLoginError(_ http.ResponseWriter, r *http.Request, return flowError } -func (e *HookExecutor) PostLoginHook(w http.ResponseWriter, r *http.Request, g node.UiNodeGroup, a *Flow, i *identity.Identity, s *session.Session) error { +func (e *HookExecutor) PostLoginHook(w http.ResponseWriter, r *http.Request, g node.UiNodeGroup, a *Flow, i *identity.Identity, s *session.Session) (err error) { + ctx := r.Context() + ctx, span := e.d.Tracer(ctx).Tracer().Start(ctx, "HookExecutor.PostLoginHook") + r = r.WithContext(ctx) + defer otelx.End(span, &err) + if err := s.Activate(r, i, e.d.Config(), time.Now().UTC()); err != nil { return err } @@ -128,7 +135,8 @@ func (e *HookExecutor) PostLoginHook(w http.ResponseWriter, r *http.Request, g n return err } - s = s.Declassify() + classified := s + s = s.Declassified() e.d.Logger(). WithRequest(r). @@ -181,7 +189,7 @@ func (e *HookExecutor) PostLoginHook(w http.ResponseWriter, r *http.Request, g n ) response := &APIFlowResponse{Session: s, Token: s.Token} - if required, _ := e.requiresAAL2(r, s, a); required { + if required, _ := e.requiresAAL2(r, classified, a); required { // If AAL is not satisfied, we omit the identity to preserve the user's privacy in case of a phishing attack. response.Session.Identity = nil } @@ -240,7 +248,7 @@ func (e *HookExecutor) PostLoginHook(w http.ResponseWriter, r *http.Request, g n finalReturnTo = rt } - x.ContentNegotiationRedirection(w, r, s.Declassify(), e.d.Writer(), finalReturnTo) + x.ContentNegotiationRedirection(w, r, s, e.d.Writer(), finalReturnTo) return nil } diff --git a/selfservice/flow/registration/hook.go b/selfservice/flow/registration/hook.go index 41f5f8e498d5..25339d610afc 100644 --- a/selfservice/flow/registration/hook.go +++ b/selfservice/flow/registration/hook.go @@ -230,7 +230,7 @@ func (e *HookExecutor) PostRegistrationHook(w http.ResponseWriter, r *http.Reque finalReturnTo = cr } - x.ContentNegotiationRedirection(w, r, s.Declassify(), e.d.Writer(), finalReturnTo) + x.ContentNegotiationRedirection(w, r, s.Declassified(), e.d.Writer(), finalReturnTo) return nil } diff --git a/session/manager_http.go b/session/manager_http.go index 7bc438111002..e6bb6c4e43c0 100644 --- a/session/manager_http.go +++ b/session/manager_http.go @@ -273,9 +273,8 @@ func (s *ManagerHTTP) DoesSessionSatisfy(r *http.Request, sess *Session, request if err != nil { return err } - sess.Identity = i } else if len(i.Credentials) == 0 { - // If credentials are not expanded, we load them here. + i = sess.Identity.CopyWithoutCredentials() // we don't want to modify the identity in the session object if err := s.r.PrivilegedIdentityPool().HydrateIdentityAssociations(ctx, i, identity.ExpandCredentials); err != nil { return err } diff --git a/session/session.go b/session/session.go index 825409ce1b38..b072c8240b38 100644 --- a/session/session.go +++ b/session/session.go @@ -261,9 +261,9 @@ func (s *Session) SetSessionDeviceInformation(r *http.Request) { s.Devices = append(s.Devices, device) } -func (s *Session) Declassify() *Session { +func (s Session) Declassified() *Session { s.Identity = s.Identity.CopyWithoutCredentials() - return s + return &s } func (s *Session) IsActive() bool { From 68c2c66b87b8ee3e7c6a525a5d68ebd38701ce24 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Tue, 14 Feb 2023 14:59:09 +0100 Subject: [PATCH 04/24] fix: nid injection --- driver/registry_default.go | 2 +- internal/driver.go | 4 +--- persistence/sql/identity/persister_identity.go | 5 ++--- persistence/sql/persister.go | 8 ++++++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/driver/registry_default.go b/driver/registry_default.go index d8d3ad11b86b..d9d876f12f16 100644 --- a/driver/registry_default.go +++ b/driver/registry_default.go @@ -644,7 +644,7 @@ func (m *RegistryDefault) Init(ctx context.Context, ctxer contextx.Contextualize return err } - p.PrivilegedPool.(*idpersistence.IdentityPersister).SetNetworkID(net.ID) + // p.PrivilegedPool.(*idpersistence.IdentityPersister).SetNetworkID(net.ID) m.persister = p.WithNetworkID(net.ID) return nil }, bc) diff --git a/internal/driver.go b/internal/driver.go index 2aa405bb87f9..fc761e4561d6 100644 --- a/internal/driver.go +++ b/internal/driver.go @@ -23,8 +23,6 @@ import ( "github.com/ory/kratos/driver" "github.com/ory/kratos/driver/config" - "github.com/ory/kratos/persistence/sql" - idpersistence "github.com/ory/kratos/persistence/sql/identity" "github.com/ory/kratos/selfservice/hook" "github.com/ory/kratos/x" ) @@ -89,7 +87,7 @@ func NewRegistryDefaultWithDSN(t *testing.T, dsn string) (*config.Config, *drive actual, err := reg.Persister().DetermineNetwork(context.Background()) require.NoError(t, err) reg.SetPersister(reg.Persister().WithNetworkID(actual.ID)) - reg.Persister().(*sql.Persister).PrivilegedPool.(*idpersistence.IdentityPersister).SetNetworkID(actual.ID) + // reg.Persister().(*sql.Persister).PrivilegedPool.(*idpersistence.IdentityPersister).SetNetworkID(actual.ID) require.EqualValues(t, reg.Persister().NetworkID(context.Background()), actual.ID) require.NotEqual(t, uuid.Nil, reg.Persister().NetworkID(context.Background())) diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index fb19b00b8435..5380c22f1c70 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -68,9 +68,8 @@ func (p *IdentityPersister) NetworkID(ctx context.Context) uuid.UUID { return p.r.Contextualizer().Network(ctx, p.nid) } -func (p *IdentityPersister) SetNetworkID(sid uuid.UUID) *IdentityPersister { - p.nid = sid - return p +func (p *IdentityPersister) SetNetworkID(nid uuid.UUID) { + p.nid = nid } func WithTransaction(ctx context.Context, tx *pop.Connection) context.Context { diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index dcca5fb3ce1f..f884f6c04e4b 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -72,8 +72,12 @@ func (p *Persister) NetworkID(ctx context.Context) uuid.UUID { return p.r.Contextualizer().Network(ctx, p.nid) } -func (p Persister) WithNetworkID(sid uuid.UUID) persistence.Persister { - p.nid = sid +func (p Persister) WithNetworkID(nid uuid.UUID) persistence.Persister { + p.nid = nid + set, ok := p.PrivilegedPool.(interface{ SetNetworkID(uuid.UUID) }) + if ok { + set.SetNetworkID(nid) + } return &p } From dc60adba14f98b8b0d21fc497f5799e9242fb49d Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Tue, 14 Feb 2023 17:20:25 +0100 Subject: [PATCH 05/24] feat: factor out device persister --- driver/registry_default.go | 4 +- internal/driver.go | 1 - persistence/sql/devices/persister_devices.go | 44 ++++++++++++++++++++ persistence/sql/persister.go | 39 ++++++++++------- persistence/sql/persister_hmac_test.go | 11 ++++- persistence/sql/persister_session.go | 22 ++++------ session/persistence.go | 4 ++ 7 files changed, 90 insertions(+), 35 deletions(-) create mode 100644 persistence/sql/devices/persister_devices.go diff --git a/driver/registry_default.go b/driver/registry_default.go index d9d876f12f16..d199a4f901a1 100644 --- a/driver/registry_default.go +++ b/driver/registry_default.go @@ -72,7 +72,6 @@ import ( "github.com/ory/kratos/driver/config" "github.com/ory/kratos/identity" - idpersistence "github.com/ory/kratos/persistence/sql/identity" "github.com/ory/kratos/selfservice/errorx" password2 "github.com/ory/kratos/selfservice/strategy/password" "github.com/ory/kratos/session" @@ -613,7 +612,7 @@ func (m *RegistryDefault) Init(ctx context.Context, ctxer contextx.Contextualize m.Logger().WithError(err).Warnf("Unable to open database, retrying.") return errors.WithStack(err) } - p, err := sql.NewPersister(ctx, m, idpersistence.NewPersister(m, c), c) + p, err := sql.NewPersister(ctx, m, c) if err != nil { m.Logger().WithError(err).Warnf("Unable to initialize persister, retrying.") return err @@ -644,7 +643,6 @@ func (m *RegistryDefault) Init(ctx context.Context, ctxer contextx.Contextualize return err } - // p.PrivilegedPool.(*idpersistence.IdentityPersister).SetNetworkID(net.ID) m.persister = p.WithNetworkID(net.ID) return nil }, bc) diff --git a/internal/driver.go b/internal/driver.go index fc761e4561d6..101fe85cbba8 100644 --- a/internal/driver.go +++ b/internal/driver.go @@ -87,7 +87,6 @@ func NewRegistryDefaultWithDSN(t *testing.T, dsn string) (*config.Config, *drive actual, err := reg.Persister().DetermineNetwork(context.Background()) require.NoError(t, err) reg.SetPersister(reg.Persister().WithNetworkID(actual.ID)) - // reg.Persister().(*sql.Persister).PrivilegedPool.(*idpersistence.IdentityPersister).SetNetworkID(actual.ID) require.EqualValues(t, reg.Persister().NetworkID(context.Background()), actual.ID) require.NotEqual(t, uuid.Nil, reg.Persister().NetworkID(context.Background())) diff --git a/persistence/sql/devices/persister_devices.go b/persistence/sql/devices/persister_devices.go new file mode 100644 index 000000000000..0cfcea4dad26 --- /dev/null +++ b/persistence/sql/devices/persister_devices.go @@ -0,0 +1,44 @@ +// Copyright © 2023 Ory Corp +// SPDX-License-Identifier: Apache-2.0 + +package devices + +import ( + "context" + + "github.com/gobuffalo/pop/v6" + "github.com/gofrs/uuid" + + "github.com/ory/kratos/session" + "github.com/ory/x/contextx" + "github.com/ory/x/popx" + "github.com/ory/x/sqlcon" +) + +var _ session.DevicePersister = (*DevicePersister)(nil) + +type DevicePersister struct { + ctxer contextx.Provider + c *pop.Connection + nid uuid.UUID +} + +func NewPersister(r contextx.Provider, c *pop.Connection) *DevicePersister { + return &DevicePersister{ + ctxer: r, + c: c, + } +} + +func (p *DevicePersister) NetworkID(ctx context.Context) uuid.UUID { + return p.ctxer.Contextualizer().Network(ctx, p.nid) +} + +func (p *DevicePersister) SetNetworkID(nid uuid.UUID) { + p.nid = nid +} + +func (p *DevicePersister) CreateDevice(ctx context.Context, d *session.Device) error { + d.NID = p.NetworkID(ctx) + return sqlcon.HandleError(popx.GetConnection(ctx, p.c.WithContext(ctx)).Create(d)) +} diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index f884f6c04e4b..88174f5ce2d7 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -9,24 +9,24 @@ import ( "fmt" "time" - "github.com/ory/x/contextx" - - "github.com/ory/x/fsx" - "github.com/gobuffalo/pop/v6" "github.com/gobuffalo/pop/v6/columns" "github.com/gofrs/uuid" "github.com/pkg/errors" - "github.com/ory/x/networkx" - "github.com/ory/x/sqlcon" - - "github.com/ory/x/popx" - "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" + "github.com/ory/kratos/schema" + "github.com/ory/kratos/session" "github.com/ory/kratos/x" + "github.com/ory/x/contextx" + "github.com/ory/x/fsx" + "github.com/ory/x/networkx" + "github.com/ory/x/popx" + "github.com/ory/x/sqlcon" ) var _ persistence.Persister = new(Persister) @@ -40,6 +40,8 @@ type ( config.Provider contextx.Provider x.TracingProvider + schema.IdentityTraitsProvider + identity.ValidationProvider } Persister struct { nid uuid.UUID @@ -48,11 +50,13 @@ type ( mbs popx.MigrationStatuses r persisterDependencies p *networkx.Manager + identity.PrivilegedPool + session.DevicePersister } ) -func NewPersister(ctx context.Context, r persisterDependencies, pool identity.PrivilegedPool, c *pop.Connection) (*Persister, error) { +func NewPersister(ctx context.Context, r persisterDependencies, c *pop.Connection) (*Persister, error) { m, err := popx.NewMigrationBox(fsx.Merge(migrations, networkx.Migrations), popx.NewMigrator(c, r.Logger(), r.Tracer(ctx), 0)) if err != nil { return nil, err @@ -60,11 +64,12 @@ func NewPersister(ctx context.Context, r persisterDependencies, pool identity.Pr m.DumpMigrations = false return &Persister{ - c: c, - mb: m, - r: r, - PrivilegedPool: pool, - p: networkx.NewManager(c, r.Logger(), r.Tracer(ctx)), + c: c, + mb: m, + r: r, + PrivilegedPool: idpersistence.NewPersister(r, c), + DevicePersister: devices.NewPersister(r, c), + p: networkx.NewManager(c, r.Logger(), r.Tracer(ctx)), }, nil } @@ -78,6 +83,10 @@ func (p Persister) WithNetworkID(nid uuid.UUID) persistence.Persister { if ok { set.SetNetworkID(nid) } + set, ok = p.DevicePersister.(interface{ SetNetworkID(uuid.UUID) }) + if ok { + set.SetNetworkID(nid) + } return &p } diff --git a/persistence/sql/persister_hmac_test.go b/persistence/sql/persister_hmac_test.go index e281d6fa262c..05dcd5985908 100644 --- a/persistence/sql/persister_hmac_test.go +++ b/persistence/sql/persister_hmac_test.go @@ -20,6 +20,8 @@ import ( "github.com/ory/x/logrusx" "github.com/ory/kratos/driver/config" + "github.com/ory/kratos/identity" + "github.com/ory/kratos/schema" ) type logRegistryOnly struct { @@ -50,6 +52,13 @@ func (l *logRegistryOnly) Audit() *logrusx.Logger { func (l *logRegistryOnly) Tracer(ctx context.Context) *otelx.Tracer { return otelx.NewNoop(l.l, new(otelx.Config)) } +func (l *logRegistryOnly) IdentityTraitsSchemas(ctx context.Context) (schema.Schemas, error) { + panic("implement me") +} + +func (l *logRegistryOnly) IdentityValidator() *identity.Validator { + panic("implement me") +} var _ persisterDependencies = &logRegistryOnly{} @@ -59,7 +68,7 @@ func TestPersisterHMAC(t *testing.T) { conf.MustSet(ctx, config.ViperKeySecretsDefault, []string{"foobarbaz"}) c, err := pop.NewConnection(&pop.ConnectionDetails{URL: "sqlite://foo?mode=memory"}) require.NoError(t, err) - p, err := NewPersister(context.Background(), &logRegistryOnly{c: conf}, nil, c) + p, err := NewPersister(context.Background(), &logRegistryOnly{c: conf}, c) require.NoError(t, err) assert.True(t, p.hmacConstantCompare(context.Background(), "hashme", p.hmacValue(context.Background(), "hashme"))) diff --git a/persistence/sql/persister_session.go b/persistence/sql/persister_session.go index e97cf90fb07e..7377d1435983 100644 --- a/persistence/sql/persister_session.go +++ b/persistence/sql/persister_session.go @@ -8,25 +8,17 @@ import ( "fmt" "time" + "github.com/gobuffalo/pop/v6" + "github.com/gofrs/uuid" + "github.com/pkg/errors" "golang.org/x/sync/errgroup" - "github.com/ory/x/otelx" - "github.com/ory/kratos/identity" - + "github.com/ory/kratos/session" + "github.com/ory/x/otelx" "github.com/ory/x/pagination/keysetpagination" - - "github.com/ory/x/stringsx" - - "github.com/gobuffalo/pop/v6" - - "github.com/pkg/errors" - - "github.com/gofrs/uuid" - "github.com/ory/x/sqlcon" - - "github.com/ory/kratos/session" + "github.com/ory/x/stringsx" ) var _ session.Persister = new(Persister) @@ -212,7 +204,7 @@ func (p *Persister) UpsertSession(ctx context.Context, s *session.Session) (err device.UserAgent = stringsx.GetPointer(stringsx.TruncateByteLen(*device.UserAgent, SessionDeviceUserAgentMaxLength)) } - if err := sqlcon.HandleError(tx.Create(device)); err != nil { + if err := p.DevicePersister.CreateDevice(ctx, device); err != nil { return err } } diff --git a/session/persistence.go b/session/persistence.go index 1d0903c488b5..34bf4d2654d4 100644 --- a/session/persistence.go +++ b/session/persistence.go @@ -68,3 +68,7 @@ type Persister interface { // RevokeSessionsIdentityExcept marks all except the given session of an identity inactive. It returns the number of sessions that were revoked. RevokeSessionsIdentityExcept(ctx context.Context, iID, sID uuid.UUID) (int, error) } + +type DevicePersister interface { + CreateDevice(ctx context.Context, d *Device) error +} From 8028d94a9b69919c63f2f575c58e5ebd72041c19 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Wed, 15 Feb 2023 12:17:54 +0100 Subject: [PATCH 06/24] fix: WithNetworkID --- identity/test/pool.go | 4 +--- persistence/sql/devices/persister_devices.go | 3 ++- persistence/sql/identity/persister_identity.go | 3 ++- persistence/sql/persister.go | 14 ++++++++------ 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/identity/test/pool.go b/identity/test/pool.go index b2050080c6dc..12d89939a89c 100644 --- a/identity/test/pool.go +++ b/identity/test/pool.go @@ -41,9 +41,7 @@ import ( "github.com/ory/kratos/x" ) -func TestPool(ctx context.Context, conf *config.Config, p interface { - persistence.Persister -}, m *identity.Manager) func(t *testing.T) { +func TestPool(ctx context.Context, conf *config.Config, p persistence.Persister, m *identity.Manager) func(t *testing.T) { return func(t *testing.T) { exampleServerURL := urlx.ParseOrPanic("http://example.com") conf.MustSet(ctx, config.ViperKeyPublicBaseURL, exampleServerURL.String()) diff --git a/persistence/sql/devices/persister_devices.go b/persistence/sql/devices/persister_devices.go index 0cfcea4dad26..b6909b132eb3 100644 --- a/persistence/sql/devices/persister_devices.go +++ b/persistence/sql/devices/persister_devices.go @@ -34,8 +34,9 @@ func (p *DevicePersister) NetworkID(ctx context.Context) uuid.UUID { return p.ctxer.Contextualizer().Network(ctx, p.nid) } -func (p *DevicePersister) SetNetworkID(nid uuid.UUID) { +func (p DevicePersister) WithNetworkID(nid uuid.UUID) session.DevicePersister { p.nid = nid + return &p } func (p *DevicePersister) CreateDevice(ctx context.Context, d *session.Device) error { diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index 5380c22f1c70..d7a413c6c849 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -68,8 +68,9 @@ func (p *IdentityPersister) NetworkID(ctx context.Context) uuid.UUID { return p.r.Contextualizer().Network(ctx, p.nid) } -func (p *IdentityPersister) SetNetworkID(nid uuid.UUID) { +func (p IdentityPersister) WithNetworkID(nid uuid.UUID) identity.PrivilegedPool { p.nid = nid + return &p } func WithTransaction(ctx context.Context, tx *pop.Connection) context.Context { diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index 88174f5ce2d7..b90f6cef6c90 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -79,13 +79,15 @@ func (p *Persister) NetworkID(ctx context.Context) uuid.UUID { func (p Persister) WithNetworkID(nid uuid.UUID) persistence.Persister { p.nid = nid - set, ok := p.PrivilegedPool.(interface{ SetNetworkID(uuid.UUID) }) - if ok { - set.SetNetworkID(nid) + if pp, ok := p.PrivilegedPool.(interface { + WithNetworkID(uuid.UUID) identity.PrivilegedPool + }); ok { + p.PrivilegedPool = pp.WithNetworkID(nid) } - set, ok = p.DevicePersister.(interface{ SetNetworkID(uuid.UUID) }) - if ok { - set.SetNetworkID(nid) + if dp, ok := p.DevicePersister.(interface { + WithNetworkID(uuid.UUID) session.DevicePersister + }); ok { + p.DevicePersister = dp.WithNetworkID(nid) } return &p } From c0b38a1e5cfb57b4fc59b7b539c9ed92ce31e34c Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Wed, 22 Feb 2023 17:55:09 +0100 Subject: [PATCH 07/24] fix: don't test internals --- identity/test/pool.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/identity/test/pool.go b/identity/test/pool.go index 12d89939a89c..5f1b2fe32827 100644 --- a/identity/test/pool.go +++ b/identity/test/pool.go @@ -132,7 +132,6 @@ func TestPool(ctx context.Context, conf *config.Config, p persistence.Persister, assert.Empty(t, actual.RecoveryAddresses) assert.Empty(t, actual.VerifiableAddresses) - require.Len(t, actual.InternalCredentials, 2) require.Len(t, actual.Credentials, 2) assertx.EqualAsJSONExcept(t, expected.Credentials[identity.CredentialsTypePassword], actual.Credentials[identity.CredentialsTypePassword], []string{"updated_at", "created_at"}) @@ -179,7 +178,6 @@ func TestPool(ctx context.Context, conf *config.Config, p persistence.Persister, t.Run("expand=everything", func(t *testing.T) { runner(t, identity.ExpandEverything, func(t *testing.T, actual *identity.Identity) { - require.Len(t, actual.InternalCredentials, 2) require.Len(t, actual.Credentials, 2) assertx.EqualAsJSONExcept(t, expected.Credentials[identity.CredentialsTypePassword], actual.Credentials[identity.CredentialsTypePassword], []string{"updated_at", "created_at"}) @@ -197,7 +195,6 @@ func TestPool(ctx context.Context, conf *config.Config, p persistence.Persister, runner(t, identity.ExpandNothing, func(t *testing.T, actual *identity.Identity) { require.NoError(t, p.HydrateIdentityAssociations(ctx, actual, identity.ExpandEverything)) - require.Len(t, actual.InternalCredentials, 2) require.Len(t, actual.Credentials, 2) assertx.EqualAsJSONExcept(t, expected.Credentials[identity.CredentialsTypePassword], actual.Credentials[identity.CredentialsTypePassword], []string{"updated_at", "created_at"}) From 9f2361f34bc40869a55385803516cbeb5b737d35 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Wed, 22 Feb 2023 17:55:47 +0100 Subject: [PATCH 08/24] fix: verbose logging --- driver/registry_default.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/driver/registry_default.go b/driver/registry_default.go index d199a4f901a1..f02bb440d465 100644 --- a/driver/registry_default.go +++ b/driver/registry_default.go @@ -517,8 +517,7 @@ func (m *RegistryDefault) ContinuityCookieManager(ctx context.Context) sessions. func (m *RegistryDefault) Tracer(ctx context.Context) *otelx.Tracer { if m.trc == nil { - m.Logger().WithError(errors.WithStack(errors.New(""))).Warn("No tracer setup in RegistryDefault") - return otelx.NewNoop(m.l, m.Config().Tracing(ctx)) // should never happen + return otelx.NewNoop(m.l, m.Config().Tracing(ctx)) } return m.trc } From a9e8e796c23188fd79b266065a5c2672dfccb02a Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Wed, 22 Feb 2023 17:57:23 +0100 Subject: [PATCH 09/24] feat: expose MigrationBox and pass through driver options to migrate command --- cmd/cliclient/migrate.go | 4 ++-- cmd/migrate/sql.go | 5 +++-- persistence/reference.go | 1 + persistence/sql/migratest/migration_test.go | 4 +--- persistence/sql/persister.go | 4 ++++ 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/cmd/cliclient/migrate.go b/cmd/cliclient/migrate.go index c0f8bf2ccb40..e22dcf2ed73c 100644 --- a/cmd/cliclient/migrate.go +++ b/cmd/cliclient/migrate.go @@ -32,7 +32,7 @@ func NewMigrateHandler() *MigrateHandler { return &MigrateHandler{} } -func (h *MigrateHandler) MigrateSQL(cmd *cobra.Command, args []string) error { +func (h *MigrateHandler) MigrateSQL(cmd *cobra.Command, args []string, opts ...driver.RegistryOption) error { var d driver.Registry var err error @@ -78,7 +78,7 @@ func (h *MigrateHandler) MigrateSQL(cmd *cobra.Command, args []string) error { } } - err = d.Init(cmd.Context(), &contextx.Default{}, driver.SkipNetworkInit) + err = d.Init(cmd.Context(), &contextx.Default{}, append(opts, driver.SkipNetworkInit)...) if err != nil { return errors.Wrap(err, "an error occurred initializing migrations") } diff --git a/cmd/migrate/sql.go b/cmd/migrate/sql.go index eb654c7a9f65..a1e940235304 100644 --- a/cmd/migrate/sql.go +++ b/cmd/migrate/sql.go @@ -7,11 +7,12 @@ import ( "github.com/spf13/cobra" "github.com/ory/kratos/cmd/cliclient" + "github.com/ory/kratos/driver" "github.com/ory/x/configx" ) // migrateSqlCmd represents the sql command -func NewMigrateSQLCmd() *cobra.Command { +func NewMigrateSQLCmd(opts ...driver.RegistryOption) *cobra.Command { c := &cobra.Command{ Use: "sql ", Short: "Create SQL schemas and apply migration plans", @@ -29,7 +30,7 @@ You can read in the database URL using the -e flag, for example: Before running this command on an existing database, create a back up! `, RunE: func(cmd *cobra.Command, args []string) error { - return cliclient.NewMigrateHandler().MigrateSQL(cmd, args) + return cliclient.NewMigrateHandler().MigrateSQL(cmd, args, opts...) }, } diff --git a/persistence/reference.go b/persistence/reference.go index 85f0b6e43984..1ab56c56f909 100644 --- a/persistence/reference.go +++ b/persistence/reference.go @@ -57,6 +57,7 @@ type Persister interface { MigrateDown(c context.Context, steps int) error MigrateUp(c context.Context) error Migrator() *popx.Migrator + MigrationBox() *popx.MigrationBox GetConnection(ctx context.Context) *pop.Connection Transaction(ctx context.Context, callback func(ctx context.Context, connection *pop.Connection) error) error Networker diff --git a/persistence/sql/migratest/migration_test.go b/persistence/sql/migratest/migration_test.go index abd67f2f6bc2..1e54469d4cbf 100644 --- a/persistence/sql/migratest/migration_test.go +++ b/persistence/sql/migratest/migration_test.go @@ -15,8 +15,6 @@ import ( "github.com/ory/x/servicelocatorx" - "github.com/ory/x/fsx" - "github.com/ory/kratos/identity" "github.com/bradleyjkemp/cupaloy/v2" @@ -124,7 +122,7 @@ func TestMigrations(t *testing.T) { t.Run("suite=up", func(t *testing.T) { tm, err := popx.NewMigrationBox( - fsx.Merge(os.DirFS("../migrations/sql")), + os.DirFS("../migrations/sql"), popx.NewMigrator(c, logrusx.New("", "", logrusx.ForceLevel(logrus.DebugLevel)), nil, 1*time.Minute), popx.WithTestdata(t, os.DirFS("./testdata")), ) diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index b90f6cef6c90..5dd59609102c 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -128,6 +128,10 @@ 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) Migrator() *popx.Migrator { return p.mb.Migrator } From a0fb6bd71f01dd339798c550bdb7819f2fe5111f Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Wed, 22 Feb 2023 17:57:53 +0100 Subject: [PATCH 10/24] fix: use laher/mergefs instead of home-grown filesystem merging --- go.mod | 1 + go.sum | 4 ++++ persistence/sql/persister.go | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 10e07483d99e..d3fc16f6546e 100644 --- a/go.mod +++ b/go.mod @@ -61,6 +61,7 @@ require ( github.com/jteeuwen/go-bindata v3.0.7+incompatible github.com/julienschmidt/httprouter v1.3.0 github.com/knadh/koanf v1.4.4 + github.com/laher/mergefs v0.1.1 github.com/luna-duclos/instrumentedsql v1.1.3 github.com/mattn/goveralls v0.0.7 github.com/mikefarah/yq/v4 v4.19.1 diff --git a/go.sum b/go.sum index c0e642be0835..96ceaaec1c59 100644 --- a/go.sum +++ b/go.sum @@ -913,6 +913,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/go-gypsy v1.0.0/go.mod h1:chkXM0zjdpXOiqkCW1XcCHDfjfk14PH2KKkQWxfJUcU= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/laher/mergefs v0.1.1 h1:nV2bTS57vrmbMxeR6uvJpI8LyGl3QHj4bLBZO3aUV58= +github.com/laher/mergefs v0.1.1/go.mod h1:FSY1hYy94on4Tz60waRMGdO1awwS23BacqJlqf9lJ9Q= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= @@ -945,6 +947,8 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/pkger v0.17.1 h1:/MKEtWqtc0mZvu9OinB9UzVN9iYCwLWuyUv4Bw+PCno= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index 5dd59609102c..58dba8c51ced 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -12,6 +12,7 @@ import ( "github.com/gobuffalo/pop/v6" "github.com/gobuffalo/pop/v6/columns" "github.com/gofrs/uuid" + "github.com/laher/mergefs" "github.com/pkg/errors" "github.com/ory/kratos/driver/config" @@ -23,7 +24,6 @@ import ( "github.com/ory/kratos/session" "github.com/ory/kratos/x" "github.com/ory/x/contextx" - "github.com/ory/x/fsx" "github.com/ory/x/networkx" "github.com/ory/x/popx" "github.com/ory/x/sqlcon" @@ -57,7 +57,7 @@ type ( ) func NewPersister(ctx context.Context, r persisterDependencies, c *pop.Connection) (*Persister, error) { - m, err := popx.NewMigrationBox(fsx.Merge(migrations, networkx.Migrations), popx.NewMigrator(c, r.Logger(), r.Tracer(ctx), 0)) + m, err := popx.NewMigrationBox(mergefs.Merge(migrations, networkx.Migrations), popx.NewMigrator(c, r.Logger(), r.Tracer(ctx), 0)) if err != nil { return nil, err } From 6360905c7a068bddf0fcfa860115ec7d17b6eb16 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Thu, 23 Feb 2023 21:05:23 +0100 Subject: [PATCH 11/24] chore: bump laher/mergefs --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d3fc16f6546e..74d575bdacec 100644 --- a/go.mod +++ b/go.mod @@ -61,7 +61,7 @@ require ( github.com/jteeuwen/go-bindata v3.0.7+incompatible github.com/julienschmidt/httprouter v1.3.0 github.com/knadh/koanf v1.4.4 - github.com/laher/mergefs v0.1.1 + github.com/laher/mergefs v0.1.2-0.20230223191438-d16611b2f4e7 github.com/luna-duclos/instrumentedsql v1.1.3 github.com/mattn/goveralls v0.0.7 github.com/mikefarah/yq/v4 v4.19.1 diff --git a/go.sum b/go.sum index 96ceaaec1c59..356691654031 100644 --- a/go.sum +++ b/go.sum @@ -913,8 +913,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/go-gypsy v1.0.0/go.mod h1:chkXM0zjdpXOiqkCW1XcCHDfjfk14PH2KKkQWxfJUcU= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/laher/mergefs v0.1.1 h1:nV2bTS57vrmbMxeR6uvJpI8LyGl3QHj4bLBZO3aUV58= -github.com/laher/mergefs v0.1.1/go.mod h1:FSY1hYy94on4Tz60waRMGdO1awwS23BacqJlqf9lJ9Q= +github.com/laher/mergefs v0.1.2-0.20230223191438-d16611b2f4e7 h1:PDeBswTUsSIT4QSrzLvlqKlGrANYa7TrXUwdBN9myU8= +github.com/laher/mergefs v0.1.2-0.20230223191438-d16611b2f4e7/go.mod h1:FSY1hYy94on4Tz60waRMGdO1awwS23BacqJlqf9lJ9Q= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag= From 5b06143c67cdfe6f255553c234f5af80416fb11a Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Wed, 1 Mar 2023 16:27:50 +0100 Subject: [PATCH 12/24] feat: allow server termination through context cancelation --- cmd/courier/watch.go | 34 +++++++++------------------------- cmd/daemon/serve.go | 4 ++-- go.mod | 4 ++-- go.sum | 7 ++++--- 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/cmd/courier/watch.go b/cmd/courier/watch.go index 197347dabd0c..b32bc4b3b280 100644 --- a/cmd/courier/watch.go +++ b/cmd/courier/watch.go @@ -4,7 +4,7 @@ package courier import ( - cx "context" + "context" "net/http" "github.com/spf13/cobra" @@ -22,7 +22,7 @@ import ( ) func NewWatchCmd(slOpts []servicelocatorx.Option, dOpts []driver.RegistryOption) *cobra.Command { - var c = &cobra.Command{ + c := &cobra.Command{ Use: "watch", Short: "Starts the Ory Kratos message courier", RunE: func(cmd *cobra.Command, args []string) error { @@ -38,7 +38,7 @@ func NewWatchCmd(slOpts []servicelocatorx.Option, dOpts []driver.RegistryOption) return c } -func StartCourier(ctx cx.Context, r driver.Registry) error { +func StartCourier(ctx context.Context, r driver.Registry) error { eg, ctx := errgroup.WithContext(ctx) if r.Config().CourierExposeMetricsPort(ctx) != 0 { @@ -54,7 +54,7 @@ func StartCourier(ctx cx.Context, r driver.Registry) error { return eg.Wait() } -func ServeMetrics(ctx cx.Context, r driver.Registry) error { +func ServeMetrics(ctx context.Context, r driver.Registry) error { c := r.Config() l := r.Logger() n := negroni.New() @@ -80,32 +80,16 @@ func ServeMetrics(ctx cx.Context, r driver.Registry) error { }) l.Printf("Starting the metrics httpd on: %s", server.Addr) - if err := graceful.Graceful(func() error { - errChan := make(chan error, 1) - go func(errChan chan error) { - if err := server.ListenAndServe(); err != nil { - errChan <- err - } - }(errChan) - select { - case err := <-errChan: - l.Errorf("Failed to start the metrics httpd: %s\n", err) - return err - case <-ctx.Done(): - l.Printf("Shutting down the metrics httpd: context closed: %s\n", ctx.Err()) - return server.Shutdown(ctx) - } - }, server.Shutdown); err != nil { + if err := graceful.GracefulContext(ctx, server.ListenAndServe, server.Shutdown); err != nil { l.Errorln("Failed to gracefully shutdown metrics httpd") return err - } else { - l.Println("Metrics httpd was shutdown gracefully") } + l.Println("Metrics httpd was shutdown gracefully") return nil } -func Watch(ctx cx.Context, r driver.Registry) error { - ctx, cancel := cx.WithCancel(ctx) +func Watch(ctx context.Context, r driver.Registry) error { + ctx, cancel := context.WithCancel(ctx) r.Logger().Println("Courier worker started.") if err := graceful.Graceful(func() error { @@ -115,7 +99,7 @@ func Watch(ctx cx.Context, r driver.Registry) error { } return c.Work(ctx) - }, func(_ cx.Context) error { + }, func(_ context.Context) error { cancel() return nil }); err != nil { diff --git a/cmd/daemon/serve.go b/cmd/daemon/serve.go index b25f7eda9786..c0689921537f 100644 --- a/cmd/daemon/serve.go +++ b/cmd/daemon/serve.go @@ -128,7 +128,7 @@ func ServePublic(r driver.Registry, cmd *cobra.Command, args []string, slOpts *s addr := c.PublicListenOn(ctx) l.Printf("Starting the public httpd on: %s", addr) - if err := graceful.Graceful(func() error { + if err := graceful.GracefulContext(ctx, func() error { listener, err := networkx.MakeListener(addr, c.PublicSocketPermission(ctx)) if err != nil { return err @@ -200,7 +200,7 @@ func ServeAdmin(r driver.Registry, cmd *cobra.Command, args []string, slOpts *se addr := c.AdminListenOn(ctx) l.Printf("Starting the admin httpd on: %s", addr) - if err := graceful.Graceful(func() error { + if err := graceful.GracefulContext(ctx, func() error { listener, err := networkx.MakeListener(addr, c.AdminSocketPermission(ctx)) if err != nil { return err diff --git a/go.mod b/go.mod index 74d575bdacec..b501a219b098 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/ory/client-go v0.2.0-alpha.60 github.com/ory/dockertest/v3 v3.9.1 github.com/ory/go-acc v0.2.9-0.20230103102148-6b1c9a70dbbe - github.com/ory/graceful v0.1.3 + github.com/ory/graceful v0.1.4-0.20230301144740-e222150c51d0 github.com/ory/herodot v0.9.13 github.com/ory/hydra-client-go/v2 v2.0.3 github.com/ory/jsonschema/v3 v3.0.7 @@ -88,7 +88,7 @@ require ( github.com/spf13/cobra v1.6.1 github.com/spf13/pflag v1.0.5 github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.2 github.com/tidwall/gjson v1.14.3 github.com/tidwall/sjson v1.2.5 github.com/urfave/negroni v1.0.0 diff --git a/go.sum b/go.sum index 356691654031..acd2028d3d9a 100644 --- a/go.sum +++ b/go.sum @@ -1097,8 +1097,8 @@ github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnz github.com/ory/go-acc v0.2.6/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw= github.com/ory/go-acc v0.2.9-0.20230103102148-6b1c9a70dbbe h1:rvu4obdvqR0fkSIJ8IfgzKOWwZ5kOT2UNfLq81Qk7rc= github.com/ory/go-acc v0.2.9-0.20230103102148-6b1c9a70dbbe/go.mod h1:z4n3u6as84LbV4YmgjHhnwtccQqzf4cZlSk9f1FhygI= -github.com/ory/graceful v0.1.3 h1:FaeXcHZh168WzS+bqruqWEw/HgXWLdNv2nJ+fbhxbhc= -github.com/ory/graceful v0.1.3/go.mod h1:4zFz687IAF7oNHHiB586U4iL+/4aV09o/PYLE34t2bA= +github.com/ory/graceful v0.1.4-0.20230301144740-e222150c51d0 h1:VMUeLRfQD14fOMvhpYZIIT4vtAqxYh+f3KnSqCeJ13o= +github.com/ory/graceful v0.1.4-0.20230301144740-e222150c51d0/go.mod h1:hg2iCy+LCWOXahBZ+NQa4dk8J2govyQD79rrqrgMyY8= github.com/ory/herodot v0.9.13 h1:cN/Z4eOkErl/9W7hDIDLb79IO/bfsH+8yscBjRpB4IU= github.com/ory/herodot v0.9.13/go.mod h1:IWDs9kSvFQqw/cQ8zi5ksyYvITiUU4dI7glUrhZcJYo= github.com/ory/hydra-client-go/v2 v2.0.3 h1:jIx968J9RBnjRuaQ21QMLCwZoa28FPvzYWAQ+88XVLw= @@ -1346,8 +1346,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= From 0f187f6c26af7aff5b46e8f2fbe377d26e3623ed Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 10:50:19 +0100 Subject: [PATCH 13/24] chore: bump dependencies --- go.mod | 16 +++++----------- go.sum | 21 +++++++++++++++------ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index b501a219b098..993859353455 100644 --- a/go.mod +++ b/go.mod @@ -3,21 +3,15 @@ module github.com/ory/kratos go 1.19 replace ( - github.com/bradleyjkemp/cupaloy/v2 => github.com/aeneasr/cupaloy/v2 v2.6.1-0.20210924214125-3dfdd01210a3 - github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.7.0 - github.com/gorilla/sessions => github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2 - github.com/knadh/koanf => github.com/aeneasr/koanf v0.14.1-0.20211230115640-aa3902b3267a - - github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.14.7-0.20210414154423-1157a4212dcb - github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1 + github.com/gorilla/sessions => github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2 // https://github.com/gorilla/sessions/pull/255 - github.com/ory/client-go => ./internal/client-go + github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.14.16 // Use the internal httpclient which can be generated in this codebase but mark it as the // official SDK, allowing for the Ory CLI to consume Ory Kratos' CLI commands. - gopkg.in/DataDog/dd-trace-go.v1 => gopkg.in/DataDog/dd-trace-go.v1 v1.27.1-0.20201005154917-54b73b3e126a + github.com/ory/client-go => ./internal/client-go ) require ( @@ -60,7 +54,7 @@ require ( github.com/jarcoal/httpmock v1.0.5 github.com/jteeuwen/go-bindata v3.0.7+incompatible github.com/julienschmidt/httprouter v1.3.0 - github.com/knadh/koanf v1.4.4 + github.com/knadh/koanf v1.5.0 github.com/laher/mergefs v0.1.2-0.20230223191438-d16611b2f4e7 github.com/luna-duclos/instrumentedsql v1.1.3 github.com/mattn/goveralls v0.0.7 @@ -231,7 +225,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.12 // indirect - github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect + github.com/mattn/go-sqlite3 v1.14.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/microcosm-cc/bluemonday v1.0.21 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect diff --git a/go.sum b/go.sum index acd2028d3d9a..44e918c94704 100644 --- a/go.sum +++ b/go.sum @@ -98,10 +98,6 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/a8m/envsubst v1.3.0 h1:GmXKmVssap0YtlU3E230W98RWtWCyIZzjtf1apWWyAg= github.com/a8m/envsubst v1.3.0/go.mod h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY= -github.com/aeneasr/cupaloy/v2 v2.6.1-0.20210924214125-3dfdd01210a3 h1:/SkiUr3JJzun9QN9cpUVCPri2ZwOFJ3ani+F3vdoCiY= -github.com/aeneasr/cupaloy/v2 v2.6.1-0.20210924214125-3dfdd01210a3/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= -github.com/aeneasr/koanf v0.14.1-0.20211230115640-aa3902b3267a h1:CWZu1palLlc1XlFcbEQ6i4Oqax3CJ8YEAb/mIdkPu5o= -github.com/aeneasr/koanf v0.14.1-0.20211230115640-aa3902b3267a/go.mod h1:1cfH5223ZeZUOs8FU2UdTmaNfHpqgtjV0+NHjRO43gs= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= @@ -181,6 +177,8 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= +github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/bwmarrin/discordgo v0.23.0 h1://ARp8qUrRZvDGMkfAjtcC20WOvsMtTgi+KrdKnl6eY= github.com/bwmarrin/discordgo v0.23.0/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M= github.com/bxcodec/faker/v3 v3.3.1 h1:G7uldFk+iO/ES7W4v7JlI/WU9FQ6op9VJ15YZlDEhGQ= @@ -685,10 +683,12 @@ github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69 h1:7xsUJsB2Nrdct github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69/go.mod h1:YLEMZOtU+AZ7dhN9T/IpGhXVGly2bvkJQ+zxj3WeVQo= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g= github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -745,15 +745,19 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hjson/hjson-go/v4 v4.0.0 h1:wlm6IYYqHjOdXH1gHev4VoXCaW20HdQAGCxdOEEg2cs= +github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= @@ -896,6 +900,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/kisom/goutils v1.4.3/go.mod h1:Lp5qrquG7yhYnWzZCI/68Pa/GpFynw//od6EkGnWpac= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs= +github.com/knadh/koanf v1.5.0/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -976,8 +982,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.14.7-0.20210414154423-1157a4212dcb h1:ax2vG2unlxsjwS7PMRo4FECIfAdQLowd6ejWYwPQhBo= -github.com/mattn/go-sqlite3 v1.14.7-0.20210414154423-1157a4212dcb/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/goveralls v0.0.7 h1:vzy0i4a2iDzEFMdXIxcanRadkr0FBvSBKUmj0P8SPlQ= github.com/mattn/goveralls v0.0.7/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKmLesRwqw= @@ -1443,14 +1449,17 @@ go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/api/v3 v3.5.6 h1:Cy2qx3npLcYqTKqGJzMypnMv2tiRyifZJ17BlWIWA7A= go.etcd.io/etcd/api/v3 v3.5.6/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.6 h1:TXQWYceBKqLp4sa87rcPs11SXxUA/mHwH975v+BDvLU= go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU= go.etcd.io/etcd/client/v2 v2.305.6 h1:fIDR0p4KMjw01MJMfUIDWdQbjo06PD6CeYM5z4EHLi0= go.etcd.io/etcd/client/v2 v2.305.6/go.mod h1:BHha8XJGe8vCIBfWBpbBLVZ4QjOIlfoouvOwydu63E0= go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.etcd.io/etcd/client/v3 v3.5.6 h1:coLs69PWCXE9G4FKquzNaSHrRyMCAXwF+IX1tAPVO8E= go.etcd.io/etcd/client/v3 v3.5.6/go.mod h1:f6GRinRMCsFVv9Ht42EyY7nfsVGwrNO0WEoS2pRKzQk= go.etcd.io/etcd/etcdctl/v3 v3.5.0-alpha.0 h1:odMFuQQCg0UmPd7Cyw6TViRYv9ybGuXuki4CusDSzqA= From b0151538126ff7ed16c4bfaed6dd7be241853f60 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 10:38:26 +0100 Subject: [PATCH 14/24] fix: consistently use otelx.End in IdentityPersister and inline private delete function --- .../sql/identity/persister_identity.go | 119 ++++++++---------- 1 file changed, 54 insertions(+), 65 deletions(-) diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index d7a413c6c849..c3c7e2020e2d 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -87,24 +87,24 @@ func (p *IdentityPersister) GetConnection(ctx context.Context) *pop.Connection { func (p *IdentityPersister) ListVerifiableAddresses(ctx context.Context, page, itemsPerPage int) (a []identity.VerifiableAddress, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.ListVerifiableAddresses") - defer span.End() + otelx.End(span, &err) if err := p.GetConnection(ctx).Where("nid = ?", p.NetworkID(ctx)).Order("id DESC").Paginate(page, x.MaxItemsPerPage(itemsPerPage)).All(&a); err != nil { return nil, sqlcon.HandleError(err) } - return a, err + return a, nil } func (p *IdentityPersister) ListRecoveryAddresses(ctx context.Context, page, itemsPerPage int) (a []identity.RecoveryAddress, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.ListRecoveryAddresses") - defer span.End() + otelx.End(span, &err) if err := p.GetConnection(ctx).Where("nid = ?", p.NetworkID(ctx)).Order("id DESC").Paginate(page, x.MaxItemsPerPage(itemsPerPage)).All(&a); err != nil { return nil, sqlcon.HandleError(err) } - return a, err + return a, nil } func stringToLowerTrim(match string) string { @@ -130,9 +130,9 @@ func NormalizeIdentifier(ct identity.CredentialsType, match string) string { return match } -func (p *IdentityPersister) FindByCredentialsIdentifier(ctx context.Context, ct identity.CredentialsType, match string) (*identity.Identity, *identity.Credentials, error) { +func (p *IdentityPersister) FindByCredentialsIdentifier(ctx context.Context, ct identity.CredentialsType, match string) (_ *identity.Identity, _ *identity.Credentials, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.FindByCredentialsIdentifier") - defer span.End() + otelx.End(span, &err) nid := p.NetworkID(ctx) @@ -181,9 +181,9 @@ func (p *IdentityPersister) FindByCredentialsIdentifier(ctx context.Context, ct return i.CopyWithoutCredentials(), creds, nil } -func (p *IdentityPersister) findIdentityCredentialsType(ctx context.Context, ct identity.CredentialsType) (*identity.CredentialsTypeTable, error) { +func (p *IdentityPersister) findIdentityCredentialsType(ctx context.Context, ct identity.CredentialsType) (_ *identity.CredentialsTypeTable, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.findIdentityCredentialsType") - defer span.End() + otelx.End(span, &err) var m identity.CredentialsTypeTable if err := p.GetConnection(ctx).Where("name = ?", ct).First(&m); err != nil { @@ -192,9 +192,9 @@ func (p *IdentityPersister) findIdentityCredentialsType(ctx context.Context, ct return &m, nil } -func (p *IdentityPersister) createIdentityCredentials(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) createIdentityCredentials(ctx context.Context, i *identity.Identity) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.createIdentityCredentials") - defer span.End() + otelx.End(span, &err) c := p.GetConnection(ctx) @@ -242,9 +242,9 @@ func (p *IdentityPersister) createIdentityCredentials(ctx context.Context, i *id return nil } -func (p *IdentityPersister) createVerifiableAddresses(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) createVerifiableAddresses(ctx context.Context, i *identity.Identity) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.createVerifiableAddresses") - defer span.End() + otelx.End(span, &err) for k := range i.VerifiableAddresses { if err := p.GetConnection(ctx).Create(&i.VerifiableAddresses[k]); err != nil { @@ -256,7 +256,10 @@ func (p *IdentityPersister) createVerifiableAddresses(ctx context.Context, i *id func updateAssociation[T interface { Hash() string -}](ctx context.Context, p *IdentityPersister, i *identity.Identity, inID []T) error { +}](ctx context.Context, p *IdentityPersister, i *identity.Identity, inID []T) (err error) { + ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.updateAssociation") + otelx.End(span, &err) + var inDB []T if err := p.GetConnection(ctx). Where("identity_id = ? AND nid = ?", i.ID, p.NetworkID(ctx)). @@ -337,9 +340,9 @@ func (p *IdentityPersister) normalizeRecoveryAddresses(ctx context.Context, id * } } -func (p *IdentityPersister) createRecoveryAddresses(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) createRecoveryAddresses(ctx context.Context, i *identity.Identity) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.createRecoveryAddresses") - defer span.End() + otelx.End(span, &err) for k := range i.RecoveryAddresses { if err := p.GetConnection(ctx).Create(&i.RecoveryAddresses[k]); err != nil { @@ -349,9 +352,9 @@ func (p *IdentityPersister) createRecoveryAddresses(ctx context.Context, i *iden return nil } -func (p *IdentityPersister) CountIdentities(ctx context.Context) (int64, error) { +func (p *IdentityPersister) CountIdentities(ctx context.Context) (n int64, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.CountIdentities") - defer span.End() + otelx.End(span, &err) count, err := p.c.WithContext(ctx).Where("nid = ?", p.NetworkID(ctx)).Count(new(identity.Identity)) if err != nil { @@ -360,9 +363,9 @@ func (p *IdentityPersister) CountIdentities(ctx context.Context) (int64, error) return int64(count), nil } -func (p *IdentityPersister) CreateIdentity(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) CreateIdentity(ctx context.Context, i *identity.Identity) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.CreateIdentity") - defer span.End() + otelx.End(span, &err) i.NID = p.NetworkID(ctx) @@ -485,6 +488,7 @@ func (p *IdentityPersister) HydrateIdentityAssociations(ctx context.Context, i * func (p *IdentityPersister) ListIdentities(ctx context.Context, params identity.ListIdentityParameters) (res []identity.Identity, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.ListIdentities") defer otelx.End(span, &err) + span.SetAttributes( attribute.Int("page", params.Page), attribute.Int("per_page", params.PerPage), @@ -542,9 +546,9 @@ func (p *IdentityPersister) ListIdentities(ctx context.Context, params identity. return is, nil } -func (p *IdentityPersister) UpdateIdentity(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) UpdateIdentity(ctx context.Context, i *identity.Identity) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.UpdateIdentity") - defer span.End() + defer otelx.End(span, &err) if err := p.validateIdentity(ctx, i); err != nil { return err @@ -584,11 +588,22 @@ func (p *IdentityPersister) UpdateIdentity(ctx context.Context, i *identity.Iden })) } -func (p *IdentityPersister) DeleteIdentity(ctx context.Context, id uuid.UUID) error { +func (p *IdentityPersister) DeleteIdentity(ctx context.Context, id uuid.UUID) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteIdentity") - defer span.End() + defer otelx.End(span, &err) - return p.delete(ctx, new(identity.Identity), id) + nid := p.NetworkID(ctx) + count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf("DELETE FROM %s WHERE id = ? AND nid = ?", new(identity.Identity).TableName(ctx)), + id, + nid, + ).ExecWithCount() + if err != nil { + return sqlcon.HandleError(err) + } + if count == 0 { + return errors.WithStack(sqlcon.ErrNoRows) + } + return nil } func (p *IdentityPersister) GetIdentity(ctx context.Context, id uuid.UUID, expand identity.Expandables) (_ *identity.Identity, err error) { @@ -620,9 +635,9 @@ func (p *IdentityPersister) GetIdentityConfidential(ctx context.Context, id uuid return p.GetIdentity(ctx, id, identity.ExpandEverything) } -func (p *IdentityPersister) FindVerifiableAddressByValue(ctx context.Context, via identity.VerifiableAddressType, value string) (*identity.VerifiableAddress, error) { +func (p *IdentityPersister) FindVerifiableAddressByValue(ctx context.Context, via identity.VerifiableAddressType, value string) (_ *identity.VerifiableAddress, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.FindVerifiableAddressByValue") - defer span.End() + otelx.End(span, &err) var address identity.VerifiableAddress if err := p.GetConnection(ctx).Where("nid = ? AND via = ? AND value = ?", p.NetworkID(ctx), via, stringToLowerTrim(value)).First(&address); err != nil { @@ -632,9 +647,9 @@ func (p *IdentityPersister) FindVerifiableAddressByValue(ctx context.Context, vi return &address, nil } -func (p *IdentityPersister) FindRecoveryAddressByValue(ctx context.Context, via identity.RecoveryAddressType, value string) (*identity.RecoveryAddress, error) { +func (p *IdentityPersister) FindRecoveryAddressByValue(ctx context.Context, via identity.RecoveryAddressType, value string) (_ *identity.RecoveryAddress, err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.FindRecoveryAddressByValue") - defer span.End() + defer otelx.End(span, &err) var address identity.RecoveryAddress if err := p.GetConnection(ctx).Where("nid = ? AND via = ? AND value = ?", p.NetworkID(ctx), via, stringToLowerTrim(value)).First(&address); err != nil { @@ -644,9 +659,10 @@ func (p *IdentityPersister) FindRecoveryAddressByValue(ctx context.Context, via return &address, nil } -func (p *IdentityPersister) VerifyAddress(ctx context.Context, code string) error { +func (p *IdentityPersister) VerifyAddress(ctx context.Context, code string) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.VerifyAddress") - defer span.End() + otelx.End(span, &err) + newCode, err := otp.New() if err != nil { return err @@ -676,18 +692,18 @@ func (p *IdentityPersister) VerifyAddress(ctx context.Context, code string) erro return nil } -func (p *IdentityPersister) UpdateVerifiableAddress(ctx context.Context, address *identity.VerifiableAddress) error { +func (p *IdentityPersister) UpdateVerifiableAddress(ctx context.Context, address *identity.VerifiableAddress) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.UpdateVerifiableAddress") - defer span.End() + otelx.End(span, &err) address.NID = p.NetworkID(ctx) address.Value = stringToLowerTrim(address.Value) return p.update(ctx, address) } -func (p *IdentityPersister) validateIdentity(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) validateIdentity(ctx context.Context, i *identity.Identity) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.validateIdentity") - defer span.End() + otelx.End(span, &err) if err := p.r.IdentityValidator().ValidateWithRunner(ctx, i); err != nil { if _, ok := errorsx.Cause(err).(*jsonschema.ValidationError); ok { @@ -699,9 +715,9 @@ func (p *IdentityPersister) validateIdentity(ctx context.Context, i *identity.Id return nil } -func (p *IdentityPersister) InjectTraitsSchemaURL(ctx context.Context, i *identity.Identity) error { +func (p *IdentityPersister) InjectTraitsSchemaURL(ctx context.Context, i *identity.Identity) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.InjectTraitsSchemaURL") - defer span.End() + otelx.End(span, &err) ss, err := p.r.IdentityTraitsSchemas(ctx) if err != nil { @@ -725,9 +741,9 @@ type node interface { GetNID() uuid.UUID } -func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...string) error { +func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...string) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.update") - defer span.End() + otelx.End(span, &err) c := p.GetConnection(ctx) quoter, ok := c.Dialect.(quotable) @@ -775,30 +791,3 @@ func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...s } return nil } - -func (p *IdentityPersister) delete(ctx context.Context, v interface{}, id uuid.UUID) error { - ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.delete") - defer span.End() - - nid := p.NetworkID(ctx) - - tabler, ok := v.(interface { - TableName(ctx context.Context) string - }) - if !ok { - return errors.Errorf("expected model to have TableName signature but got: %T", v) - } - - /* #nosec G201 TableName is static */ - count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf("DELETE FROM %s WHERE id = ? AND nid = ?", tabler.TableName(ctx)), - id, - nid, - ).ExecWithCount() - if err != nil { - return sqlcon.HandleError(err) - } - if count == 0 { - return errors.WithStack(sqlcon.ErrNoRows) - } - return nil -} From 58d6461c74899a1efb7bc1a600a15b4e76888544 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 11:11:34 +0100 Subject: [PATCH 15/24] Inline private (*Persister).delete function into persister_session.go --- persistence/sql/persister.go | 27 --------------------------- persistence/sql/persister_session.go | 14 +++++++++++++- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index 58dba8c51ced..3b38d102af57 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -259,30 +259,3 @@ func (p *Persister) update(ctx context.Context, v node, columnNames ...string) e } return nil } - -func (p *Persister) delete(ctx context.Context, v interface{}, id uuid.UUID) error { - ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.delete") - defer span.End() - - nid := p.NetworkID(ctx) - - tabler, ok := v.(interface { - TableName(ctx context.Context) string - }) - if !ok { - return errors.Errorf("expected model to have TableName signature but got: %T", v) - } - - /* #nosec G201 TableName is static */ - count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf("DELETE FROM %s WHERE id = ? AND nid = ?", tabler.TableName(ctx)), - id, - nid, - ).ExecWithCount() - if err != nil { - return sqlcon.HandleError(err) - } - if count == 0 { - return errors.WithStack(sqlcon.ErrNoRows) - } - return nil -} diff --git a/persistence/sql/persister_session.go b/persistence/sql/persister_session.go index 7377d1435983..dc4243bef4b5 100644 --- a/persistence/sql/persister_session.go +++ b/persistence/sql/persister_session.go @@ -217,7 +217,19 @@ func (p *Persister) DeleteSession(ctx context.Context, sid uuid.UUID) (err error ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteSession") defer otelx.End(span, &err) - return p.delete(ctx, new(session.Session), sid) + nid := p.NetworkID(ctx) + //#nosec G201 -- TableName is static + count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf("DELETE FROM %s WHERE id = ? AND nid = ?", new(session.Session).TableName(ctx)), + sid, + nid, + ).ExecWithCount() + if err != nil { + return sqlcon.HandleError(err) + } + if count == 0 { + return errors.WithStack(sqlcon.ErrNoRows) + } + return nil } func (p *Persister) DeleteSessionsByIdentity(ctx context.Context, identityID uuid.UUID) (err error) { From 476f5d9aeda4fd32fc9933ba501c3b0023dd19a9 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 11:12:16 +0100 Subject: [PATCH 16/24] chore: update #nosec lint directives https://github.com/securego/gosec#annotating-code --- cmd/courier/watch.go | 2 +- cmd/daemon/serve.go | 4 +-- cmd/hashers/argon2/loadtest.go | 2 +- cmd/jsonnet/format.go | 2 +- courier/smtp.go | 4 +-- hash/hash_comparator.go | 8 ++--- hash/hasher_pbkdf2.go | 2 +- internal/testhelpers/e2e_server.go | 2 +- internal/testhelpers/selfservice_settings.go | 2 +- .../sql/identity/persister_identity.go | 10 +++---- persistence/sql/persister.go | 4 +-- persistence/sql/persister_continuity.go | 4 +-- persistence/sql/persister_errorx.go | 6 ++-- persistence/sql/persister_login.go | 2 +- persistence/sql/persister_recovery.go | 14 ++++----- persistence/sql/persister_registration.go | 2 +- persistence/sql/persister_session.go | 30 ++++++++++--------- persistence/sql/persister_settings.go | 2 +- persistence/sql/persister_verification.go | 14 ++++----- .../strategy/oidc/strategy_helper_test.go | 2 +- selfservice/strategy/password/validator.go | 5 ++-- .../strategy/password/validator_test.go | 4 +-- test/e2e/hydra-login-consent/main.go | 2 +- x/time.go | 3 +- 24 files changed, 66 insertions(+), 66 deletions(-) diff --git a/cmd/courier/watch.go b/cmd/courier/watch.go index b32bc4b3b280..3a159dbfc5c4 100644 --- a/cmd/courier/watch.go +++ b/cmd/courier/watch.go @@ -73,7 +73,7 @@ func ServeMetrics(ctx context.Context, r driver.Registry) error { handler = otelx.NewHandler(handler, "cmd.courier.ServeMetrics", otelhttp.WithTracerProvider(tp)) } - // #nosec G112 - the correct settings are set by graceful.WithDefaults + //#nosec G112 -- the correct settings are set by graceful.WithDefaults server := graceful.WithDefaults(&http.Server{ Addr: c.MetricsListenOn(ctx), Handler: handler, diff --git a/cmd/daemon/serve.go b/cmd/daemon/serve.go index c0689921537f..f2c036bef9f7 100644 --- a/cmd/daemon/serve.go +++ b/cmd/daemon/serve.go @@ -120,7 +120,7 @@ func ServePublic(r driver.Registry, cmd *cobra.Command, args []string, slOpts *s handler = otelx.TraceHandler(handler, otelhttp.WithTracerProvider(tracer.Provider())) } - // #nosec G112 - the correct settings are set by graceful.WithDefaults + //#nosec G112 -- the correct settings are set by graceful.WithDefaults server := graceful.WithDefaults(&http.Server{ Handler: handler, TLSConfig: &tls.Config{GetCertificate: certs, MinVersion: tls.VersionTLS12}, @@ -191,7 +191,7 @@ func ServeAdmin(r driver.Registry, cmd *cobra.Command, args []string, slOpts *se ) } - // #nosec G112 - the correct settings are set by graceful.WithDefaults + //#nosec G112 -- the correct settings are set by graceful.WithDefaults server := graceful.WithDefaults(&http.Server{ Handler: handler, TLSConfig: &tls.Config{GetCertificate: certs, MinVersion: tls.VersionTLS12}, diff --git a/cmd/hashers/argon2/loadtest.go b/cmd/hashers/argon2/loadtest.go index 547d054b3f85..e1e3715bef42 100644 --- a/cmd/hashers/argon2/loadtest.go +++ b/cmd/hashers/argon2/loadtest.go @@ -188,7 +188,7 @@ func runLoadTest(cmd *cobra.Command, conf *argon2Config, reqPerMin int) (*result eg.Go(func(i int) func() error { return func() error { // wait randomly before starting, max. sample time - // #nosec G404 - just a timeout to collect statistical data + //#nosec G404 -- just a timeout to collect statistical data t := time.Duration(rand.Intn(int(sampleTime))) timer := time.NewTimer(t) defer timer.Stop() diff --git a/cmd/jsonnet/format.go b/cmd/jsonnet/format.go index ec45f1b3a17e..461654ef3dd1 100644 --- a/cmd/jsonnet/format.go +++ b/cmd/jsonnet/format.go @@ -47,7 +47,7 @@ Use -w or --write to write output back to files instead of stdout. cmdx.Must(err, `JSONNet file "%s" could not be formatted: %s`, file, err) if shouldWrite { - err := os.WriteFile(file, []byte(output), 0644) // #nosec + err := os.WriteFile(file, []byte(output), 0644) //#nosec cmdx.Must(err, `Could not write to file "%s" because: %s`, file, err) } else { fmt.Println(output) diff --git a/courier/smtp.go b/courier/smtp.go index 4cb40afd1c92..45908b861905 100644 --- a/courier/smtp.go +++ b/courier/smtp.go @@ -82,13 +82,13 @@ func newSMTP(ctx context.Context, deps Dependencies) (*smtpClient, error) { // Enforcing StartTLS by default for security best practices (config review, etc.) skipStartTLS, _ := strconv.ParseBool(uri.Query().Get("disable_starttls")) if !skipStartTLS { - // #nosec G402 This is ok (and required!) because it is configurable and disabled by default. + //#nosec G402 -- This is ok (and required!) because it is configurable and disabled by default. dialer.TLSConfig = &tls.Config{InsecureSkipVerify: sslSkipVerify, Certificates: tlsCertificates, ServerName: serverName} // Enforcing StartTLS dialer.StartTLSPolicy = gomail.MandatoryStartTLS } case "smtps": - // #nosec G402 This is ok (and required!) because it is configurable and disabled by default. + //#nosec G402 -- This is ok (and required!) because it is configurable and disabled by default. dialer.TLSConfig = &tls.Config{InsecureSkipVerify: sslSkipVerify, Certificates: tlsCertificates, ServerName: serverName} dialer.SSL = true } diff --git a/hash/hash_comparator.go b/hash/hash_comparator.go index 84bfdb1d68ac..f3169f6f5ea3 100644 --- a/hash/hash_comparator.go +++ b/hash/hash_comparator.go @@ -7,8 +7,8 @@ import ( "context" "crypto/aes" "crypto/cipher" - "crypto/md5" // #nosec G501 - "crypto/sha1" // #nosec G505 - compatibility for imported passwords + "crypto/md5" //#nosec G501 -- compatibility for imported passwords + "crypto/sha1" //#nosec G505 -- compatibility for imported passwords "crypto/sha256" "crypto/sha512" "crypto/subtle" @@ -220,7 +220,7 @@ func CompareMD5(_ context.Context, password []byte, hash []byte) error { r := strings.NewReplacer("{SALT}", string(salt), "{PASSWORD}", string(password)) arg = []byte(r.Replace(string(pf))) } - // #nosec G401 + //#nosec G401 -- compatibility for imported passwords otherHash := md5.Sum(arg) // Check that the contents of the hashed passwords are identical. Note @@ -412,7 +412,7 @@ func compareSHAHelper(hasher string, raw []byte, hash []byte) error { switch hasher { case "sha1": - sum := sha1.Sum(raw) // #nosec G401 - compatibility for imported passwords + sum := sha1.Sum(raw) //#nosec G401 -- compatibility for imported passwords sha = sum[:] case "sha256": sum := sha256.Sum256(raw) diff --git a/hash/hasher_pbkdf2.go b/hash/hasher_pbkdf2.go index 828b41d33176..38c26bba6e06 100644 --- a/hash/hasher_pbkdf2.go +++ b/hash/hasher_pbkdf2.go @@ -7,7 +7,7 @@ import ( "bytes" "context" "crypto/rand" - "crypto/sha1" // #nosec G505 - compatibility for imported passwords + "crypto/sha1" //#nosec G505 -- compatibility for imported passwords "crypto/sha256" "crypto/sha512" "encoding/base64" diff --git a/internal/testhelpers/e2e_server.go b/internal/testhelpers/e2e_server.go index 7c41f76fceba..0eebca91f726 100644 --- a/internal/testhelpers/e2e_server.go +++ b/internal/testhelpers/e2e_server.go @@ -148,7 +148,7 @@ func CheckE2EServerOnHTTP(t *testing.T, publicPort, adminPort int) (publicUrl, a func waitToComeAlive(t *testing.T, publicUrl, adminUrl string) { require.NoError(t, retry.Do(func() error { - /* #nosec G402: TLS InsecureSkipVerify set true. */ + //#nosec G402 -- TLS InsecureSkipVerify set true tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} client := &http.Client{Transport: tr} diff --git a/internal/testhelpers/selfservice_settings.go b/internal/testhelpers/selfservice_settings.go index 25e7b7087eb7..aea2a8b8b3db 100644 --- a/internal/testhelpers/selfservice_settings.go +++ b/internal/testhelpers/selfservice_settings.go @@ -197,7 +197,7 @@ func NewSettingsAPIServer(t *testing.T, reg *driver.RegistryDefault, ids map[str reg.Config().MustSet(ctx, config.ViperKeyPublicBaseURL, tsp.URL) reg.Config().MustSet(ctx, config.ViperKeyAdminBaseURL, tsa.URL) - // #nosec G112 + //#nosec G112 return tsp, tsa, AddAndLoginIdentities(t, reg, &httptest.Server{Config: &http.Server{Handler: public}, URL: tsp.URL}, ids) } diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index c3c7e2020e2d..3dc0f214a90f 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -522,7 +522,7 @@ func (p *IdentityPersister) ListIdentities(ctx context.Context, params identity. query = query.Paginate(params.Page, params.PerPage) } - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static if err := sqlcon.HandleError(query.All(&is)); err != nil { return nil, err } @@ -570,7 +570,7 @@ func (p *IdentityPersister) UpdateIdentity(ctx context.Context, i *identity.Iden return err } - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static if err := tx.RawQuery( fmt.Sprintf( `DELETE FROM %s WHERE identity_id = ? AND nid = ?`, @@ -669,7 +669,7 @@ func (p *IdentityPersister) VerifyAddress(ctx context.Context, code string) (err } count, err := p.GetConnection(ctx).RawQuery( - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static fmt.Sprintf( "UPDATE %s SET status = ?, verified = true, verified_at = ?, code = ? WHERE nid = ? AND code = ? AND expires_at > ?", new(identity.VerifiableAddress).TableName(ctx), @@ -762,7 +762,7 @@ func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...s cols = columns.ForStructWithAlias(v, tn, model.As, model.IDField()) } - // #nosec + //#nosec stmt := fmt.Sprintf("SELECT COUNT(id) FROM %s AS %s WHERE %s.id = ? AND %s.nid = ?", quoter.Quote(model.TableName()), model.Alias(), @@ -777,7 +777,7 @@ func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...s return errors.WithStack(sqlcon.ErrNoRows) } - // #nosec + //#nosec stmt = fmt.Sprintf("UPDATE %s AS %s SET %s WHERE %s AND %s.nid = :nid", quoter.Quote(model.TableName()), model.Alias(), diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index 3b38d102af57..87412fcade88 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -230,7 +230,7 @@ func (p *Persister) update(ctx context.Context, v node, columnNames ...string) e cols = columns.ForStructWithAlias(v, tn, model.As, model.IDField()) } - // #nosec + //#nosec stmt := fmt.Sprintf("SELECT COUNT(id) FROM %s AS %s WHERE %s.id = ? AND %s.nid = ?", quoter.Quote(model.TableName()), model.Alias(), @@ -245,7 +245,7 @@ func (p *Persister) update(ctx context.Context, v node, columnNames ...string) e return errors.WithStack(sqlcon.ErrNoRows) } - // #nosec + //#nosec stmt = fmt.Sprintf("UPDATE %s AS %s SET %s WHERE %s AND %s.nid = :nid", quoter.Quote(model.TableName()), model.Alias(), diff --git a/persistence/sql/persister_continuity.go b/persistence/sql/persister_continuity.go index da722bebfaaa..c57d64a8462c 100644 --- a/persistence/sql/persister_continuity.go +++ b/persistence/sql/persister_continuity.go @@ -43,7 +43,7 @@ func (p *Persister) DeleteContinuitySession(ctx context.Context, id uuid.UUID) e defer span.End() if count, err := p.GetConnection(ctx).RawQuery( - // #nosec + //#nosec fmt.Sprintf("DELETE FROM %s WHERE id=? AND nid=?", new(continuity.Container).TableName(ctx)), id, p.NetworkID(ctx)).ExecWithCount(); err != nil { return sqlcon.HandleError(err) @@ -54,7 +54,7 @@ func (p *Persister) DeleteContinuitySession(ctx context.Context, id uuid.UUID) e } func (p *Persister) DeleteExpiredContinuitySessions(ctx context.Context, expiresAt time.Time, limit int) error { - // #nosec G201 + //#nosec G201 err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(continuity.Container).TableName(ctx), diff --git a/persistence/sql/persister_errorx.go b/persistence/sql/persister_errorx.go index d75c6f573b60..623583e199a8 100644 --- a/persistence/sql/persister_errorx.go +++ b/persistence/sql/persister_errorx.go @@ -56,7 +56,7 @@ func (p *Persister) Read(ctx context.Context, id uuid.UUID) (*errorx.ErrorContai return nil, sqlcon.HandleError(err) } - // #nosec G201 + //#nosec G201 if err := p.GetConnection(ctx).RawQuery( fmt.Sprintf("UPDATE %s SET was_seen = true, seen_at = ? WHERE id = ? AND nid = ?", "selfservice_errors"), time.Now().UTC(), id, p.NetworkID(ctx)).Exec(); err != nil { @@ -71,12 +71,12 @@ func (p *Persister) Clear(ctx context.Context, olderThan time.Duration, force bo defer span.End() if force { - // #nosec G201 + //#nosec G201 err = p.GetConnection(ctx).RawQuery( fmt.Sprintf("DELETE FROM %s WHERE nid = ? AND seen_at < ? AND seen_at IS NOT NULL", "selfservice_errors"), p.NetworkID(ctx), time.Now().UTC().Add(-olderThan)).Exec() } else { - // #nosec G201 + //#nosec G201 err = p.GetConnection(ctx).RawQuery( fmt.Sprintf("DELETE FROM %s WHERE nid = ? AND was_seen=true AND seen_at < ? AND seen_at IS NOT NULL", "selfservice_errors"), p.NetworkID(ctx), time.Now().UTC().Add(-olderThan)).Exec() diff --git a/persistence/sql/persister_login.go b/persistence/sql/persister_login.go index 584b18fc390e..23c7e54c01b9 100644 --- a/persistence/sql/persister_login.go +++ b/persistence/sql/persister_login.go @@ -68,7 +68,7 @@ func (p *Persister) ForceLoginFlow(ctx context.Context, id uuid.UUID) error { } func (p *Persister) DeleteExpiredLoginFlows(ctx context.Context, expiresAt time.Time, limit int) error { - // #nosec G201 + //#nosec G201 err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(login.Flow).TableName(ctx), diff --git a/persistence/sql/persister_recovery.go b/persistence/sql/persister_recovery.go index af9fca615e0c..f783d1f72293 100644 --- a/persistence/sql/persister_recovery.go +++ b/persistence/sql/persister_recovery.go @@ -101,7 +101,7 @@ func (p *Persister) UseRecoveryToken(ctx context.Context, fID uuid.UUID, token s } rt.RecoveryAddress = &ra - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static return tx.RawQuery(fmt.Sprintf("UPDATE %s SET used=true, used_at=? WHERE id=? AND nid = ?", rt.TableName(ctx)), time.Now().UTC(), rt.ID, nid).Exec() })); err != nil { return nil, err @@ -114,12 +114,12 @@ func (p *Persister) DeleteRecoveryToken(ctx context.Context, token string) error ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteRecoveryToken") defer span.End() - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static return p.GetConnection(ctx).RawQuery(fmt.Sprintf("DELETE FROM %s WHERE token=? AND nid = ?", new(link.RecoveryToken).TableName(ctx)), token, p.NetworkID(ctx)).Exec() } func (p *Persister) DeleteExpiredRecoveryFlows(ctx context.Context, expiresAt time.Time, limit int) error { - // #nosec G201 + //#nosec G201 err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(recovery.Flow).TableName(ctx), @@ -186,14 +186,14 @@ func (p *Persister) UseRecoveryCode(ctx context.Context, fID uuid.UUID, codeVal if err := sqlcon.HandleError(p.Transaction(ctx, func(ctx context.Context, tx *pop.Connection) (err error) { - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static if err := sqlcon.HandleError(tx.RawQuery(fmt.Sprintf("UPDATE %s SET submit_count = submit_count + 1 WHERE id = ? AND nid = ?", flowTableName), fID, nid).Exec()); err != nil { return err } var submitCount int // Because MySQL does not support "RETURNING" clauses, but we need the updated `submit_count` later on. - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static if err := sqlcon.HandleError(tx.RawQuery(fmt.Sprintf("SELECT submit_count FROM %s WHERE id = ? AND nid = ?", flowTableName), fID, nid).First(&submitCount)); err != nil { if errors.Is(err, sqlcon.ErrNoRows) { // Return no error, as that would roll back the transaction @@ -248,7 +248,7 @@ func (p *Persister) UseRecoveryCode(ctx context.Context, fID uuid.UUID, codeVal } recoveryCode.RecoveryAddress = &ra - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static return sqlcon.HandleError(tx.RawQuery(fmt.Sprintf("UPDATE %s SET used_at = ? WHERE id = ? AND nid = ?", recoveryCode.TableName(ctx)), time.Now().UTC(), recoveryCode.ID, nid).Exec()) })); err != nil { return nil, err @@ -273,6 +273,6 @@ func (p *Persister) DeleteRecoveryCodesOfFlow(ctx context.Context, fID uuid.UUID ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteRecoveryCodesOfFlow") defer span.End() - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static return p.GetConnection(ctx).RawQuery(fmt.Sprintf("DELETE FROM %s WHERE selfservice_recovery_flow_id = ? AND nid = ?", new(code.RecoveryCode).TableName(ctx)), fID, p.NetworkID(ctx)).Exec() } diff --git a/persistence/sql/persister_registration.go b/persistence/sql/persister_registration.go index 42f3508132d8..fbd04759f0be 100644 --- a/persistence/sql/persister_registration.go +++ b/persistence/sql/persister_registration.go @@ -48,7 +48,7 @@ func (p *Persister) GetRegistrationFlow(ctx context.Context, id uuid.UUID) (*reg } func (p *Persister) DeleteExpiredRegistrationFlows(ctx context.Context, expiresAt time.Time, limit int) error { - // #nosec G201 + //#nosec G201 err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(registration.Flow).TableName(ctx), diff --git a/persistence/sql/persister_session.go b/persistence/sql/persister_session.go index dc4243bef4b5..080a807cc9f9 100644 --- a/persistence/sql/persister_session.go +++ b/persistence/sql/persister_session.go @@ -236,10 +236,10 @@ func (p *Persister) DeleteSessionsByIdentity(ctx context.Context, identityID uui ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteSessionsByIdentity") defer otelx.End(span, &err) - // #nosec G201 + //#nosec G201 -- TableName is static count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE identity_id = ? AND nid = ?", - "sessions", + new(session.Session).TableName(ctx), ), identityID, p.NetworkID(ctx), @@ -302,10 +302,10 @@ func (p *Persister) DeleteSessionByToken(ctx context.Context, token string) (err ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteSessionByToken") defer otelx.End(span, &err) - // #nosec G201 + //#nosec G201 -- TableName is static count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE token = ? AND nid = ?", - "sessions", + new(session.Session).TableName(ctx), ), token, p.NetworkID(ctx), @@ -323,10 +323,10 @@ func (p *Persister) RevokeSessionByToken(ctx context.Context, token string) (err ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.RevokeSessionByToken") defer otelx.End(span, &err) - // #nosec G201 + //#nosec G201 -- TableName is static count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "UPDATE %s SET active = false WHERE token = ? AND nid = ?", - "sessions", + new(session.Session).TableName(ctx), ), token, p.NetworkID(ctx), @@ -345,10 +345,10 @@ func (p *Persister) RevokeSessionById(ctx context.Context, sID uuid.UUID) (err e ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.RevokeSessionById") defer otelx.End(span, &err) - // #nosec G201 + //#nosec G201 -- TableName is static count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "UPDATE %s SET active = false WHERE id = ? AND nid = ?", - "sessions", + new(session.Session).TableName(ctx), ), sID, p.NetworkID(ctx), @@ -368,10 +368,10 @@ func (p *Persister) RevokeSession(ctx context.Context, iID, sID uuid.UUID) (err ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.RevokeSession") defer otelx.End(span, &err) - // #nosec G201 + //#nosec G201 -- TableName is static err = p.GetConnection(ctx).RawQuery(fmt.Sprintf( "UPDATE %s SET active = false WHERE id = ? AND identity_id = ? AND nid = ?", - "sessions", + new(session.Session).TableName(ctx), ), sID, iID, @@ -388,10 +388,10 @@ func (p *Persister) RevokeSessionsIdentityExcept(ctx context.Context, iID, sID u ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.RevokeSessionsIdentityExcept") defer otelx.End(span, &err) - // #nosec G201 + //#nosec G201 -- TableName is static count, err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "UPDATE %s SET active = false WHERE identity_id = ? AND id != ? AND nid = ?", - "sessions", + new(session.Session).TableName(ctx), ), iID, sID, @@ -406,10 +406,12 @@ func (p *Persister) RevokeSessionsIdentityExcept(ctx context.Context, iID, sID u func (p *Persister) DeleteExpiredSessions(ctx context.Context, expiresAt time.Time, limit int) (err error) { ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteExpiredSessions") defer otelx.End(span, &err) + + //#nosec G201 -- TableName is static err = p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", - "sessions", - "sessions", + new(session.Session).TableName(ctx), + new(session.Session).TableName(ctx), limit, ), expiresAt, diff --git a/persistence/sql/persister_settings.go b/persistence/sql/persister_settings.go index c75be85c6d9e..7218720efb1d 100644 --- a/persistence/sql/persister_settings.go +++ b/persistence/sql/persister_settings.go @@ -58,7 +58,7 @@ func (p *Persister) UpdateSettingsFlow(ctx context.Context, r *settings.Flow) er } func (p *Persister) DeleteExpiredSettingsFlows(ctx context.Context, expiresAt time.Time, limit int) error { - // #nosec G201 + //#nosec G201 err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(settings.Flow).TableName(ctx), diff --git a/persistence/sql/persister_verification.go b/persistence/sql/persister_verification.go index d6a886186a82..2305c184c124 100644 --- a/persistence/sql/persister_verification.go +++ b/persistence/sql/persister_verification.go @@ -101,7 +101,7 @@ func (p *Persister) UseVerificationToken(ctx context.Context, fID uuid.UUID, tok rt.VerifiableAddress = &va - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static return tx.RawQuery(fmt.Sprintf("UPDATE %s SET used=true, used_at=? WHERE id=? AND nid = ?", rt.TableName(ctx)), time.Now().UTC(), rt.ID, nid).Exec() })); err != nil { return nil, err @@ -115,12 +115,12 @@ func (p *Persister) DeleteVerificationToken(ctx context.Context, token string) e defer span.End() nid := p.NetworkID(ctx) - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static return p.GetConnection(ctx).RawQuery(fmt.Sprintf("DELETE FROM %s WHERE token=? AND nid = ?", new(link.VerificationToken).TableName(ctx)), token, nid).Exec() } func (p *Persister) DeleteExpiredVerificationFlows(ctx context.Context, expiresAt time.Time, limit int) error { - // #nosec G201 + //#nosec G201 err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(verification.Flow).TableName(ctx), @@ -149,7 +149,7 @@ func (p *Persister) UseVerificationCode(ctx context.Context, fID uuid.UUID, code if err := sqlcon.HandleError( tx.RawQuery( - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static fmt.Sprintf("UPDATE %s SET submit_count = submit_count + 1 WHERE id = ? AND nid = ?", flowTableName), fID, nid, @@ -162,7 +162,7 @@ func (p *Persister) UseVerificationCode(ctx context.Context, fID uuid.UUID, code // Because MySQL does not support "RETURNING" clauses, but we need the updated `submit_count` later on. if err := sqlcon.HandleError( tx.RawQuery( - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static fmt.Sprintf("SELECT submit_count FROM %s WHERE id = ? AND nid = ?", flowTableName), fID, nid, @@ -222,7 +222,7 @@ func (p *Persister) UseVerificationCode(ctx context.Context, fID uuid.UUID, code verificationCode.VerifiableAddress = &va - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static return tx. RawQuery( fmt.Sprintf("UPDATE %s SET used_at = ? WHERE id = ? AND nid = ?", verificationCode.TableName(ctx)), @@ -276,7 +276,7 @@ func (p *Persister) DeleteVerificationCodesOfFlow(ctx context.Context, fID uuid. ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.DeleteVerificationCodesOfFlow") defer span.End() - /* #nosec G201 TableName is static */ + //#nosec G201 -- TableName is static return p.GetConnection(ctx). RawQuery( fmt.Sprintf("DELETE FROM %s WHERE selfservice_verification_flow_id = ? AND nid = ?", new(code.VerificationCode).TableName(ctx)), diff --git a/selfservice/strategy/oidc/strategy_helper_test.go b/selfservice/strategy/oidc/strategy_helper_test.go index ff6ad8fc2841..16089bed8599 100644 --- a/selfservice/strategy/oidc/strategy_helper_test.go +++ b/selfservice/strategy/oidc/strategy_helper_test.go @@ -176,7 +176,7 @@ func newHydraIntegration(t *testing.T, remote *string, subject *string, claims * parsed, err := url.ParseRequestURI(addr) require.NoError(t, err) - // #nosec G112 + //#nosec G112 server := &http.Server{Addr: ":" + parsed.Port(), Handler: router} go func(t *testing.T) { if err := server.ListenAndServe(); err != http.ErrServerClosed { diff --git a/selfservice/strategy/password/validator.go b/selfservice/strategy/password/validator.go index bd3d1fc0fe25..1d4d5d00c607 100644 --- a/selfservice/strategy/password/validator.go +++ b/selfservice/strategy/password/validator.go @@ -10,8 +10,7 @@ import ( "github.com/hashicorp/go-retryablehttp" - /* #nosec G505 sha1 is used for k-anonymity */ - "crypto/sha1" + "crypto/sha1" //#nosec G505 sha1 is used for k-anonymity "fmt" "net/http" "strconv" @@ -188,7 +187,7 @@ func (s *DefaultPasswordValidator) validate(ctx context.Context, identifier, pas return nil } - /* #nosec G401 sha1 is used for k-anonymity */ + //#nosec G401 -- sha1 is used for k-anonymity h := sha1.New() if _, err := h.Write([]byte(password)); err != nil { return err diff --git a/selfservice/strategy/password/validator_test.go b/selfservice/strategy/password/validator_test.go index 49f2a9d38776..af64cdd2ceda 100644 --- a/selfservice/strategy/password/validator_test.go +++ b/selfservice/strategy/password/validator_test.go @@ -7,7 +7,7 @@ import ( "bytes" "context" "crypto/rand" - "crypto/sha1" // #nosec G505 - compatibility for imported passwords + "crypto/sha1" //#nosec G505 - compatibility for imported passwords "errors" "fmt" "io" @@ -144,7 +144,7 @@ func TestDefaultPasswordValidationStrategy(t *testing.T) { s.Client = httpx.NewResilientClient(httpx.ResilientClientWithClient(&fakeClient.Client), httpx.ResilientClientWithMaxRetry(1), httpx.ResilientClientWithConnectionTimeout(time.Millisecond)) var hashPw = func(t *testing.T, pw string) string { - /* #nosec G401 sha1 is used for k-anonymity */ + //#nosec G401 -- sha1 is used for k-anonymity h := sha1.New() _, err := h.Write([]byte(pw)) require.NoError(t, err) diff --git a/test/e2e/hydra-login-consent/main.go b/test/e2e/hydra-login-consent/main.go index 56fb2012f7e1..eb86399cc023 100644 --- a/test/e2e/hydra-login-consent/main.go +++ b/test/e2e/hydra-login-consent/main.go @@ -176,7 +176,7 @@ func main() { }) addr := ":" + osx.GetenvDefault("PORT", "4446") - // #nosec G112 + //#nosec G112 server := &http.Server{Addr: addr, Handler: router} fmt.Printf("Starting web server at %s\n", addr) check(server.ListenAndServe()) diff --git a/x/time.go b/x/time.go index 17c6f4311b79..4457e0347afd 100644 --- a/x/time.go +++ b/x/time.go @@ -13,8 +13,7 @@ import ( "github.com/stretchr/testify/require" ) -// #nosec G404 -var rnd = rand.New(rand.NewSource(time.Now().Unix())) +var rnd = rand.New(rand.NewSource(time.Now().Unix())) //#nosec G404 func AssertEqualTime(t *testing.T, expected, actual time.Time) { assert.EqualValues(t, expected.UTC().Round(time.Second), actual.UTC().Round(time.Second)) From bf12ceb0bc416435e6405a9a4e11814fed2a3ec4 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 11:14:42 +0100 Subject: [PATCH 17/24] fix: lint --- internal/registrationhelpers/helpers.go | 2 +- persistence/sql/identity/persister_identity.go | 5 ++--- persistence/sql/persister.go | 4 ++-- persistence/sql/persister_continuity.go | 4 ++-- persistence/sql/persister_errorx.go | 10 +++------- persistence/sql/persister_login.go | 2 +- persistence/sql/persister_recovery.go | 2 +- persistence/sql/persister_registration.go | 2 +- persistence/sql/persister_settings.go | 2 +- persistence/sql/persister_verification.go | 2 +- selfservice/strategy/password/registration_test.go | 3 +-- selfservice/strategy/password/validator.go | 2 +- selfservice/strategy/password/validator_test.go | 2 +- selfservice/strategy/webauthn/registration_test.go | 3 +-- 14 files changed, 19 insertions(+), 26 deletions(-) diff --git a/internal/registrationhelpers/helpers.go b/internal/registrationhelpers/helpers.go index 5b84b57340c1..e9dbe7598797 100644 --- a/internal/registrationhelpers/helpers.go +++ b/internal/registrationhelpers/helpers.go @@ -275,7 +275,7 @@ func AssertRegistrationRespectsValidation(t *testing.T, reg *driver.RegistryDefa }) } -func AssertCommonErrorCases(t *testing.T, reg *driver.RegistryDefault, flows []string) { +func AssertCommonErrorCases(t *testing.T, flows []string) { ctx := context.Background() conf, reg := internal.NewFastRegistryWithMocks(t) testhelpers.SetDefaultIdentitySchemaFromRaw(conf, basicSchema) diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index 3dc0f214a90f..c696be362139 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -522,7 +522,6 @@ func (p *IdentityPersister) ListIdentities(ctx context.Context, params identity. query = query.Paginate(params.Page, params.PerPage) } - //#nosec G201 -- TableName is static if err := sqlcon.HandleError(query.All(&is)); err != nil { return nil, err } @@ -762,7 +761,7 @@ func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...s cols = columns.ForStructWithAlias(v, tn, model.As, model.IDField()) } - //#nosec + //#nosec G201 -- TableName is static stmt := fmt.Sprintf("SELECT COUNT(id) FROM %s AS %s WHERE %s.id = ? AND %s.nid = ?", quoter.Quote(model.TableName()), model.Alias(), @@ -777,7 +776,7 @@ func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...s return errors.WithStack(sqlcon.ErrNoRows) } - //#nosec + //#nosec G201 -- TableName is static stmt = fmt.Sprintf("UPDATE %s AS %s SET %s WHERE %s AND %s.nid = :nid", quoter.Quote(model.TableName()), model.Alias(), diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index 87412fcade88..c202d3fd4fd8 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -230,7 +230,7 @@ func (p *Persister) update(ctx context.Context, v node, columnNames ...string) e cols = columns.ForStructWithAlias(v, tn, model.As, model.IDField()) } - //#nosec + //#nosec G201 -- TableName is static stmt := fmt.Sprintf("SELECT COUNT(id) FROM %s AS %s WHERE %s.id = ? AND %s.nid = ?", quoter.Quote(model.TableName()), model.Alias(), @@ -245,7 +245,7 @@ func (p *Persister) update(ctx context.Context, v node, columnNames ...string) e return errors.WithStack(sqlcon.ErrNoRows) } - //#nosec + //#nosec G201 -- TableName is static stmt = fmt.Sprintf("UPDATE %s AS %s SET %s WHERE %s AND %s.nid = :nid", quoter.Quote(model.TableName()), model.Alias(), diff --git a/persistence/sql/persister_continuity.go b/persistence/sql/persister_continuity.go index c57d64a8462c..a8759f56d8bd 100644 --- a/persistence/sql/persister_continuity.go +++ b/persistence/sql/persister_continuity.go @@ -43,7 +43,7 @@ func (p *Persister) DeleteContinuitySession(ctx context.Context, id uuid.UUID) e defer span.End() if count, err := p.GetConnection(ctx).RawQuery( - //#nosec + //#nosec G201 -- TableName is static fmt.Sprintf("DELETE FROM %s WHERE id=? AND nid=?", new(continuity.Container).TableName(ctx)), id, p.NetworkID(ctx)).ExecWithCount(); err != nil { return sqlcon.HandleError(err) @@ -54,7 +54,7 @@ func (p *Persister) DeleteContinuitySession(ctx context.Context, id uuid.UUID) e } func (p *Persister) DeleteExpiredContinuitySessions(ctx context.Context, expiresAt time.Time, limit int) error { - //#nosec G201 + //#nosec G201 -- TableName is static err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(continuity.Container).TableName(ctx), diff --git a/persistence/sql/persister_errorx.go b/persistence/sql/persister_errorx.go index 623583e199a8..5bfe7bd99ed8 100644 --- a/persistence/sql/persister_errorx.go +++ b/persistence/sql/persister_errorx.go @@ -7,7 +7,6 @@ import ( "bytes" "context" "encoding/json" - "fmt" "time" "github.com/gofrs/uuid" @@ -56,9 +55,8 @@ func (p *Persister) Read(ctx context.Context, id uuid.UUID) (*errorx.ErrorContai return nil, sqlcon.HandleError(err) } - //#nosec G201 if err := p.GetConnection(ctx).RawQuery( - fmt.Sprintf("UPDATE %s SET was_seen = true, seen_at = ? WHERE id = ? AND nid = ?", "selfservice_errors"), + "UPDATE selfservice_errors SET was_seen = true, seen_at = ? WHERE id = ? AND nid = ?", time.Now().UTC(), id, p.NetworkID(ctx)).Exec(); err != nil { return nil, sqlcon.HandleError(err) } @@ -71,14 +69,12 @@ func (p *Persister) Clear(ctx context.Context, olderThan time.Duration, force bo defer span.End() if force { - //#nosec G201 err = p.GetConnection(ctx).RawQuery( - fmt.Sprintf("DELETE FROM %s WHERE nid = ? AND seen_at < ? AND seen_at IS NOT NULL", "selfservice_errors"), + "DELETE FROM selfservice_errors WHERE nid = ? AND seen_at < ? AND seen_at IS NOT NULL", p.NetworkID(ctx), time.Now().UTC().Add(-olderThan)).Exec() } else { - //#nosec G201 err = p.GetConnection(ctx).RawQuery( - fmt.Sprintf("DELETE FROM %s WHERE nid = ? AND was_seen=true AND seen_at < ? AND seen_at IS NOT NULL", "selfservice_errors"), + "DELETE FROM selfservice_errors WHERE nid = ? AND was_seen=true AND seen_at < ? AND seen_at IS NOT NULL", p.NetworkID(ctx), time.Now().UTC().Add(-olderThan)).Exec() } diff --git a/persistence/sql/persister_login.go b/persistence/sql/persister_login.go index 23c7e54c01b9..1773049079c0 100644 --- a/persistence/sql/persister_login.go +++ b/persistence/sql/persister_login.go @@ -68,7 +68,7 @@ func (p *Persister) ForceLoginFlow(ctx context.Context, id uuid.UUID) error { } func (p *Persister) DeleteExpiredLoginFlows(ctx context.Context, expiresAt time.Time, limit int) error { - //#nosec G201 + //#nosec G201 -- TableName is static err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(login.Flow).TableName(ctx), diff --git a/persistence/sql/persister_recovery.go b/persistence/sql/persister_recovery.go index f783d1f72293..f7f97c7e3b9d 100644 --- a/persistence/sql/persister_recovery.go +++ b/persistence/sql/persister_recovery.go @@ -119,7 +119,7 @@ func (p *Persister) DeleteRecoveryToken(ctx context.Context, token string) error } func (p *Persister) DeleteExpiredRecoveryFlows(ctx context.Context, expiresAt time.Time, limit int) error { - //#nosec G201 + //#nosec G201 -- TableName is static err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(recovery.Flow).TableName(ctx), diff --git a/persistence/sql/persister_registration.go b/persistence/sql/persister_registration.go index fbd04759f0be..c2c996e409b3 100644 --- a/persistence/sql/persister_registration.go +++ b/persistence/sql/persister_registration.go @@ -48,7 +48,7 @@ func (p *Persister) GetRegistrationFlow(ctx context.Context, id uuid.UUID) (*reg } func (p *Persister) DeleteExpiredRegistrationFlows(ctx context.Context, expiresAt time.Time, limit int) error { - //#nosec G201 + //#nosec G201 -- TableName is static err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(registration.Flow).TableName(ctx), diff --git a/persistence/sql/persister_settings.go b/persistence/sql/persister_settings.go index 7218720efb1d..dcdbded94198 100644 --- a/persistence/sql/persister_settings.go +++ b/persistence/sql/persister_settings.go @@ -58,7 +58,7 @@ func (p *Persister) UpdateSettingsFlow(ctx context.Context, r *settings.Flow) er } func (p *Persister) DeleteExpiredSettingsFlows(ctx context.Context, expiresAt time.Time, limit int) error { - //#nosec G201 + //#nosec G201 -- TableName is static err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(settings.Flow).TableName(ctx), diff --git a/persistence/sql/persister_verification.go b/persistence/sql/persister_verification.go index 2305c184c124..1fe219d6f7a4 100644 --- a/persistence/sql/persister_verification.go +++ b/persistence/sql/persister_verification.go @@ -120,7 +120,7 @@ func (p *Persister) DeleteVerificationToken(ctx context.Context, token string) e } func (p *Persister) DeleteExpiredVerificationFlows(ctx context.Context, expiresAt time.Time, limit int) error { - //#nosec G201 + //#nosec G201 -- TableName is static err := p.GetConnection(ctx).RawQuery(fmt.Sprintf( "DELETE FROM %s WHERE id in (SELECT id FROM (SELECT id FROM %s c WHERE expires_at <= ? and nid = ? ORDER BY expires_at ASC LIMIT %d ) AS s )", new(verification.Flow).TableName(ctx), diff --git a/selfservice/strategy/password/registration_test.go b/selfservice/strategy/password/registration_test.go index 1059d14f9cdf..33bb46c485bf 100644 --- a/selfservice/strategy/password/registration_test.go +++ b/selfservice/strategy/password/registration_test.go @@ -76,8 +76,7 @@ func TestRegistration(t *testing.T) { apiClient := testhelpers.NewDebugClient(t) t.Run("AssertCommonErrorCases", func(t *testing.T) { - reg := newRegistrationRegistry(t) - registrationhelpers.AssertCommonErrorCases(t, reg, flows) + registrationhelpers.AssertCommonErrorCases(t, flows) }) t.Run("AssertRegistrationRespectsValidation", func(t *testing.T) { diff --git a/selfservice/strategy/password/validator.go b/selfservice/strategy/password/validator.go index 1d4d5d00c607..2d9411d01da1 100644 --- a/selfservice/strategy/password/validator.go +++ b/selfservice/strategy/password/validator.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/go-retryablehttp" - "crypto/sha1" //#nosec G505 sha1 is used for k-anonymity + "crypto/sha1" //#nosec G505 -- sha1 is used for k-anonymity "fmt" "net/http" "strconv" diff --git a/selfservice/strategy/password/validator_test.go b/selfservice/strategy/password/validator_test.go index af64cdd2ceda..c3a066aad5dc 100644 --- a/selfservice/strategy/password/validator_test.go +++ b/selfservice/strategy/password/validator_test.go @@ -7,7 +7,7 @@ import ( "bytes" "context" "crypto/rand" - "crypto/sha1" //#nosec G505 - compatibility for imported passwords + "crypto/sha1" //#nosec G505 -- compatibility for imported passwords "errors" "fmt" "io" diff --git a/selfservice/strategy/webauthn/registration_test.go b/selfservice/strategy/webauthn/registration_test.go index 59a559f7ce6d..6c0eda973309 100644 --- a/selfservice/strategy/webauthn/registration_test.go +++ b/selfservice/strategy/webauthn/registration_test.go @@ -88,8 +88,7 @@ func TestRegistration(t *testing.T) { //} t.Run("AssertCommonErrorCases", func(t *testing.T) { - reg := newRegistrationRegistry(t) - registrationhelpers.AssertCommonErrorCases(t, reg, flows) + registrationhelpers.AssertCommonErrorCases(t, flows) }) t.Run("AssertRegistrationRespectsValidation", func(t *testing.T) { From cb1664947921ca7b529b74c14ddd1cd131847428 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 11:56:12 +0100 Subject: [PATCH 18/24] feat: factor out (*Persister).update() --- .../sql/identity/persister_identity.go | 3 +- persistence/sql/persister.go | 63 ---------------- persistence/sql/persister_courier.go | 3 +- persistence/sql/persister_login.go | 3 +- persistence/sql/persister_recovery.go | 3 +- persistence/sql/persister_registration.go | 3 +- persistence/sql/persister_settings.go | 3 +- persistence/sql/persister_verification.go | 3 +- persistence/sql/update/update.go | 72 +++++++++++++++++++ 9 files changed, 86 insertions(+), 70 deletions(-) create mode 100644 persistence/sql/update/update.go diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index c696be362139..b5ac8c40b7d7 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -26,6 +26,7 @@ import ( "github.com/ory/kratos/driver/config" "github.com/ory/kratos/identity" "github.com/ory/kratos/otp" + "github.com/ory/kratos/persistence/sql/update" "github.com/ory/kratos/schema" "github.com/ory/kratos/x" @@ -697,7 +698,7 @@ func (p *IdentityPersister) UpdateVerifiableAddress(ctx context.Context, address address.NID = p.NetworkID(ctx) address.Value = stringToLowerTrim(address.Value) - return p.update(ctx, address) + return update.Generic(ctx, p.GetConnection(ctx), p.r.Tracer(ctx).Tracer(), address) } func (p *IdentityPersister) validateIdentity(ctx context.Context, i *identity.Identity) (err error) { diff --git a/persistence/sql/persister.go b/persistence/sql/persister.go index c202d3fd4fd8..c49216d3f7aa 100644 --- a/persistence/sql/persister.go +++ b/persistence/sql/persister.go @@ -6,11 +6,9 @@ package sql import ( "context" "embed" - "fmt" "time" "github.com/gobuffalo/pop/v6" - "github.com/gobuffalo/pop/v6/columns" "github.com/gofrs/uuid" "github.com/laher/mergefs" "github.com/pkg/errors" @@ -26,7 +24,6 @@ import ( "github.com/ory/x/contextx" "github.com/ory/x/networkx" "github.com/ory/x/popx" - "github.com/ory/x/sqlcon" ) var _ persistence.Persister = new(Persister) @@ -149,15 +146,6 @@ func (p *Persister) Ping() error { return errors.WithStack(p.c.Store.(pinger).Ping()) } -type quotable interface { - Quote(key string) string -} - -type node interface { - GetID() uuid.UUID - GetNID() uuid.UUID -} - 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) @@ -208,54 +196,3 @@ func (p *Persister) CleanupDatabase(ctx context.Context, wait time.Duration, old "This should be re-run periodically, to be sure that all expired data is purged.") return nil } - -func (p *Persister) update(ctx context.Context, v node, columnNames ...string) error { - ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.update") - defer span.End() - - c := p.GetConnection(ctx) - quoter, ok := c.Dialect.(quotable) - if !ok { - return errors.Errorf("store is not a quoter: %T", p.c.Store) - } - - model := pop.NewModel(v, ctx) - tn := model.TableName() - - cols := columns.Columns{} - if len(columnNames) > 0 && tn == model.TableName() { - cols = columns.NewColumnsWithAlias(tn, model.As, model.IDField()) - cols.Add(columnNames...) - } else { - cols = columns.ForStructWithAlias(v, tn, model.As, model.IDField()) - } - - //#nosec G201 -- TableName is static - stmt := fmt.Sprintf("SELECT COUNT(id) FROM %s AS %s WHERE %s.id = ? AND %s.nid = ?", - quoter.Quote(model.TableName()), - model.Alias(), - model.Alias(), - model.Alias(), - ) - - var count int - if err := c.Store.GetContext(ctx, &count, c.Dialect.TranslateSQL(stmt), v.GetID(), v.GetNID()); err != nil { - return sqlcon.HandleError(err) - } else if count == 0 { - return errors.WithStack(sqlcon.ErrNoRows) - } - - //#nosec G201 -- TableName is static - stmt = fmt.Sprintf("UPDATE %s AS %s SET %s WHERE %s AND %s.nid = :nid", - quoter.Quote(model.TableName()), - model.Alias(), - cols.Writeable().QuotedUpdateString(quoter), - model.WhereNamedID(), - model.Alias(), - ) - - if _, err := c.Store.NamedExecContext(ctx, stmt, v); err != nil { - return sqlcon.HandleError(err) - } - return nil -} diff --git a/persistence/sql/persister_courier.go b/persistence/sql/persister_courier.go index 15fda3e3b674..437d9132e1d0 100644 --- a/persistence/sql/persister_courier.go +++ b/persistence/sql/persister_courier.go @@ -18,6 +18,7 @@ import ( "github.com/ory/x/uuidx" "github.com/ory/kratos/courier" + "github.com/ory/kratos/persistence/sql/update" ) var _ courier.Persister = new(Persister) @@ -89,7 +90,7 @@ func (p *Persister) NextMessages(ctx context.Context, limit uint8) (messages []c for i := range m { message := &m[i] message.Status = courier.MessageStatusProcessing - if err := p.update(ctx, message, "status"); err != nil { + if err := update.Generic(ctx, p.GetConnection(ctx), p.r.Tracer(ctx).Tracer(), message, "status"); err != nil { return err } } diff --git a/persistence/sql/persister_login.go b/persistence/sql/persister_login.go index 1773049079c0..1f29a1860e35 100644 --- a/persistence/sql/persister_login.go +++ b/persistence/sql/persister_login.go @@ -14,6 +14,7 @@ import ( "github.com/ory/x/sqlcon" + "github.com/ory/kratos/persistence/sql/update" "github.com/ory/kratos/selfservice/flow/login" ) @@ -35,7 +36,7 @@ func (p *Persister) UpdateLoginFlow(ctx context.Context, r *login.Flow) error { r.EnsureInternalContext() cp := *r cp.NID = p.NetworkID(ctx) - return p.update(ctx, cp) + return update.Generic(ctx, p.GetConnection(ctx), p.r.Tracer(ctx).Tracer(), cp) } func (p *Persister) GetLoginFlow(ctx context.Context, id uuid.UUID) (*login.Flow, error) { diff --git a/persistence/sql/persister_recovery.go b/persistence/sql/persister_recovery.go index f7f97c7e3b9d..d34a6fabd435 100644 --- a/persistence/sql/persister_recovery.go +++ b/persistence/sql/persister_recovery.go @@ -15,6 +15,7 @@ import ( "github.com/gofrs/uuid" "github.com/ory/kratos/identity" + "github.com/ory/kratos/persistence/sql/update" "github.com/ory/kratos/selfservice/flow" "github.com/ory/kratos/selfservice/flow/recovery" "github.com/ory/kratos/selfservice/strategy/code" @@ -51,7 +52,7 @@ func (p *Persister) UpdateRecoveryFlow(ctx context.Context, r *recovery.Flow) er cp := *r cp.NID = p.NetworkID(ctx) - return p.update(ctx, cp) + return update.Generic(ctx, p.GetConnection(ctx), p.r.Tracer(ctx).Tracer(), cp) } func (p *Persister) CreateRecoveryToken(ctx context.Context, token *link.RecoveryToken) error { diff --git a/persistence/sql/persister_registration.go b/persistence/sql/persister_registration.go index c2c996e409b3..fe7e25ceeac3 100644 --- a/persistence/sql/persister_registration.go +++ b/persistence/sql/persister_registration.go @@ -12,6 +12,7 @@ import ( "github.com/ory/x/sqlcon" + "github.com/ory/kratos/persistence/sql/update" "github.com/ory/kratos/selfservice/flow/registration" ) @@ -31,7 +32,7 @@ func (p *Persister) UpdateRegistrationFlow(ctx context.Context, r *registration. r.EnsureInternalContext() cp := *r cp.NID = p.NetworkID(ctx) - return p.update(ctx, cp) + return update.Generic(ctx, p.GetConnection(ctx), p.r.Tracer(ctx).Tracer(), cp) } func (p *Persister) GetRegistrationFlow(ctx context.Context, id uuid.UUID) (*registration.Flow, error) { diff --git a/persistence/sql/persister_settings.go b/persistence/sql/persister_settings.go index dcdbded94198..51be36725cbf 100644 --- a/persistence/sql/persister_settings.go +++ b/persistence/sql/persister_settings.go @@ -9,6 +9,7 @@ import ( "time" "github.com/ory/kratos/identity" + "github.com/ory/kratos/persistence/sql/update" "github.com/gofrs/uuid" @@ -54,7 +55,7 @@ func (p *Persister) UpdateSettingsFlow(ctx context.Context, r *settings.Flow) er r.EnsureInternalContext() cp := *r cp.NID = p.NetworkID(ctx) - return p.update(ctx, cp) + return update.Generic(ctx, p.GetConnection(ctx), p.r.Tracer(ctx).Tracer(), cp) } func (p *Persister) DeleteExpiredSettingsFlows(ctx context.Context, expiresAt time.Time, limit int) error { diff --git a/persistence/sql/persister_verification.go b/persistence/sql/persister_verification.go index 1fe219d6f7a4..f25bf5e38141 100644 --- a/persistence/sql/persister_verification.go +++ b/persistence/sql/persister_verification.go @@ -12,6 +12,7 @@ import ( "github.com/pkg/errors" "github.com/ory/kratos/identity" + "github.com/ory/kratos/persistence/sql/update" "github.com/gobuffalo/pop/v6" "github.com/gofrs/uuid" @@ -53,7 +54,7 @@ func (p *Persister) UpdateVerificationFlow(ctx context.Context, r *verification. cp := *r cp.NID = p.NetworkID(ctx) - return p.update(ctx, cp) + return update.Generic(ctx, p.GetConnection(ctx), p.r.Tracer(ctx).Tracer(), cp) } func (p *Persister) CreateVerificationToken(ctx context.Context, token *link.VerificationToken) error { diff --git a/persistence/sql/update/update.go b/persistence/sql/update/update.go new file mode 100644 index 000000000000..2d7582060f8e --- /dev/null +++ b/persistence/sql/update/update.go @@ -0,0 +1,72 @@ +// Copyright © 2023 Ory Corp +// SPDX-License-Identifier: Apache-2.0 + +package update + +import ( + "context" + "fmt" + + "github.com/gobuffalo/pop/v6" + "github.com/gobuffalo/pop/v6/columns" + "github.com/gofrs/uuid" + "github.com/pkg/errors" + "go.opentelemetry.io/otel/trace" + + "github.com/ory/x/sqlcon" +) + +type Model interface { + GetID() uuid.UUID + GetNID() uuid.UUID +} + +func Generic(ctx context.Context, c *pop.Connection, tracer trace.Tracer, v Model, columnNames ...string) error { + ctx, span := tracer.Start(ctx, "persistence.sql.update") + defer span.End() + + quoter, ok := c.Dialect.(interface{ Quote(key string) string }) + if !ok { + return errors.Errorf("store is not a quoter: %T", c.Store) + } + + model := pop.NewModel(v, ctx) + tn := model.TableName() + + cols := columns.Columns{} + if len(columnNames) > 0 && tn == model.TableName() { + cols = columns.NewColumnsWithAlias(tn, model.As, model.IDField()) + cols.Add(columnNames...) + } else { + cols = columns.ForStructWithAlias(v, tn, model.As, model.IDField()) + } + + //#nosec G201 -- TableName is static + stmt := fmt.Sprintf("SELECT COUNT(id) FROM %s AS %s WHERE %s.id = ? AND %s.nid = ?", + quoter.Quote(model.TableName()), + model.Alias(), + model.Alias(), + model.Alias(), + ) + + var count int + if err := c.Store.GetContext(ctx, &count, c.Dialect.TranslateSQL(stmt), v.GetID(), v.GetNID()); err != nil { + return sqlcon.HandleError(err) + } else if count == 0 { + return errors.WithStack(sqlcon.ErrNoRows) + } + + //#nosec G201 -- TableName is static + stmt = fmt.Sprintf("UPDATE %s AS %s SET %s WHERE %s AND %s.nid = :nid", + quoter.Quote(model.TableName()), + model.Alias(), + cols.Writeable().QuotedUpdateString(quoter), + model.WhereNamedID(), + model.Alias(), + ) + + if _, err := c.Store.NamedExecContext(ctx, stmt, v); err != nil { + return sqlcon.HandleError(err) + } + return nil +} From 58c82c70398b64cb9a588e24bcd41e9588474232 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 12:09:36 +0100 Subject: [PATCH 19/24] fix: hydrate session identity --- session/manager_http.go | 1 - 1 file changed, 1 deletion(-) diff --git a/session/manager_http.go b/session/manager_http.go index e6bb6c4e43c0..b24a41a94b8d 100644 --- a/session/manager_http.go +++ b/session/manager_http.go @@ -274,7 +274,6 @@ func (s *ManagerHTTP) DoesSessionSatisfy(r *http.Request, sess *Session, request return err } } else if len(i.Credentials) == 0 { - i = sess.Identity.CopyWithoutCredentials() // we don't want to modify the identity in the session object if err := s.r.PrivilegedIdentityPool().HydrateIdentityAssociations(ctx, i, identity.ExpandCredentials); err != nil { return err } From f85a0337299b10e4b37b50de041b9861e5ec3b49 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 12:14:23 +0100 Subject: [PATCH 20/24] fix: InjectTraitsSchemaURL description --- identity/pool.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/identity/pool.go b/identity/pool.go index 296c93d064bc..f5d5ad50dfd1 100644 --- a/identity/pool.go +++ b/identity/pool.go @@ -78,7 +78,7 @@ type ( // HydrateIdentityAssociations hydrates the associations of an identity. HydrateIdentityAssociations(ctx context.Context, i *Identity, expandables Expandables) error - // TODO: description + // InjectTraitsSchemaURL sets the identity's traits JSON schema URL from the schema's ID. InjectTraitsSchemaURL(ctx context.Context, i *Identity) error } ) From 076fe90144434b61197f44d5baa5f7cd8bb9988e Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 12:45:56 +0100 Subject: [PATCH 21/24] fix: expose (*Identity).Validate() --- identity/identity.go | 4 ++-- identity/identity_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/identity/identity.go b/identity/identity.go index bf6253c35298..520d824cf867 100644 --- a/identity/identity.go +++ b/identity/identity.go @@ -137,7 +137,7 @@ func (i *Identity) AfterEagerFind(tx *pop.Connection) error { return err } - if err := i.validate(); err != nil { + if err := i.Validate(); err != nil { return err } @@ -378,7 +378,7 @@ func (i WithCredentialsMetadataAndAdminMetadataInJSON) MarshalJSON() ([]byte, er return json.Marshal(localIdentity(i)) } -func (i *Identity) validate() error { +func (i *Identity) Validate() error { expected := i.NID if expected == uuid.Nil { return errors.WithStack(herodot.ErrInternalServerError.WithReason("Received empty nid.")) diff --git a/identity/identity_test.go b/identity/identity_test.go index e6008d0ae050..af72fd5ae4a7 100644 --- a/identity/identity_test.go +++ b/identity/identity_test.go @@ -267,7 +267,7 @@ func TestValidateNID(t *testing.T) { }, } { t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) { - err := tc.i.validate() + err := tc.i.Validate() if tc.expectedErr { require.Error(t, err) } else { From 864c868e9faafa342b1cd68b38821812e892386b Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 12:50:58 +0100 Subject: [PATCH 22/24] fix: delete (*IdentityPersister).update() --- .../sql/identity/persister_identity.go | 63 +------------------ 1 file changed, 1 insertion(+), 62 deletions(-) diff --git a/persistence/sql/identity/persister_identity.go b/persistence/sql/identity/persister_identity.go index b5ac8c40b7d7..723c5fbc0cbd 100644 --- a/persistence/sql/identity/persister_identity.go +++ b/persistence/sql/identity/persister_identity.go @@ -31,7 +31,6 @@ import ( "github.com/ory/kratos/x" "github.com/gobuffalo/pop/v6" - "github.com/gobuffalo/pop/v6/columns" "github.com/gofrs/uuid" "github.com/pkg/errors" @@ -580,7 +579,7 @@ func (p *IdentityPersister) UpdateIdentity(ctx context.Context, i *identity.Iden return sqlcon.HandleError(err) } - if err := p.update(WithTransaction(ctx, tx), i); err != nil { + if err := update.Generic(WithTransaction(ctx, tx), tx, p.r.Tracer(ctx).Tracer(), i); err != nil { return err } @@ -731,63 +730,3 @@ func (p *IdentityPersister) InjectTraitsSchemaURL(ctx context.Context, i *identi i.SchemaURL = s.SchemaURL(p.r.Config().SelfPublicURL(ctx)).String() return nil } - -type quotable interface { - Quote(key string) string -} - -type node interface { - GetID() uuid.UUID - GetNID() uuid.UUID -} - -func (p *IdentityPersister) update(ctx context.Context, v node, columnNames ...string) (err error) { - ctx, span := p.r.Tracer(ctx).Tracer().Start(ctx, "persistence.sql.update") - otelx.End(span, &err) - - c := p.GetConnection(ctx) - quoter, ok := c.Dialect.(quotable) - if !ok { - return errors.Errorf("store is not a quoter: %T", p.c.Store) - } - - model := pop.NewModel(v, ctx) - tn := model.TableName() - - cols := columns.Columns{} - if len(columnNames) > 0 && tn == model.TableName() { - cols = columns.NewColumnsWithAlias(tn, model.As, model.IDField()) - cols.Add(columnNames...) - } else { - cols = columns.ForStructWithAlias(v, tn, model.As, model.IDField()) - } - - //#nosec G201 -- TableName is static - stmt := fmt.Sprintf("SELECT COUNT(id) FROM %s AS %s WHERE %s.id = ? AND %s.nid = ?", - quoter.Quote(model.TableName()), - model.Alias(), - model.Alias(), - model.Alias(), - ) - - var count int - if err := c.Store.GetContext(ctx, &count, c.Dialect.TranslateSQL(stmt), v.GetID(), v.GetNID()); err != nil { - return sqlcon.HandleError(err) - } else if count == 0 { - return errors.WithStack(sqlcon.ErrNoRows) - } - - //#nosec G201 -- TableName is static - stmt = fmt.Sprintf("UPDATE %s AS %s SET %s WHERE %s AND %s.nid = :nid", - quoter.Quote(model.TableName()), - model.Alias(), - cols.Writeable().QuotedUpdateString(quoter), - model.WhereNamedID(), - model.Alias(), - ) - - if _, err := c.Store.NamedExecContext(ctx, stmt, v); err != nil { - return sqlcon.HandleError(err) - } - return nil -} From d5ead1c0e6c152b9277cb5a9f8af9d2a22006be3 Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 12:56:13 +0100 Subject: [PATCH 23/24] fix: hydrate session identity --- session/manager_http.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/session/manager_http.go b/session/manager_http.go index b24a41a94b8d..7bc438111002 100644 --- a/session/manager_http.go +++ b/session/manager_http.go @@ -273,7 +273,9 @@ func (s *ManagerHTTP) DoesSessionSatisfy(r *http.Request, sess *Session, request if err != nil { return err } + sess.Identity = i } else if len(i.Credentials) == 0 { + // If credentials are not expanded, we load them here. if err := s.r.PrivilegedIdentityPool().HydrateIdentityAssociations(ctx, i, identity.ExpandCredentials); err != nil { return err } From b8a7b725f7419fa9e49ce848040621957e2d47be Mon Sep 17 00:00:00 2001 From: Arne Luenser Date: Fri, 3 Mar 2023 13:58:30 +0100 Subject: [PATCH 24/24] Revert "chore: bump dependencies" This reverts commit 0f187f6c26af7aff5b46e8f2fbe377d26e3623ed. --- go.mod | 16 +++++++++++----- go.sum | 21 ++++++--------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/go.mod b/go.mod index 993859353455..b501a219b098 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,21 @@ module github.com/ory/kratos go 1.19 replace ( + github.com/bradleyjkemp/cupaloy/v2 => github.com/aeneasr/cupaloy/v2 v2.6.1-0.20210924214125-3dfdd01210a3 + github.com/go-sql-driver/mysql => github.com/go-sql-driver/mysql v1.7.0 - github.com/gorilla/sessions => github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2 // https://github.com/gorilla/sessions/pull/255 + github.com/gorilla/sessions => github.com/ory/sessions v1.2.2-0.20220110165800-b09c17334dc2 + github.com/knadh/koanf => github.com/aeneasr/koanf v0.14.1-0.20211230115640-aa3902b3267a + + github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.14.7-0.20210414154423-1157a4212dcb + github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1 - github.com/mattn/go-sqlite3 => github.com/mattn/go-sqlite3 v1.14.16 + github.com/ory/client-go => ./internal/client-go // Use the internal httpclient which can be generated in this codebase but mark it as the // official SDK, allowing for the Ory CLI to consume Ory Kratos' CLI commands. - github.com/ory/client-go => ./internal/client-go + gopkg.in/DataDog/dd-trace-go.v1 => gopkg.in/DataDog/dd-trace-go.v1 v1.27.1-0.20201005154917-54b73b3e126a ) require ( @@ -54,7 +60,7 @@ require ( github.com/jarcoal/httpmock v1.0.5 github.com/jteeuwen/go-bindata v3.0.7+incompatible github.com/julienschmidt/httprouter v1.3.0 - github.com/knadh/koanf v1.5.0 + github.com/knadh/koanf v1.4.4 github.com/laher/mergefs v0.1.2-0.20230223191438-d16611b2f4e7 github.com/luna-duclos/instrumentedsql v1.1.3 github.com/mattn/goveralls v0.0.7 @@ -225,7 +231,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.12 // indirect - github.com/mattn/go-sqlite3 v1.14.16 // indirect + github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/microcosm-cc/bluemonday v1.0.21 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect diff --git a/go.sum b/go.sum index 44e918c94704..acd2028d3d9a 100644 --- a/go.sum +++ b/go.sum @@ -98,6 +98,10 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/a8m/envsubst v1.3.0 h1:GmXKmVssap0YtlU3E230W98RWtWCyIZzjtf1apWWyAg= github.com/a8m/envsubst v1.3.0/go.mod h1:MVUTQNGQ3tsjOOtKCNd+fl8RzhsXcDvvAEzkhGtlsbY= +github.com/aeneasr/cupaloy/v2 v2.6.1-0.20210924214125-3dfdd01210a3 h1:/SkiUr3JJzun9QN9cpUVCPri2ZwOFJ3ani+F3vdoCiY= +github.com/aeneasr/cupaloy/v2 v2.6.1-0.20210924214125-3dfdd01210a3/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= +github.com/aeneasr/koanf v0.14.1-0.20211230115640-aa3902b3267a h1:CWZu1palLlc1XlFcbEQ6i4Oqax3CJ8YEAb/mIdkPu5o= +github.com/aeneasr/koanf v0.14.1-0.20211230115640-aa3902b3267a/go.mod h1:1cfH5223ZeZUOs8FU2UdTmaNfHpqgtjV0+NHjRO43gs= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= @@ -177,8 +181,6 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M= -github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0= github.com/bwmarrin/discordgo v0.23.0 h1://ARp8qUrRZvDGMkfAjtcC20WOvsMtTgi+KrdKnl6eY= github.com/bwmarrin/discordgo v0.23.0/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M= github.com/bxcodec/faker/v3 v3.3.1 h1:G7uldFk+iO/ES7W4v7JlI/WU9FQ6op9VJ15YZlDEhGQ= @@ -683,12 +685,10 @@ github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69 h1:7xsUJsB2Nrdct github.com/gtank/cryptopasta v0.0.0-20170601214702-1f550f6f2f69/go.mod h1:YLEMZOtU+AZ7dhN9T/IpGhXVGly2bvkJQ+zxj3WeVQo= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/api v1.18.0 h1:R7PPNzTCeN6VuQNDwwhZWJvzCtGSrNpJqfb22h3yH9g= github.com/hashicorp/consul/api v1.18.0/go.mod h1:owRRGJ9M5xReDC5nfT8FTJrNAPbT4NM6p/k+d03q2v4= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/consul/sdk v0.13.0 h1:lce3nFlpv8humJL8rNrrGHYSKc3q+Kxfeg3Ii1m6ZWU= github.com/hashicorp/consul/sdk v0.13.0/go.mod h1:0hs/l5fOVhJy/VdcoaNqUSi2AUs95eF5WKtv+EYIQqE= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -745,19 +745,15 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q= github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/hjson/hjson-go/v4 v4.0.0 h1:wlm6IYYqHjOdXH1gHev4VoXCaW20HdQAGCxdOEEg2cs= -github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= @@ -900,8 +896,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/kisom/goutils v1.4.3/go.mod h1:Lp5qrquG7yhYnWzZCI/68Pa/GpFynw//od6EkGnWpac= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/knadh/koanf v1.5.0 h1:q2TSd/3Pyc/5yP9ldIrSdIz26MCcyNQzW0pEAugLPNs= -github.com/knadh/koanf v1.5.0/go.mod h1:Hgyjp4y8v44hpZtPzs7JZfRAW5AhN7KfZcwv1RYggDs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -982,8 +976,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= -github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.7-0.20210414154423-1157a4212dcb h1:ax2vG2unlxsjwS7PMRo4FECIfAdQLowd6ejWYwPQhBo= +github.com/mattn/go-sqlite3 v1.14.7-0.20210414154423-1157a4212dcb/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/goveralls v0.0.7 h1:vzy0i4a2iDzEFMdXIxcanRadkr0FBvSBKUmj0P8SPlQ= github.com/mattn/goveralls v0.0.7/go.mod h1:h8b4ow6FxSPMQHF6o2ve3qsclnffZjYTNEKmLesRwqw= @@ -1449,17 +1443,14 @@ go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw= -go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/api/v3 v3.5.6 h1:Cy2qx3npLcYqTKqGJzMypnMv2tiRyifZJ17BlWIWA7A= go.etcd.io/etcd/api/v3 v3.5.6/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= -go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/pkg/v3 v3.5.6 h1:TXQWYceBKqLp4sa87rcPs11SXxUA/mHwH975v+BDvLU= go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU= go.etcd.io/etcd/client/v2 v2.305.6 h1:fIDR0p4KMjw01MJMfUIDWdQbjo06PD6CeYM5z4EHLi0= go.etcd.io/etcd/client/v2 v2.305.6/go.mod h1:BHha8XJGe8vCIBfWBpbBLVZ4QjOIlfoouvOwydu63E0= go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= -go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.etcd.io/etcd/client/v3 v3.5.6 h1:coLs69PWCXE9G4FKquzNaSHrRyMCAXwF+IX1tAPVO8E= go.etcd.io/etcd/client/v3 v3.5.6/go.mod h1:f6GRinRMCsFVv9Ht42EyY7nfsVGwrNO0WEoS2pRKzQk= go.etcd.io/etcd/etcdctl/v3 v3.5.0-alpha.0 h1:odMFuQQCg0UmPd7Cyw6TViRYv9ybGuXuki4CusDSzqA=