mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
## Problem description During tests we found concurrency issues in the relational table projections. Tests got flaky if a table (e.g. organization domains) had too many foreign keys to tables which were projected by another handler. ## Resolution The projections of the relational tables got merged into one handler to enforce sequential reduction of events. ## Additional info - closes https://github.com/zitadel/zitadel/issues/11703 - closes https://github.com/zitadel/zitadel/issues/10810 --------- Co-authored-by: Marco Ardizzone <[email protected]>
1878 lines
62 KiB
Go
1878 lines
62 KiB
Go
package projection
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"time"
|
|
|
|
"github.com/zitadel/zitadel/backend/v3/domain"
|
|
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
|
v3_sql "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/sql"
|
|
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
|
|
"github.com/zitadel/zitadel/internal/crypto"
|
|
old_domain "github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/eventstore"
|
|
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
|
"github.com/zitadel/zitadel/internal/repository/user"
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
|
)
|
|
|
|
func (p *relationalTablesProjection) reduceHumanAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
v3Tx := v3_sql.SQLTx(tx)
|
|
|
|
userRepo := repository.UserRepository()
|
|
|
|
var phone *domain.HumanPhone
|
|
if e.PhoneNumber != "" {
|
|
phone = &domain.HumanPhone{
|
|
UnverifiedNumber: string(e.PhoneNumber),
|
|
}
|
|
}
|
|
|
|
password := domain.HumanPassword{
|
|
IsChangeRequired: e.ChangeRequired,
|
|
}
|
|
if hash := crypto.SecretOrEncodedHash(e.Secret, e.EncodedHash); hash != "" {
|
|
password.Hash = hash
|
|
password.ChangedAt = e.CreatedAt()
|
|
}
|
|
|
|
return userRepo.Create(ctx, v3Tx, &domain.User{
|
|
InstanceID: e.Aggregate().InstanceID,
|
|
OrganizationID: e.Aggregate().ResourceOwner,
|
|
ID: e.Aggregate().ID,
|
|
Username: e.UserName,
|
|
State: domain.UserStateActive,
|
|
CreatedAt: e.CreatedAt(),
|
|
UpdatedAt: e.CreatedAt(),
|
|
Human: &domain.HumanUser{
|
|
FirstName: e.FirstName,
|
|
LastName: e.LastName,
|
|
Nickname: e.NickName,
|
|
DisplayName: e.DisplayName,
|
|
PreferredLanguage: e.PreferredLanguage,
|
|
Gender: mapHumanGender(e.Gender),
|
|
Email: domain.HumanEmail{
|
|
UnverifiedAddress: string(e.EmailAddress),
|
|
},
|
|
Phone: phone,
|
|
Password: password,
|
|
},
|
|
})
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanRegistered(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanRegisteredEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
v3Tx := v3_sql.SQLTx(tx)
|
|
|
|
userRepo := repository.UserRepository()
|
|
|
|
var phone *domain.HumanPhone
|
|
if e.PhoneNumber != "" {
|
|
phone = &domain.HumanPhone{
|
|
UnverifiedNumber: string(e.PhoneNumber),
|
|
}
|
|
}
|
|
|
|
password := domain.HumanPassword{
|
|
IsChangeRequired: e.ChangeRequired,
|
|
}
|
|
if hash := crypto.SecretOrEncodedHash(e.Secret, e.EncodedHash); hash != "" {
|
|
password.Hash = hash
|
|
password.ChangedAt = e.CreatedAt()
|
|
}
|
|
|
|
return userRepo.Create(ctx, v3Tx, &domain.User{
|
|
InstanceID: e.Aggregate().InstanceID,
|
|
OrganizationID: e.Aggregate().ResourceOwner,
|
|
ID: e.Aggregate().ID,
|
|
Username: e.UserName,
|
|
State: domain.UserStateActive,
|
|
CreatedAt: e.CreatedAt(),
|
|
UpdatedAt: e.CreatedAt(),
|
|
Human: &domain.HumanUser{
|
|
FirstName: e.FirstName,
|
|
LastName: e.LastName,
|
|
Nickname: e.NickName,
|
|
DisplayName: e.DisplayName,
|
|
PreferredLanguage: e.PreferredLanguage,
|
|
Gender: mapHumanGender(e.Gender),
|
|
Email: domain.HumanEmail{
|
|
UnverifiedAddress: string(e.EmailAddress),
|
|
},
|
|
Phone: phone,
|
|
Password: password,
|
|
},
|
|
})
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserLocked(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserLockedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewMultiStatement(e,
|
|
handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Update(
|
|
ctx,
|
|
v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID),
|
|
repo.SetState(domain.UserStateLocked),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}),
|
|
handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-fcxV68", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
v3Tx := v3_sql.SQLTx(tx)
|
|
|
|
sessionRepo := repository.SessionRepository()
|
|
condition := database.And(
|
|
sessionRepo.InstanceIDCondition(event.Aggregate().InstanceID),
|
|
sessionRepo.UserIDCondition(event.Aggregate().ID),
|
|
)
|
|
_, err := sessionRepo.Delete(ctx, v3Tx, condition)
|
|
return err
|
|
}),
|
|
), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserUnlocked(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserUnlockedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Update(
|
|
ctx,
|
|
v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID),
|
|
repo.SetState(domain.UserStateActive),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserDeactivated(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserDeactivatedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewMultiStatement(event,
|
|
handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Update(
|
|
ctx,
|
|
v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID),
|
|
repo.SetState(domain.UserStateInactive),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}),
|
|
handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-fcxV68", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
v3Tx := v3_sql.SQLTx(tx)
|
|
|
|
sessionRepo := repository.SessionRepository()
|
|
condition := database.And(
|
|
sessionRepo.InstanceIDCondition(event.Aggregate().InstanceID),
|
|
sessionRepo.UserIDCondition(event.Aggregate().ID),
|
|
)
|
|
_, err := sessionRepo.Delete(ctx, v3Tx, condition)
|
|
return err
|
|
}),
|
|
), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserReactivated(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserReactivatedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Update(
|
|
ctx,
|
|
v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID),
|
|
repo.SetState(domain.UserStateActive),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Delete(
|
|
ctx,
|
|
v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUsernameChanged(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UsernameChangedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Update(
|
|
ctx,
|
|
v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID),
|
|
repo.SetUsername(e.UserName),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserDomainClaimed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.DomainClaimedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
userRepo := repository.UserRepository()
|
|
|
|
_, err := userRepo.Update(ctx, v3_sql.SQLTx(tx),
|
|
userRepo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
userRepo.SetUsername(e.UserName),
|
|
userRepo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanProfileChanged(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanProfileChangedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
repo := repository.UserRepository().Human()
|
|
changes := make([]database.Change, 0, 7)
|
|
|
|
if e.FirstName != "" {
|
|
changes = append(changes, repo.SetFirstName(e.FirstName))
|
|
}
|
|
|
|
if e.LastName != "" {
|
|
changes = append(changes, repo.SetLastName(e.LastName))
|
|
}
|
|
|
|
if e.NickName != nil {
|
|
changes = append(changes, repo.SetNickname(*e.NickName))
|
|
}
|
|
|
|
if e.DisplayName != nil {
|
|
changes = append(changes, repo.SetDisplayName(*e.DisplayName))
|
|
}
|
|
|
|
if e.PreferredLanguage != nil {
|
|
changes = append(changes, repo.SetPreferredLanguage(*e.PreferredLanguage))
|
|
}
|
|
|
|
if e.Gender != nil {
|
|
changes = append(changes, repo.SetGender(mapHumanGender(*e.Gender)))
|
|
}
|
|
changes = append(changes, repo.SetUpdatedAt(e.CreatedAt()))
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID),
|
|
changes...,
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPhoneChanged(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPhoneChangedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetUnverifiedPhone(string(e.PhoneNumber)),
|
|
repo.SetPhoneVerification(&domain.VerificationTypeInit{
|
|
CreatedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPhoneRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPhoneRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemovePhone(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPhoneVerified(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPhoneVerifiedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetPhoneVerification(&domain.VerificationTypeSucceeded{
|
|
VerifiedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPhoneCodeAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPhoneCodeAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var expiry *time.Duration
|
|
if e.Expiry > 0 {
|
|
expiry = &e.Expiry
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Human()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetPhoneVerification(&domain.VerificationTypeUpdate{
|
|
Code: e.Code,
|
|
Expiry: expiry,
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPhoneVerificationFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPhoneVerificationFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Human()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetPhoneVerification(&domain.VerificationTypeFailed{
|
|
FailedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanEmailChanged(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanEmailChangedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Human()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetUnverifiedEmail(string(e.EmailAddress)),
|
|
repo.SetEmailVerification(&domain.VerificationTypeInit{
|
|
CreatedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanEmailVerified(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanEmailVerifiedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Human()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetEmailVerification(&domain.VerificationTypeSucceeded{
|
|
VerifiedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanEmailCodeAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanEmailCodeAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Human()
|
|
|
|
var expiry *time.Duration
|
|
if e.Expiry > 0 {
|
|
expiry = &e.Expiry
|
|
}
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetEmailVerification(&domain.VerificationTypeUpdate{
|
|
Code: e.Code,
|
|
Expiry: expiry,
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanEmailVerificationFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanEmailVerificationFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Human()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetEmailVerification(&domain.VerificationTypeFailed{
|
|
FailedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanAvatarAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanAvatarAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Human()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetAvatarKey(&e.StoreKey),
|
|
repo.SetUpdatedAt(e.CreationDate()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanAvatarRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanAvatarRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Human()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetAvatarKey(nil),
|
|
repo.SetUpdatedAt(e.CreationDate()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPasswordChanged(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordChangedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewMultiStatement(e,
|
|
handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetPasswordChangeRequired(e.ChangeRequired),
|
|
repo.SetPassword(crypto.SecretOrEncodedHash(e.Secret, e.EncodedHash)),
|
|
repo.SetResetPasswordVerification(&domain.VerificationTypeSucceeded{VerifiedAt: e.CreatedAt()}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}),
|
|
handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
v3Tx := v3_sql.SQLTx(tx)
|
|
|
|
sessionRepo := repository.SessionRepository()
|
|
condition := database.And(
|
|
sessionRepo.InstanceIDCondition(e.Aggregate().InstanceID),
|
|
sessionRepo.UserIDCondition(e.Aggregate().ID),
|
|
sessionRepo.ExistsFactor(
|
|
database.And(
|
|
sessionRepo.FactorConditions().FactorTypeCondition(domain.SessionFactorTypePassword),
|
|
sessionRepo.FactorConditions().LastVerifiedBeforeCondition(e.CreatedAt()),
|
|
),
|
|
),
|
|
)
|
|
_, err = sessionRepo.Update(ctx, v3Tx, condition,
|
|
sessionRepo.SetUpdatedAt(e.CreatedAt()),
|
|
sessionRepo.ClearFactor(domain.SessionFactorTypePassword),
|
|
)
|
|
return err
|
|
}),
|
|
), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPasswordCodeAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordCodeAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
|
|
var expiry *time.Duration
|
|
if e.Expiry > 0 {
|
|
expiry = &e.Expiry
|
|
}
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetResetPasswordVerification(&domain.VerificationTypeUpdate{
|
|
Code: e.Code,
|
|
Expiry: expiry,
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPasswordCheckSucceeded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordCheckSucceededEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetLastSuccessfulPasswordCheck(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPasswordCheckFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordCheckFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.IncrementPasswordFailedAttempts(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceHumanPasswordHashUpdated(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordHashUpdatedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetPassword(e.EncodedHash),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceMachineSecretSet(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MachineSecretSetEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.MachineUserRepository()
|
|
|
|
secret := crypto.SecretOrEncodedHash(e.ClientSecret, e.HashedSecret)
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetSecret(&secret),
|
|
repo.SetUpdatedAt(e.CreationDate()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceMachineSecretHashUpdated(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MachineSecretHashUpdatedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Machine()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetSecret(&e.HashedSecret),
|
|
repo.SetUpdatedAt(e.CreationDate()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceMachineSecretRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MachineSecretRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository().Machine()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetSecret(nil),
|
|
repo.SetUpdatedAt(e.CreationDate()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceMachineKeyAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MachineKeyAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.MachineUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.AddKey(&domain.MachineKey{
|
|
ID: e.KeyID,
|
|
Type: mapMachineKeyType(e.KeyType),
|
|
PublicKey: e.PublicKey,
|
|
CreatedAt: e.CreatedAt(),
|
|
ExpiresAt: e.ExpirationDate,
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceMachineKeyRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MachineKeyRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.MachineUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemoveKey(e.KeyID),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceMachineAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MachineAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
return repo.Create(ctx, v3_sql.SQLTx(tx),
|
|
&domain.User{
|
|
ID: e.Aggregate().ID,
|
|
InstanceID: e.Aggregate().InstanceID,
|
|
OrganizationID: e.Aggregate().ResourceOwner,
|
|
Username: e.UserName,
|
|
State: domain.UserStateActive,
|
|
CreatedAt: e.CreatedAt(),
|
|
UpdatedAt: e.CreatedAt(),
|
|
Machine: &domain.MachineUser{
|
|
Name: e.Name,
|
|
Description: e.Description,
|
|
AccessTokenType: mapMachineAccessTokenType(e.AccessTokenType),
|
|
},
|
|
},
|
|
)
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceMachineChanged(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MachineChangedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
repo := repository.MachineUserRepository()
|
|
|
|
changes := make([]database.Change, 0, 4)
|
|
if e.Name != nil {
|
|
changes = append(changes, repo.SetName(*e.Name))
|
|
}
|
|
if e.Description != nil {
|
|
changes = append(changes, repo.SetDescription(*e.Description))
|
|
}
|
|
if e.AccessTokenType != nil {
|
|
changes = append(changes, repo.SetAccessTokenType(mapMachineAccessTokenType(*e.AccessTokenType)))
|
|
}
|
|
changes = append(changes, repo.SetUpdatedAt(e.CreatedAt()))
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
database.And(
|
|
repo.InstanceIDCondition(e.Aggregate().InstanceID),
|
|
repo.IDCondition(e.Aggregate().ID),
|
|
),
|
|
changes...,
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePersonalAccessTokenAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.PersonalAccessTokenAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.MachineUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.AddPersonalAccessToken(&domain.PersonalAccessToken{
|
|
ID: e.TokenID,
|
|
Scopes: e.Scopes,
|
|
ExpiresAt: e.Expiration,
|
|
CreatedAt: e.CreatedAt(),
|
|
}),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePersonalAccessTokenRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.PersonalAccessTokenRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.MachineUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemovePersonalAccessToken(e.TokenID),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserMetadataSet(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MetadataSetEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-xg4IJ", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetMetadata(&domain.Metadata{
|
|
Key: e.Key,
|
|
Value: e.Value,
|
|
CreatedAt: e.CreationDate(),
|
|
UpdatedAt: e.CreationDate(),
|
|
}),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserMetadataRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MetadataRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-xg4IJ", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemoveMetadata(repo.MetadataConditions().MetadataKeyCondition(database.TextOperationEqual, e.Key)),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceUserMetadataRemovedAll(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.MetadataRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-xg4IJ", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.UserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemoveMetadata(nil),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePasskeyAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
var (
|
|
e user.HumanWebAuthNAddedEvent
|
|
typ domain.PasskeyType
|
|
)
|
|
switch typed := event.(type) {
|
|
case *user.HumanPasswordlessAddedEvent:
|
|
e = typed.HumanWebAuthNAddedEvent
|
|
typ = domain.PasskeyTypePasswordless
|
|
case *user.HumanU2FAddedEvent:
|
|
e = typed.HumanWebAuthNAddedEvent
|
|
typ = domain.PasskeyTypeU2F
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-nd7f3", "reduce.wrong.event.type for passkey %s", event.Type())
|
|
}
|
|
return handler.NewStatement(&e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
database.And(
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
),
|
|
repo.AddPasskey(&domain.Passkey{
|
|
ID: e.WebAuthNTokenID,
|
|
Challenge: []byte(e.Challenge),
|
|
RelyingPartyID: e.RPID,
|
|
CreatedAt: e.CreatedAt(),
|
|
UpdatedAt: e.CreatedAt(),
|
|
Type: typ,
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePasskeyVerified(event eventstore.Event) (*handler.Statement, error) {
|
|
var (
|
|
e user.HumanWebAuthNVerifiedEvent
|
|
)
|
|
switch typed := event.(type) {
|
|
case *user.HumanPasswordlessVerifiedEvent:
|
|
e = typed.HumanWebAuthNVerifiedEvent
|
|
case *user.HumanU2FVerifiedEvent:
|
|
e = typed.HumanWebAuthNVerifiedEvent
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-nd7f3", "reduce.wrong.event.type for passkey %s", event.Type())
|
|
}
|
|
return handler.NewStatement(&e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.UpdatePasskey(
|
|
repo.PasskeyConditions().IDCondition(e.WebAuthNTokenID),
|
|
repo.SetPasskeyKeyID(e.KeyID),
|
|
repo.SetPasskeyPublicKey(e.PublicKey),
|
|
repo.SetPasskeyAttestationType(e.AttestationType),
|
|
repo.SetPasskeyAuthenticatorAttestationGUID(e.AAGUID),
|
|
repo.SetPasskeySignCount(e.SignCount),
|
|
repo.SetPasskeyName(e.WebAuthNTokenName),
|
|
repo.SetPasskeyUpdatedAt(e.CreatedAt()),
|
|
),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePasskeySignCountSet(event eventstore.Event) (*handler.Statement, error) {
|
|
var (
|
|
e user.HumanWebAuthNSignCountChangedEvent
|
|
)
|
|
switch typed := event.(type) {
|
|
case *user.HumanPasswordlessSignCountChangedEvent:
|
|
e = typed.HumanWebAuthNSignCountChangedEvent
|
|
case *user.HumanU2FSignCountChangedEvent:
|
|
e = typed.HumanWebAuthNSignCountChangedEvent
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-nd7f3", "reduce.wrong.event.type for passkey %s", event.Type())
|
|
}
|
|
return handler.NewStatement(&e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.UpdatePasskey(
|
|
repo.PasskeyConditions().IDCondition(e.WebAuthNTokenID),
|
|
repo.SetPasskeySignCount(e.SignCount),
|
|
),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePasskeyRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
var (
|
|
e user.HumanWebAuthNRemovedEvent
|
|
)
|
|
switch typed := event.(type) {
|
|
case *user.HumanPasswordlessRemovedEvent:
|
|
e = typed.HumanWebAuthNRemovedEvent
|
|
case *user.HumanU2FRemovedEvent:
|
|
e = typed.HumanWebAuthNRemovedEvent
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-nd7f3", "reduce.wrong.event.type for passkey %s", event.Type())
|
|
}
|
|
return handler.NewStatement(&e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
userRepo := repository.UserRepository()
|
|
humanRepo := userRepo.Human()
|
|
_, err := userRepo.Update(ctx, v3_sql.SQLTx(tx),
|
|
userRepo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
humanRepo.RemovePasskey(humanRepo.PasskeyConditions().IDCondition(e.WebAuthNTokenID)),
|
|
humanRepo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePasskeyInitCodeAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordlessInitCodeAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetVerification(&domain.VerificationTypeInit{
|
|
ID: &e.ID,
|
|
Code: e.Code,
|
|
CreatedAt: e.CreatedAt(),
|
|
Expiry: &e.Expiry,
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePasskeyInitCodeCheckFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordlessInitCodeCheckFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetVerification(&domain.VerificationTypeFailed{
|
|
ID: &e.ID,
|
|
FailedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePasskeyInitCodeCheckSucceeded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordlessInitCodeCheckSucceededEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetVerification(&domain.VerificationTypeSucceeded{
|
|
ID: &e.ID,
|
|
VerifiedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reducePasskeyInitCodeRequested(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordlessInitCodeRequestedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetVerification(&domain.VerificationTypeInit{
|
|
ID: &e.ID,
|
|
Code: e.Code,
|
|
CreatedAt: e.CreatedAt(),
|
|
Expiry: &e.Expiry,
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceMFAInitSkipped(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanMFAInitSkippedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SkipMultifactorInitializationAt(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceIDPLinkAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserIDPLinkAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.AddIdentityProviderLink(&domain.IdentityProviderLink{
|
|
ProviderID: e.IDPConfigID,
|
|
ProvidedUserID: e.ExternalUserID,
|
|
ProvidedUsername: e.DisplayName,
|
|
CreatedAt: e.CreatedAt(),
|
|
UpdatedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceIDPLinkCascadeRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserIDPLinkCascadeRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemoveIdentityProviderLink(e.IDPConfigID, e.ExternalUserID),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceIDPLinkRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserIDPLinkRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemoveIdentityProviderLink(e.IDPConfigID, e.ExternalUserID),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceIDPLinkUserIDMigrated(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserIDPExternalIDMigratedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.UpdateIdentityProviderLink(
|
|
database.And(repo.IdentityProviderLinkConditions().ProviderIDCondition(e.IDPConfigID), repo.IdentityProviderLinkConditions().ProvidedUserIDCondition(e.PreviousID)),
|
|
repo.SetIdentityProviderLinkProvidedID(e.NewID),
|
|
),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceIDPLinkUsernameChanged(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserIDPExternalUsernameEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.UpdateIdentityProviderLink(
|
|
database.And(repo.IdentityProviderLinkConditions().ProviderIDCondition(e.IDPConfigID), repo.IdentityProviderLinkConditions().ProvidedUserIDCondition(e.ExternalUserID)),
|
|
repo.SetIdentityProviderLinkUsername(e.ExternalUsername),
|
|
),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceTOTPAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetTOTPSecret(e.Secret),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceTOTPVerified(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPVerifiedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetTOTPVerifiedAt(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceTOTPRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemoveTOTP(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceTOTPCheckSucceeded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPCheckSucceededEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetLastSuccessfulTOTPCheck(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceTOTPCheckFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPCheckFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.IncrementTOTPFailedAttempts(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceOTPSMSEnabled(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPSMSAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.EnableSMSOTPAt(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceOTPSMSDisabled(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPSMSRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.DisableSMSOTP(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceOTPSMSCheckSucceeded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPSMSCheckSucceededEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetLastSuccessfulSMSOTPCheck(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceOTPSMSCheckFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPSMSCheckFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.IncrementSMSOTPFailedAttempts(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceOTPEmailEnabled(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPEmailAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.EnableEmailOTPAt(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceOTPEmailDisabled(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPEmailRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.DisableEmailOTP(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceOTPEmailCheckSucceeded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPEmailCheckSucceededEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetLastSuccessfulEmailOTPCheck(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceOTPEmailCheckFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanOTPEmailCheckFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.IncrementEmailOTPFailedAttempts(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceInviteCodeAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanInviteCodeAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
|
|
var expiry *time.Duration
|
|
if e.Expiry > 0 {
|
|
expiry = &e.Expiry
|
|
}
|
|
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetInviteVerification(&domain.VerificationTypeInit{
|
|
CreatedAt: e.CreatedAt(),
|
|
Code: e.Code,
|
|
Expiry: expiry,
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceInviteCheckSucceeded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanInviteCheckSucceededEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetInviteVerification(&domain.VerificationTypeSucceeded{
|
|
VerifiedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceInviteCheckFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanInviteCheckFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.SetInviteVerification(&domain.VerificationTypeFailed{
|
|
FailedAt: e.CreatedAt(),
|
|
}),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceRecoveryCodesAdded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanRecoveryCodesAddedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-oqwfuV", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.AddRecoveryCodes(e.Codes),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceRecoveryCodesRemoved(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanRecoveryCodesRemovedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-ZueNKs", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemoveAllRecoveryCodes(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceRecoveryCodeCheckSucceeded(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanRecoveryCodeCheckSucceededEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-wr8WuW", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.RemoveRecoveryCode(e.CodeChecked),
|
|
repo.SetLastSuccessfulRecoveryCodeCheck(e.CreatedAt()),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func (p *relationalTablesProjection) reduceRecoveryCodeCheckFailed(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanRecoveryCodeCheckFailedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error {
|
|
tx, ok := ex.(*sql.Tx)
|
|
if !ok {
|
|
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-mWuV7a", "reduce.wrong.db.pool %T", ex)
|
|
}
|
|
repo := repository.HumanUserRepository()
|
|
_, err := repo.Update(ctx, v3_sql.SQLTx(tx),
|
|
repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID),
|
|
repo.IncrementRecoveryCodeFailedAttempts(),
|
|
repo.SetUpdatedAt(e.CreatedAt()),
|
|
)
|
|
return err
|
|
}), nil
|
|
}
|
|
|
|
func mapHumanGender(gender old_domain.Gender) domain.HumanGender {
|
|
switch gender {
|
|
case old_domain.GenderFemale:
|
|
return domain.HumanGenderFemale
|
|
case old_domain.GenderMale:
|
|
return domain.HumanGenderMale
|
|
case old_domain.GenderDiverse:
|
|
return domain.HumanGenderDiverse
|
|
case old_domain.GenderUnspecified:
|
|
fallthrough
|
|
default:
|
|
return domain.HumanGenderUnspecified
|
|
}
|
|
}
|
|
|
|
func mapMachineAccessTokenType(tokenType old_domain.OIDCTokenType) domain.AccessTokenType {
|
|
switch tokenType {
|
|
case old_domain.OIDCTokenTypeBearer:
|
|
return domain.AccessTokenTypeBearer
|
|
case old_domain.OIDCTokenTypeJWT:
|
|
return domain.AccessTokenTypeJWT
|
|
default:
|
|
return domain.AccessTokenTypeUnspecified
|
|
}
|
|
}
|
|
|
|
func mapMachineKeyType(keyType old_domain.AuthNKeyType) domain.MachineKeyType {
|
|
switch keyType {
|
|
case old_domain.AuthNKeyTypeJSON:
|
|
return domain.MachineKeyTypeJSON
|
|
case old_domain.AuthNKeyTypeNONE:
|
|
fallthrough
|
|
default:
|
|
return domain.MachineKeyTypeNone
|
|
}
|
|
}
|