refactor: merge relational table projections into one handler (#11740)

## 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]>
This commit is contained in:
Silvan
2026-03-10 17:01:46 +00:00
committed by GitHub
co-authored by Marco Ardizzone
parent 689b90d9d9
commit de1cab9976
30 changed files with 4174 additions and 4259 deletions
@@ -367,6 +367,12 @@ func AddNoOpStatement() func(eventstore.Event) Exec {
}
}
func AddStatement(e Exec) func(eventstore.Event) Exec {
return func(event eventstore.Event) Exec {
return NewStatement(event, e).Execute
}
}
func AddCreateStatement(columns []Column, opts ...execOption) func(eventstore.Event) Exec {
return func(event eventstore.Event) Exec {
return NewCreateStatement(event, columns, opts...).Execute
@@ -15,59 +15,7 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
const (
AuthorizationRelationalProjectionTable = "zitadel.authorizations"
)
type authorizationRelationalProjection struct{}
func (*authorizationRelationalProjection) Name() string {
return AuthorizationRelationalProjectionTable
}
func newAuthorizationRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(authorizationRelationalProjection))
}
func (a *authorizationRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: usergrant.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: usergrant.UserGrantAddedType,
Reduce: a.reduceUserGrantAdded,
},
{
Event: usergrant.UserGrantChangedType,
Reduce: a.reduceUserGrantChanged,
},
{
Event: usergrant.UserGrantCascadeChangedType,
Reduce: a.reduceUserGrantChanged,
},
{
Event: usergrant.UserGrantCascadeRemovedType,
Reduce: a.reduceUserGrantRemoved,
},
{
Event: usergrant.UserGrantRemovedType,
Reduce: a.reduceUserGrantRemoved,
},
{
Event: usergrant.UserGrantDeactivatedType,
Reduce: a.reduceUserGrantDeactivated,
},
{
Event: usergrant.UserGrantReactivatedType,
Reduce: a.reduceUserGrantReactivated,
},
},
},
}
}
func (a *authorizationRelationalProjection) reduceUserGrantAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceAuthorizationAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*usergrant.UserGrantAddedEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-an0k9a", "reduce.wrong.event.type %s", usergrant.UserGrantAddedType)
@@ -97,7 +45,7 @@ func (a *authorizationRelationalProjection) reduceUserGrantAdded(event eventstor
}), nil
}
func (a *authorizationRelationalProjection) reduceUserGrantChanged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceAuthorizationChanged(event eventstore.Event) (*handler.Statement, error) {
var roles []string
switch e := event.(type) {
case *usergrant.UserGrantChangedEvent:
@@ -124,7 +72,7 @@ func (a *authorizationRelationalProjection) reduceUserGrantChanged(event eventst
}), nil
}
func (a *authorizationRelationalProjection) reduceUserGrantRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceAuthorizationRemoved(event eventstore.Event) (*handler.Statement, error) {
switch event.(type) {
case *usergrant.UserGrantRemovedEvent, *usergrant.UserGrantCascadeRemovedEvent:
// ok
@@ -145,7 +93,7 @@ func (a *authorizationRelationalProjection) reduceUserGrantRemoved(event eventst
}), nil
}
func (a *authorizationRelationalProjection) reduceUserGrantDeactivated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceAuthorizationDeactivated(event eventstore.Event) (*handler.Statement, error) {
_, ok := event.(*usergrant.UserGrantDeactivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-dFtRl0", "reduce.wrong.event.type %s", usergrant.UserGrantDeactivatedType)
@@ -166,7 +114,7 @@ func (a *authorizationRelationalProjection) reduceUserGrantDeactivated(event eve
}), nil
}
func (a *authorizationRelationalProjection) reduceUserGrantReactivated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceAuthorizationReactivated(event eventstore.Event) (*handler.Statement, error) {
_, ok := event.(*usergrant.UserGrantReactivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-dFtRl1", "reduce.wrong.event.type %s", usergrant.UserGrantReactivatedType)
@@ -0,0 +1,145 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceAppleIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.AppleIDPAddedEvent
switch e := event.(type) {
case *org.AppleIDPAddedEvent:
idpEvent = e.AppleIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.AppleIDPAddedEvent:
idpEvent = e.AppleIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YFvg3", "reduce.wrong.event.type %v", []eventstore.EventType{org.AppleIDPAddedEventType /*, instance.AppleIDPAddedEventType*/})
}
apple := domain.Apple{
ClientID: idpEvent.ClientID,
TeamID: idpEvent.TeamID,
KeyID: idpEvent.KeyID,
PrivateKey: idpEvent.PrivateKey,
Scopes: idpEvent.Scopes,
}
payloadJSON, err := json.Marshal(apple)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-Ku2YB", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeApple),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceAppleIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.AppleIDPChangedEvent
switch e := event.(type) {
case *org.AppleIDPChangedEvent:
idpEvent = e.AppleIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.AppleIDPChangedEvent:
idpEvent = e.AppleIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YBez3", "reduce.wrong.event.type %v", []eventstore.EventType{org.AppleIDPChangedEventType /*, instance.AppleIDPChangedEventType*/})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
apple, err := idpRepo.GetApple(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &apple.Apple
payloadChanged := p.reduceAppleIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceAppleIDPChangedColumns(payload *domain.Apple, idpEvent *idp.AppleIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.TeamID != nil && *idpEvent.TeamID != payload.TeamID {
payloadChanged = true
payload.TeamID = *idpEvent.TeamID
}
if idpEvent.KeyID != nil && *idpEvent.KeyID != payload.KeyID {
payloadChanged = true
payload.KeyID = *idpEvent.KeyID
}
if idpEvent.PrivateKey != nil {
payloadChanged = true
payload.PrivateKey = idpEvent.PrivateKey
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
return payloadChanged
}
@@ -0,0 +1,215 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceOIDCIDPMigratedAzureAD(event eventstore.Event) (*handler.Statement, error) {
var orgID *string
var idpEvent idp.OIDCIDPMigratedAzureADEvent
switch e := event.(type) {
case *org.OIDCIDPMigratedAzureADEvent:
idpEvent = e.OIDCIDPMigratedAzureADEvent
orgID = gu.Ptr(idpEvent.Aggregate().ResourceOwner)
case *instance.OIDCIDPMigratedAzureADEvent:
idpEvent = e.OIDCIDPMigratedAzureADEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Yb582ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.OIDCIDPMigratedAzureADEventType, instance.OIDCIDPMigratedAzureADEventType})
}
azureTenant, err := domain.AzureTenantTypeString(idpEvent.Tenant)
if err != nil {
return nil, err
}
azure := domain.Azure{
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
Scopes: idpEvent.Scopes,
Tenant: azureTenant,
IsEmailVerified: idpEvent.IsEmailVerified,
}
payloadJSON, err := json.Marshal(azure)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-mj7LQ", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
changes := database.Changes{
repo.SetName(idpEvent.Name),
repo.SetType(domain.IDPTypeAzure),
repo.SetAllowCreation(idpEvent.IsCreationAllowed),
repo.SetAllowLinking(idpEvent.IsLinkingAllowed),
repo.SetAllowAutoCreation(idpEvent.IsAutoCreation),
repo.SetAllowAutoUpdate(idpEvent.IsAutoUpdate),
repo.SetAutoLinkingField(mapAutoLinkingField(idpEvent.AutoLinkingOption)),
repo.SetPayload(string(payloadJSON)),
repo.SetUpdatedAt(gu.Ptr(event.CreatedAt())),
}
_, err = repo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(repo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgID), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceAzureADIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.AzureADIDPAddedEvent
switch e := event.(type) {
case *org.AzureADIDPAddedEvent:
idpEvent = e.AzureADIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.AzureADIDPAddedEvent:
idpEvent = e.AzureADIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y9a022b", "reduce.wrong.event.type %v", []eventstore.EventType{org.AzureADIDPAddedEventType, instance.AzureADIDPAddedEventType})
}
azureTenant, err := domain.AzureTenantTypeString(idpEvent.Tenant)
if err != nil {
return nil, err
}
azure := domain.Azure{
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
Scopes: idpEvent.Scopes,
Tenant: azureTenant,
IsEmailVerified: idpEvent.IsEmailVerified,
}
payloadJSON, err := json.Marshal(azure)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-GJ4Kb", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeAzure),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceAzureADIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.AzureADIDPChangedEvent
switch e := event.(type) {
case *org.AzureADIDPChangedEvent:
idpEvent = e.AzureADIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.AzureADIDPChangedEvent:
idpEvent = e.AzureADIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YZ5x25s", "reduce.wrong.event.type %v", []eventstore.EventType{org.AzureADIDPChangedEventType, instance.AzureADIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
azure, err := idpRepo.GetAzureAD(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &azure.Azure
payloadChanged, err := p.reduceAzureADIDPChangedColumns(payload, &idpEvent)
if err != nil {
return err
}
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceAzureADIDPChangedColumns(payload *domain.Azure, idpEvent *idp.AzureADIDPChangedEvent) (bool, error) {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged, nil
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
payloadChanged = true
payload.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
if idpEvent.Tenant != nil && *idpEvent.Tenant != payload.Tenant.String() {
payloadChanged = true
azureTenant, err := domain.AzureTenantTypeString(*idpEvent.Tenant)
if err != nil {
return false, err
}
payload.Tenant = azureTenant
}
if idpEvent.IsEmailVerified != nil && *idpEvent.IsEmailVerified != payload.IsEmailVerified {
payloadChanged = true
payload.IsEmailVerified = *idpEvent.IsEmailVerified
}
return payloadChanged, nil
}
@@ -0,0 +1,264 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceGitHubIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GitHubIDPAddedEvent
switch e := event.(type) {
case *org.GitHubIDPAddedEvent:
idpEvent = e.GitHubIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GitHubIDPAddedEvent:
idpEvent = e.GitHubIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-x9a022b", "reduce.wrong.event.type %v", []eventstore.EventType{org.GitHubIDPAddedEventType, instance.GitHubIDPAddedEventType})
}
github := domain.Github{
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
Scopes: idpEvent.Scopes,
}
payloadJSON, err := json.Marshal(github)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-HNpgd", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeGitHub),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceGitHubIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GitHubIDPChangedEvent
switch e := event.(type) {
case *org.GitHubIDPChangedEvent:
idpEvent = e.GitHubIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GitHubIDPChangedEvent:
idpEvent = e.GitHubIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-L1U89ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.GitHubIDPChangedEventType, instance.GitHubIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
github, err := idpRepo.GetGithub(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &github.Github
payloadChanged := p.reduceGitHubIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceGitHubEnterpriseIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GitHubEnterpriseIDPAddedEvent
switch e := event.(type) {
case *org.GitHubEnterpriseIDPAddedEvent:
idpEvent = e.GitHubEnterpriseIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GitHubEnterpriseIDPAddedEvent:
idpEvent = e.GitHubEnterpriseIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Yf3g2a", "reduce.wrong.event.type %v", []eventstore.EventType{org.GitHubEnterpriseIDPAddedEventType, instance.GitHubEnterpriseIDPAddedEventType})
}
githubEnterprise := domain.GithubEnterprise{
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
AuthorizationEndpoint: idpEvent.AuthorizationEndpoint,
TokenEndpoint: idpEvent.TokenEndpoint,
UserEndpoint: idpEvent.UserEndpoint,
Scopes: idpEvent.Scopes,
}
payloadJSON, err := json.Marshal(githubEnterprise)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-Kv4Fu", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeGitHubEnterprise),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceGitHubEnterpriseIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GitHubEnterpriseIDPChangedEvent
switch e := event.(type) {
case *org.GitHubEnterpriseIDPChangedEvent:
idpEvent = e.GitHubEnterpriseIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GitHubEnterpriseIDPChangedEvent:
idpEvent = e.GitHubEnterpriseIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YDg3g", "reduce.wrong.event.type %v", []eventstore.EventType{org.GitHubEnterpriseIDPChangedEventType, instance.GitHubEnterpriseIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
githubEnterprise, err := idpRepo.GetGithubEnterprise(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &githubEnterprise.GithubEnterprise
payloadChanged := p.reduceGitHubEnterpriseIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceGitHubIDPChangedColumns(payload *domain.Github, idpEvent *idp.GitHubIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
payloadChanged = true
payload.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
return payloadChanged
}
func (p *relationalTablesProjection) reduceGitHubEnterpriseIDPChangedColumns(payload *domain.GithubEnterprise, idpEvent *idp.GitHubEnterpriseIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
payloadChanged = true
payload.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.AuthorizationEndpoint != nil && *idpEvent.AuthorizationEndpoint != payload.AuthorizationEndpoint {
payloadChanged = true
payload.AuthorizationEndpoint = *idpEvent.AuthorizationEndpoint
}
if idpEvent.TokenEndpoint != nil && *idpEvent.TokenEndpoint != payload.TokenEndpoint {
payloadChanged = true
payload.TokenEndpoint = *idpEvent.TokenEndpoint
}
if idpEvent.UserEndpoint != nil && *idpEvent.UserEndpoint != payload.UserEndpoint {
payloadChanged = true
payload.UserEndpoint = *idpEvent.UserEndpoint
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
return payloadChanged
}
@@ -0,0 +1,254 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceGitLabIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GitLabIDPAddedEvent
switch e := event.(type) {
case *org.GitLabIDPAddedEvent:
idpEvent = e.GitLabIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GitLabIDPAddedEvent:
idpEvent = e.GitLabIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y9a022b", "reduce.wrong.event.type %v", []eventstore.EventType{org.GitLabIDPAddedEventType, instance.GitLabIDPAddedEventType})
}
gitlab := domain.Gitlab{
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
Scopes: idpEvent.Scopes,
}
payloadJSON, err := json.Marshal(gitlab)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-kN8Qx", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeGitLab),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceGitLabIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GitLabIDPChangedEvent
switch e := event.(type) {
case *org.GitLabIDPChangedEvent:
idpEvent = e.GitLabIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GitLabIDPChangedEvent:
idpEvent = e.GitLabIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-mT5827b", "reduce.wrong.event.type %v", []eventstore.EventType{org.GitLabIDPChangedEventType, instance.GitLabIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
gitlab, err := idpRepo.GetGitlab(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &gitlab.Gitlab
payloadChanged := p.reduceGitLabIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceGitLabSelfHostedIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GitLabSelfHostedIDPAddedEvent
switch e := event.(type) {
case *org.GitLabSelfHostedIDPAddedEvent:
idpEvent = e.GitLabSelfHostedIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GitLabSelfHostedIDPAddedEvent:
idpEvent = e.GitLabSelfHostedIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YAF3gw", "reduce.wrong.event.type %v", []eventstore.EventType{org.GitLabSelfHostedIDPAddedEventType, instance.GitLabSelfHostedIDPAddedEventType})
}
gitlabSelfHosted := domain.GitlabSelfHosted{
Issuer: idpEvent.Issuer,
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
Scopes: idpEvent.Scopes,
}
payloadJSON, err := json.Marshal(gitlabSelfHosted)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-FQrtw", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeGitLabSelfHosted),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceGitLabSelfHostedIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GitLabSelfHostedIDPChangedEvent
switch e := event.(type) {
case *org.GitLabSelfHostedIDPChangedEvent:
idpEvent = e.GitLabSelfHostedIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GitLabSelfHostedIDPChangedEvent:
idpEvent = e.GitLabSelfHostedIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YAf3g2", "reduce.wrong.event.type %v", []eventstore.EventType{org.GitLabSelfHostedIDPChangedEventType, instance.GitLabSelfHostedIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
gitlabSelfHosted, err := idpRepo.GetGitlabSelfHosted(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &gitlabSelfHosted.GitlabSelfHosted
payloadChanged := p.reduceGitLabSelfHostedIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceGitLabIDPChangedColumns(payload *domain.Gitlab, idpEvent *idp.GitLabIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
payloadChanged = true
payload.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
return payloadChanged
}
func (p *relationalTablesProjection) reduceGitLabSelfHostedIDPChangedColumns(payload *domain.GitlabSelfHosted, idpEvent *idp.GitLabSelfHostedIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
payloadChanged = true
payload.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.Issuer != nil && *idpEvent.Issuer != payload.Issuer {
payloadChanged = true
payload.Issuer = *idpEvent.Issuer
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
return payloadChanged
}
@@ -0,0 +1,183 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceOIDCIDPMigratedGoogle(event eventstore.Event) (*handler.Statement, error) {
var orgID *string
var idpEvent idp.OIDCIDPMigratedGoogleEvent
switch e := event.(type) {
case *org.OIDCIDPMigratedGoogleEvent:
idpEvent = e.OIDCIDPMigratedGoogleEvent
orgID = gu.Ptr(idpEvent.Aggregate().ResourceOwner)
case *instance.OIDCIDPMigratedGoogleEvent:
idpEvent = e.OIDCIDPMigratedGoogleEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y1502hk", "reduce.wrong.event.type %v", []eventstore.EventType{org.OIDCIDPMigratedGoogleEventType, instance.OIDCIDPMigratedGoogleEventType})
}
google := domain.Google{
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
Scopes: idpEvent.Scopes,
}
payloadJSON, err := json.Marshal(google)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-HDqk9", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
changes := database.Changes{
repo.SetName(idpEvent.Name),
repo.SetType(domain.IDPTypeGoogle),
repo.SetAllowCreation(idpEvent.IsCreationAllowed),
repo.SetAllowLinking(idpEvent.IsLinkingAllowed),
repo.SetAllowAutoCreation(idpEvent.IsAutoCreation),
repo.SetAllowAutoUpdate(idpEvent.IsAutoUpdate),
repo.SetAutoLinkingField(mapAutoLinkingField(idpEvent.AutoLinkingOption)),
repo.SetPayload(string(payloadJSON)),
repo.SetUpdatedAt(gu.Ptr(event.CreatedAt())),
}
_, err = repo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(repo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgID), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceGoogleIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GoogleIDPAddedEvent
switch e := event.(type) {
case *org.GoogleIDPAddedEvent:
idpEvent = e.GoogleIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GoogleIDPAddedEvent:
idpEvent = e.GoogleIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Yp9ihb", "reduce.wrong.event.type %v", []eventstore.EventType{org.GoogleIDPAddedEventType, instance.GoogleIDPAddedEventType})
}
google := domain.Google{
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
Scopes: idpEvent.Scopes,
}
payloadJSON, err := json.Marshal(google)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-B9SPm", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeGoogle),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceGoogleIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.GoogleIDPChangedEvent
switch e := event.(type) {
case *org.GoogleIDPChangedEvent:
idpEvent = e.GoogleIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.GoogleIDPChangedEvent:
idpEvent = e.GoogleIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YN58hml", "reduce.wrong.event.type %v", []eventstore.EventType{org.GoogleIDPChangedEventType, instance.GoogleIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
google, err := idpRepo.GetGoogle(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &google.Google
payloadChanged := p.reduceGoogleIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceGoogleIDPChangedColumns(payload *domain.Google, idpEvent *idp.GoogleIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
payloadChanged = true
payload.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
return payloadChanged
}
@@ -15,40 +15,7 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
const (
IDPIntentRelationalProjectionTable = "zitadel.identity_provider_intents"
)
type idpIntentRelationalProjection struct{}
func (*idpIntentRelationalProjection) Name() string {
return IDPIntentRelationalProjectionTable
}
func newIDPIntentRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(idpIntentRelationalProjection))
}
// Reducers implements [handler.Projection].
func (i *idpIntentRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: idpintent.AggregateType,
EventReducers: []handler.EventReducer{
{Event: idpintent.StartedEventType, Reduce: i.reduceStartedEvent},
{Event: idpintent.SucceededEventType, Reduce: i.reduceSucceededEvent},
{Event: idpintent.SAMLSucceededEventType, Reduce: i.reduceSAMLSucceededEvent},
{Event: idpintent.SAMLRequestEventType, Reduce: i.reduceSAMLRequestEvent},
{Event: idpintent.LDAPSucceededEventType, Reduce: i.reduceLDAPSucceededEvent},
{Event: idpintent.FailedEventType, Reduce: i.reduceFailedEvent},
{Event: idpintent.ConsumedEventType, Reduce: i.reduceConsumedEvent},
},
},
}
}
func (i *idpIntentRelationalProjection) reduceStartedEvent(evt eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceIDPIntentStartedEvent(evt eventstore.Event) (*handler.Statement, error) {
e, ok := evt.(*idpintent.StartedEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-Lqj3HB", "reduce.wrong.event.type %s", idpintent.StartedEventType)
@@ -74,7 +41,7 @@ func (i *idpIntentRelationalProjection) reduceStartedEvent(evt eventstore.Event)
}), nil
}
func (i *idpIntentRelationalProjection) reduceSucceededEvent(evt eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceIDPIntentSucceededEvent(evt eventstore.Event) (*handler.Statement, error) {
e, ok := evt.(*idpintent.SucceededEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-hQSxj0", "reduce.wrong.event.type %s", idpintent.SucceededEventType)
@@ -116,7 +83,7 @@ func (i *idpIntentRelationalProjection) reduceSucceededEvent(evt eventstore.Even
}), nil
}
func (i *idpIntentRelationalProjection) reduceSAMLSucceededEvent(evt eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceIDPIntentSAMLSucceededEvent(evt eventstore.Event) (*handler.Statement, error) {
e, ok := evt.(*idpintent.SAMLSucceededEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-t2uaiv", "reduce.wrong.event.type %s", idpintent.SAMLSucceededEventType)
@@ -153,7 +120,7 @@ func (i *idpIntentRelationalProjection) reduceSAMLSucceededEvent(evt eventstore.
}), nil
}
func (i *idpIntentRelationalProjection) reduceSAMLRequestEvent(evt eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceIDPIntentSAMLRequestEvent(evt eventstore.Event) (*handler.Statement, error) {
e, ok := evt.(*idpintent.SAMLRequestEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-f7O6K2", "reduce.wrong.event.type %s", idpintent.SAMLRequestEventType)
@@ -175,7 +142,7 @@ func (i *idpIntentRelationalProjection) reduceSAMLRequestEvent(evt eventstore.Ev
}), nil
}
func (i *idpIntentRelationalProjection) reduceLDAPSucceededEvent(evt eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceIDPIntentLDAPSucceededEvent(evt eventstore.Event) (*handler.Statement, error) {
e, ok := evt.(*idpintent.LDAPSucceededEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-Gw8ddW", "reduce.wrong.event.type %s", idpintent.LDAPSucceededEventType)
@@ -209,7 +176,7 @@ func (i *idpIntentRelationalProjection) reduceLDAPSucceededEvent(evt eventstore.
}), nil
}
func (i *idpIntentRelationalProjection) reduceFailedEvent(evt eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceIDPIntentFailedEvent(evt eventstore.Event) (*handler.Statement, error) {
e, ok := evt.(*idpintent.FailedEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-x3o9LZ", "reduce.wrong.event.type %s", idpintent.FailedEventType)
@@ -233,7 +200,7 @@ func (i *idpIntentRelationalProjection) reduceFailedEvent(evt eventstore.Event)
}), nil
}
func (i *idpIntentRelationalProjection) reduceConsumedEvent(evt eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceIDPIntentConsumedEvent(evt eventstore.Event) (*handler.Statement, error) {
e, ok := evt.(*idpintent.ConsumedEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-jHZs6T", "reduce.wrong.event.type %s", idpintent.ConsumedEventType)
@@ -0,0 +1,225 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/idpconfig"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceJWTConfigAdded(event eventstore.Event) (*handler.Statement, error) {
var orgID *string
var idpEvent idpconfig.JWTConfigAddedEvent
switch e := event.(type) {
case *org.IDPJWTConfigAddedEvent:
idpEvent = e.JWTConfigAddedEvent
orgID = gu.Ptr(idpEvent.Aggregate().ResourceOwner)
case *instance.IDPJWTConfigAddedEvent:
idpEvent = e.JWTConfigAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YvPdb", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPJWTConfigAddedEventType, instance.IDPJWTConfigAddedEventType})
}
payloadJSON, err := json.Marshal(idpEvent)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-tJQ8V", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
_, err = repo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(repo, idpEvent.Aggregate().InstanceID, idpEvent.IDPConfigID, orgID),
repo.SetPayload(string(payloadJSON)),
repo.SetType(domain.IDPTypeJWT),
repo.SetUpdatedAt(gu.Ptr(event.CreatedAt())),
)
return err
}), nil
}
func (p *relationalTablesProjection) reduceJWTConfigChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idpconfig.JWTConfigChangedEvent
switch e := event.(type) {
case *org.IDPJWTConfigChangedEvent:
idpEvent = e.JWTConfigChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.IDPJWTConfigChangedEvent:
idpEvent = e.JWTConfigChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y2IVI", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPJWTConfigChangedEventType, instance.IDPJWTConfigChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-sh6Lp", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
jwt, err := idpRepo.GetJWT(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.IDPConfigID, orgId)))
if err != nil {
return err
}
if idpEvent.JWTEndpoint != nil && *idpEvent.JWTEndpoint != jwt.JWTEndpoint {
jwt.JWTEndpoint = *idpEvent.JWTEndpoint
}
if idpEvent.Issuer != nil && *idpEvent.Issuer != jwt.Issuer {
jwt.Issuer = *idpEvent.Issuer
}
if idpEvent.KeysEndpoint != nil && *idpEvent.KeysEndpoint != jwt.KeysEndpoint {
jwt.KeysEndpoint = *idpEvent.KeysEndpoint
}
if idpEvent.HeaderName != nil && *idpEvent.HeaderName != jwt.HeaderName {
jwt.HeaderName = *idpEvent.HeaderName
}
payloadJSON, err := json.Marshal(jwt.JWT)
if err != nil {
return err
}
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.IDPConfigID, orgId),
idpRepo.SetPayload(string(payloadJSON)),
idpRepo.SetType(domain.IDPTypeJWT),
idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())),
)
return err
}), nil
}
func (p *relationalTablesProjection) reduceJWTIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.JWTIDPAddedEvent
switch e := event.(type) {
case *org.JWTIDPAddedEvent:
idpEvent = e.JWTIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.JWTIDPAddedEvent:
idpEvent = e.JWTIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Yopi2s", "reduce.wrong.event.type %v", []eventstore.EventType{org.JWTIDPAddedEventType, instance.JWTIDPAddedEventType})
}
jwt := domain.JWT{
JWTEndpoint: idpEvent.JWTEndpoint,
Issuer: idpEvent.Issuer,
KeysEndpoint: idpEvent.KeysEndpoint,
HeaderName: idpEvent.HeaderName,
}
payloadJSON, err := json.Marshal(jwt)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-ZYYyQ", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeJWT),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceJWTIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.JWTIDPChangedEvent
switch e := event.(type) {
case *org.JWTIDPChangedEvent:
idpEvent = e.JWTIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.JWTIDPChangedEvent:
idpEvent = e.JWTIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-H15j2il", "reduce.wrong.event.type %v", []eventstore.EventType{org.JWTIDPChangedEventType, instance.JWTIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
jwt, err := idpRepo.GetJWT(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &jwt.JWT
payloadChanged := p.reduceJWTIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceJWTIDPChangedColumns(payload *domain.JWT, idpEvent *idp.JWTIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.JWTEndpoint != nil && *idpEvent.JWTEndpoint != payload.JWTEndpoint {
payloadChanged = true
payload.JWTEndpoint = *idpEvent.JWTEndpoint
}
if idpEvent.KeysEndpoint != nil && *idpEvent.KeysEndpoint != payload.KeysEndpoint {
payloadChanged = true
payload.KeysEndpoint = *idpEvent.KeysEndpoint
}
if idpEvent.HeaderName != nil && *idpEvent.HeaderName != payload.HeaderName {
payloadChanged = true
payload.HeaderName = *idpEvent.HeaderName
}
if idpEvent.Issuer != nil && *idpEvent.Issuer != payload.Issuer {
payloadChanged = true
payload.Issuer = *idpEvent.Issuer
}
return payloadChanged
}
@@ -0,0 +1,237 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceLDAPIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.LDAPIDPAddedEvent
switch e := event.(type) {
case *org.LDAPIDPAddedEvent:
idpEvent = e.LDAPIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.LDAPIDPAddedEvent:
idpEvent = e.LDAPIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-9s02m1", "reduce.wrong.event.type %v", []eventstore.EventType{org.LDAPIDPAddedEventType, instance.LDAPIDPAddedEventType})
}
ldap := domain.LDAP{
Servers: idpEvent.Servers,
StartTLS: idpEvent.StartTLS,
BaseDN: idpEvent.BaseDN,
BindDN: idpEvent.BindDN,
BindPassword: idpEvent.BindPassword,
UserBase: idpEvent.UserBase,
UserObjectClasses: idpEvent.UserObjectClasses,
UserFilters: idpEvent.UserFilters,
Timeout: idpEvent.Timeout,
LDAPAttributes: domain.LDAPAttributes{
IDAttribute: idpEvent.IDAttribute,
FirstNameAttribute: idpEvent.FirstNameAttribute,
LastNameAttribute: idpEvent.LastNameAttribute,
DisplayNameAttribute: idpEvent.DisplayNameAttribute,
NickNameAttribute: idpEvent.NickNameAttribute,
PreferredUsernameAttribute: idpEvent.PreferredUsernameAttribute,
EmailAttribute: idpEvent.EmailAttribute,
EmailVerifiedAttribute: idpEvent.EmailVerifiedAttribute,
PhoneAttribute: idpEvent.PhoneAttribute,
PhoneVerifiedAttribute: idpEvent.PhoneVerifiedAttribute,
PreferredLanguageAttribute: idpEvent.PreferredLanguageAttribute,
AvatarURLAttribute: idpEvent.AvatarURLAttribute,
ProfileAttribute: idpEvent.ProfileAttribute,
},
}
payloadJSON, err := json.Marshal(ldap)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-XCJ8w", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeLDAP),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceLDAPIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.LDAPIDPChangedEvent
switch e := event.(type) {
case *org.LDAPIDPChangedEvent:
idpEvent = e.LDAPIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.LDAPIDPChangedEvent:
idpEvent = e.LDAPIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-p1582ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.LDAPIDPChangedEventType, instance.LDAPIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
ldap, err := idpRepo.GetLDAP(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &ldap.LDAP
payloadChanged := p.reduceLDAPIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
//nolint:gocognit
func (p *relationalTablesProjection) reduceLDAPIDPChangedColumns(payload *domain.LDAP, idpEvent *idp.LDAPIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.Servers != nil && !slices.Equal(idpEvent.Servers, payload.Servers) {
payloadChanged = true
payload.Servers = idpEvent.Servers
}
if idpEvent.StartTLS != nil && *idpEvent.StartTLS != payload.StartTLS {
payloadChanged = true
payload.StartTLS = *idpEvent.StartTLS
}
if idpEvent.BaseDN != nil && *idpEvent.BaseDN != payload.BaseDN {
payloadChanged = true
payload.BaseDN = *idpEvent.BaseDN
}
if idpEvent.BindDN != nil && *idpEvent.BindDN != payload.BindDN {
payloadChanged = true
payload.BindDN = *idpEvent.BindDN
}
if idpEvent.BindPassword != nil {
payloadChanged = true
payload.BindPassword = idpEvent.BindPassword
}
if idpEvent.UserBase != nil && *idpEvent.UserBase != payload.UserBase {
payloadChanged = true
payload.UserBase = *idpEvent.UserBase
}
if idpEvent.UserObjectClasses != nil && !slices.Equal(idpEvent.UserObjectClasses, payload.UserObjectClasses) {
payloadChanged = true
payload.UserObjectClasses = idpEvent.UserObjectClasses
}
if idpEvent.UserFilters != nil && !slices.Equal(idpEvent.UserFilters, payload.UserFilters) {
payloadChanged = true
payload.UserFilters = idpEvent.UserFilters
}
if idpEvent.Timeout != nil && *idpEvent.Timeout != payload.Timeout {
payloadChanged = true
payload.Timeout = *idpEvent.Timeout
}
if idpEvent.RootCA != nil && !slices.Equal(idpEvent.RootCA, payload.RootCA) {
payloadChanged = true
payload.RootCA = idpEvent.RootCA
}
if idpEvent.IDAttribute != nil && *idpEvent.IDAttribute != payload.IDAttribute {
payloadChanged = true
payload.IDAttribute = *idpEvent.IDAttribute
}
if idpEvent.FirstNameAttribute != nil && *idpEvent.FirstNameAttribute != payload.FirstNameAttribute {
payloadChanged = true
payload.FirstNameAttribute = *idpEvent.FirstNameAttribute
}
if idpEvent.LastNameAttribute != nil && *idpEvent.LastNameAttribute != payload.LastNameAttribute {
payloadChanged = true
payload.LastNameAttribute = *idpEvent.LastNameAttribute
}
if idpEvent.DisplayNameAttribute != nil && *idpEvent.DisplayNameAttribute != payload.DisplayNameAttribute {
payloadChanged = true
payload.DisplayNameAttribute = *idpEvent.DisplayNameAttribute
}
if idpEvent.NickNameAttribute != nil && *idpEvent.NickNameAttribute != payload.NickNameAttribute {
payloadChanged = true
payload.NickNameAttribute = *idpEvent.NickNameAttribute
}
if idpEvent.PreferredUsernameAttribute != nil && *idpEvent.PreferredUsernameAttribute != payload.PreferredUsernameAttribute {
payloadChanged = true
payload.PreferredUsernameAttribute = *idpEvent.PreferredUsernameAttribute
}
if idpEvent.EmailAttribute != nil && *idpEvent.EmailAttribute != payload.EmailAttribute {
payloadChanged = true
payload.EmailAttribute = *idpEvent.EmailAttribute
}
if idpEvent.EmailVerifiedAttribute != nil && *idpEvent.EmailVerifiedAttribute != payload.EmailVerifiedAttribute {
payloadChanged = true
payload.EmailVerifiedAttribute = *idpEvent.EmailVerifiedAttribute
}
if idpEvent.PhoneAttribute != nil && *idpEvent.PhoneAttribute != payload.PhoneAttribute {
payloadChanged = true
payload.PhoneAttribute = *idpEvent.PhoneAttribute
}
if idpEvent.PhoneVerifiedAttribute != nil && *idpEvent.PhoneVerifiedAttribute != payload.PhoneVerifiedAttribute {
payloadChanged = true
payload.PhoneVerifiedAttribute = *idpEvent.PhoneVerifiedAttribute
}
if idpEvent.PreferredLanguageAttribute != nil && *idpEvent.PreferredLanguageAttribute != payload.PreferredLanguageAttribute {
payloadChanged = true
payload.PreferredLanguageAttribute = *idpEvent.PreferredLanguageAttribute
}
if idpEvent.AvatarURLAttribute != nil && *idpEvent.AvatarURLAttribute != payload.AvatarURLAttribute {
payloadChanged = true
payload.AvatarURLAttribute = *idpEvent.AvatarURLAttribute
}
if idpEvent.ProfileAttribute != nil && *idpEvent.ProfileAttribute != payload.ProfileAttribute {
payloadChanged = true
payload.ProfileAttribute = *idpEvent.ProfileAttribute
}
return payloadChanged
}
@@ -0,0 +1,160 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceOAuthIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.OAuthIDPAddedEvent
switch e := event.(type) {
case *org.OAuthIDPAddedEvent:
idpEvent = e.OAuthIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.OAuthIDPAddedEvent:
idpEvent = e.OAuthIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Yap9ihb", "reduce.wrong.event.type %v", []eventstore.EventType{org.OAuthIDPAddedEventType, instance.OAuthIDPAddedEventType})
}
oauth := domain.OAuth{
ClientID: idpEvent.ClientID,
ClientSecret: idpEvent.ClientSecret,
AuthorizationEndpoint: idpEvent.AuthorizationEndpoint,
TokenEndpoint: idpEvent.TokenEndpoint,
UserEndpoint: idpEvent.UserEndpoint,
Scopes: idpEvent.Scopes,
IDAttribute: idpEvent.IDAttribute,
UsePKCE: idpEvent.UsePKCE,
}
payloadJSON, err := json.Marshal(oauth)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-mB2hq", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeOAuth),
AllowCreation: idpEvent.IsCreationAllowed,
AllowLinking: idpEvent.IsLinkingAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceOAuthIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.OAuthIDPChangedEvent
switch e := event.(type) {
case *org.OAuthIDPChangedEvent:
idpEvent = e.OAuthIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.OAuthIDPChangedEvent:
idpEvent = e.OAuthIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-K1582ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.OAuthIDPChangedEventType, instance.OAuthIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
oauth, err := idpRepo.GetOAuth(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &oauth.OAuth
payloadChanged := p.reduceOAuthIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceOAuthIDPChangedColumns(payload *domain.OAuth, idpEvent *idp.OAuthIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
payloadChanged = true
payload.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.AuthorizationEndpoint != nil && *idpEvent.AuthorizationEndpoint != payload.AuthorizationEndpoint {
payloadChanged = true
payload.AuthorizationEndpoint = *idpEvent.AuthorizationEndpoint
}
if idpEvent.TokenEndpoint != nil && *idpEvent.TokenEndpoint != payload.TokenEndpoint {
payloadChanged = true
payload.TokenEndpoint = *idpEvent.TokenEndpoint
}
if idpEvent.UserEndpoint != nil && *idpEvent.UserEndpoint != payload.UserEndpoint {
payloadChanged = true
payload.UserEndpoint = *idpEvent.UserEndpoint
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
if idpEvent.IDAttribute != nil && *idpEvent.IDAttribute != payload.IDAttribute {
payloadChanged = true
payload.IDAttribute = *idpEvent.IDAttribute
}
if idpEvent.UsePKCE != nil && *idpEvent.UsePKCE != payload.UsePKCE {
payloadChanged = true
payload.UsePKCE = *idpEvent.UsePKCE
}
return payloadChanged
}
@@ -0,0 +1,253 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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"
internal_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/idp"
"github.com/zitadel/zitadel/internal/repository/idpconfig"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceOIDCConfigAdded(event eventstore.Event) (*handler.Statement, error) {
var orgID *string
var idpEvent idpconfig.OIDCConfigAddedEvent
switch e := event.(type) {
case *org.IDPOIDCConfigAddedEvent:
idpEvent = e.OIDCConfigAddedEvent
orgID = gu.Ptr(idpEvent.Aggregate().ResourceOwner)
case *instance.IDPOIDCConfigAddedEvent:
idpEvent = e.OIDCConfigAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YFuAA", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPOIDCConfigAddedEventType, instance.IDPOIDCConfigAddedEventType})
}
payloadJSON, err := json.Marshal(idpEvent)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-5cvzY", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
_, err = repo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(repo, idpEvent.Aggregate().InstanceID, idpEvent.IDPConfigID, orgID),
repo.SetPayload(string(payloadJSON)),
repo.SetType(domain.IDPTypeOIDC),
repo.SetUpdatedAt(gu.Ptr(event.CreatedAt())),
)
return err
}), nil
}
func (p *relationalTablesProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idpconfig.OIDCConfigChangedEvent
switch e := event.(type) {
case *org.IDPOIDCConfigChangedEvent:
idpEvent = e.OIDCConfigChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.IDPOIDCConfigChangedEvent:
idpEvent = e.OIDCConfigChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y2IVI", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPOIDCConfigChangedEventType, instance.IDPOIDCConfigChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-sh6Lp", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
oidc, err := idpRepo.GetOIDC(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.IDPConfigID, orgId)))
if err != nil {
return err
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != oidc.ClientID {
oidc.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
oidc.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.Issuer != nil && *idpEvent.Issuer != oidc.Issuer {
oidc.Issuer = *idpEvent.Issuer
}
if idpEvent.AuthorizationEndpoint != nil && *idpEvent.AuthorizationEndpoint != oidc.AuthorizationEndpoint {
oidc.AuthorizationEndpoint = *idpEvent.AuthorizationEndpoint
}
if idpEvent.TokenEndpoint != nil && *idpEvent.TokenEndpoint != oidc.TokenEndpoint {
oidc.TokenEndpoint = *idpEvent.TokenEndpoint
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, oidc.Scopes) {
oidc.Scopes = idpEvent.Scopes
}
if idpEvent.IDPDisplayNameMapping != nil {
oidc.IDPDisplayNameMapping = mapOIDCMappingField(*idpEvent.IDPDisplayNameMapping)
}
if idpEvent.UserNameMapping != nil {
oidc.UserNameMapping = mapOIDCMappingField(*idpEvent.UserNameMapping)
}
payloadJSON, err := json.Marshal(oidc.OIDC)
if err != nil {
return err
}
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.IDPConfigID, orgId),
idpRepo.SetPayload(string(payloadJSON)),
idpRepo.SetType(domain.IDPTypeOIDC),
idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())),
)
return err
}), nil
}
func mapOIDCMappingField(field internal_domain.OIDCMappingField) domain.OIDCMappingField {
switch field {
case internal_domain.OIDCMappingFieldEmail:
return domain.OIDCMappingFieldEmail
case internal_domain.OIDCMappingFieldPreferredLoginName:
return domain.OIDCMappingFieldPreferredLoginName
case internal_domain.OIDCMappingFieldUnspecified:
fallthrough
default:
return domain.OIDCMappingFieldUnspecified
}
}
func (p *relationalTablesProjection) reduceOIDCIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.OIDCIDPAddedEvent
switch e := event.(type) {
case *org.OIDCIDPAddedEvent:
idpEvent = e.OIDCIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.OIDCIDPAddedEvent:
idpEvent = e.OIDCIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Ys02m1", "reduce.wrong.event.type %v", []eventstore.EventType{org.OIDCIDPAddedEventType, instance.OIDCIDPAddedEventType})
}
payloadJSON, err := json.Marshal(idpEvent)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-C9ju3", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeOIDC),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceOIDCIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.OIDCIDPChangedEvent
switch e := event.(type) {
case *org.OIDCIDPChangedEvent:
idpEvent = e.OIDCIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.OIDCIDPChangedEvent:
idpEvent = e.OIDCIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y1K82ks", "reduce.wrong.event.type %v", []eventstore.EventType{org.OIDCIDPChangedEventType, instance.OIDCIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-L8CQt", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
oidc, err := idpRepo.GetOIDC(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &oidc.OIDC
payloadChanged := p.reduceOIDCIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceOIDCIDPChangedColumns(payload *domain.OIDC, idpEvent *idp.OIDCIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.ClientID != nil && *idpEvent.ClientID != payload.ClientID {
payloadChanged = true
payload.ClientID = *idpEvent.ClientID
}
if idpEvent.ClientSecret != nil {
payloadChanged = true
payload.ClientSecret = idpEvent.ClientSecret
}
if idpEvent.Issuer != nil && *idpEvent.Issuer != payload.Issuer {
payloadChanged = true
payload.Issuer = *idpEvent.Issuer
}
if idpEvent.Scopes != nil && !slices.Equal(idpEvent.Scopes, payload.Scopes) {
payloadChanged = true
payload.Scopes = idpEvent.Scopes
}
if idpEvent.IsIDTokenMapping != nil && *idpEvent.IsIDTokenMapping != payload.IsIDTokenMapping {
payloadChanged = true
payload.IsIDTokenMapping = *idpEvent.IsIDTokenMapping
}
if idpEvent.UsePKCE != nil && *idpEvent.UsePKCE != payload.UsePKCE {
payloadChanged = true
payload.UsePKCE = *idpEvent.UsePKCE
}
return payloadChanged
}
+246
View File
@@ -0,0 +1,246 @@
package projection
import (
"context"
"database/sql"
"github.com/muhlemmer/gu"
"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"
internal_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/idp"
"github.com/zitadel/zitadel/internal/repository/idpconfig"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idpconfig.IDPConfigAddedEvent
switch e := event.(type) {
case *org.IDPConfigAddedEvent:
idpEvent = e.IDPConfigAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.IDPConfigAddedEvent:
idpEvent = e.IDPConfigAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YcUdQ", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigAddedEventType, instance.IDPConfigAddedEventType})
}
return handler.NewStatement(event, 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.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: event.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ConfigID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: mapIDPConfigType(idpEvent.Typ),
AllowAutoCreation: idpEvent.AutoRegister,
AllowLinking: true,
AllowCreation: true,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func mapIDPConfigType(typ internal_domain.IDPConfigType) *domain.IDPType {
switch typ {
case internal_domain.IDPConfigTypeOIDC:
return gu.Ptr(domain.IDPTypeOIDC)
case internal_domain.IDPConfigTypeSAML:
return gu.Ptr(domain.IDPTypeSAML)
case internal_domain.IDPConfigTypeJWT:
return gu.Ptr(domain.IDPTypeJWT)
case internal_domain.IDPConfigTypeUnspecified:
fallthrough
default:
return nil
}
}
func mapAutoLinkingField(option internal_domain.AutoLinkingOption) *domain.IDPAutoLinkingField {
if option == internal_domain.AutoLinkingOptionUnspecified {
return nil
}
switch option {
case internal_domain.AutoLinkingOptionEmail:
return gu.Ptr(domain.IDPAutoLinkingFieldEmail)
case internal_domain.AutoLinkingOptionUsername:
return gu.Ptr(domain.IDPAutoLinkingFieldUsername)
case internal_domain.AutoLinkingOptionUnspecified:
fallthrough
default:
return nil
}
}
func idpScopedCondition(repo domain.IDProviderRepository, instanceID, id string, orgID *string) database.Condition {
return database.And(
repo.PrimaryKeyCondition(instanceID, id),
repo.OrgIDCondition(orgID),
)
}
func (p *relationalTablesProjection) reduceIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgID *string
var idpEvent idpconfig.IDPConfigChangedEvent
switch e := event.(type) {
case *org.IDPConfigChangedEvent:
idpEvent = e.IDPConfigChangedEvent
orgID = gu.Ptr(idpEvent.Aggregate().ResourceOwner)
case *instance.IDPConfigChangedEvent:
idpEvent = e.IDPConfigChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-YVvJD", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigChangedEventType, instance.IDPConfigChangedEventType})
}
repo := repository.IDProviderRepository()
changes := make(database.Changes, 0, 3)
if idpEvent.Name != nil {
changes = append(changes, repo.SetName(*idpEvent.Name))
}
if idpEvent.AutoRegister != nil {
changes = append(changes, repo.SetAllowAutoCreation(*idpEvent.AutoRegister))
}
if len(changes) == 0 {
return handler.NewNoOpStatement(&idpEvent), nil
}
changes = append(changes, repo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-9sX8h", "reduce.wrong.db.pool %T", ex)
}
_, err := repo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(repo, event.Aggregate().InstanceID, idpEvent.ConfigID, orgID), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceIDPDeactivated(event eventstore.Event) (*handler.Statement, error) {
var orgID *string
var idpEvent idpconfig.IDPConfigDeactivatedEvent
switch e := event.(type) {
case *org.IDPConfigDeactivatedEvent:
idpEvent = e.IDPConfigDeactivatedEvent
orgID = gu.Ptr(idpEvent.Aggregate().ResourceOwner)
case *instance.IDPConfigDeactivatedEvent:
idpEvent = e.IDPConfigDeactivatedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y4O5l", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigDeactivatedEventType, instance.IDPConfigDeactivatedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-9sX8h", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
_, err := repo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(repo, event.Aggregate().InstanceID, idpEvent.ConfigID, orgID),
repo.SetState(domain.IDPStateInactive),
repo.SetUpdatedAt(gu.Ptr(event.CreatedAt())),
)
return err
}), nil
}
func (p *relationalTablesProjection) reduceIDPReactivated(event eventstore.Event) (*handler.Statement, error) {
var orgID *string
var idpEvent idpconfig.IDPConfigReactivatedEvent
switch e := event.(type) {
case *org.IDPConfigReactivatedEvent:
idpEvent = e.IDPConfigReactivatedEvent
orgID = gu.Ptr(idpEvent.Aggregate().ResourceOwner)
case *instance.IDPConfigReactivatedEvent:
idpEvent = e.IDPConfigReactivatedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y8QyS", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPConfigReactivatedEventType, instance.IDPConfigReactivatedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-2Db9P", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
_, err := repo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(repo, idpEvent.Aggregate().InstanceID, idpEvent.ConfigID, orgID),
repo.SetState(domain.IDPStateActive),
repo.SetUpdatedAt(gu.Ptr(event.CreatedAt())),
)
return err
}), nil
}
func (p *relationalTablesProjection) reduceIDPRemoved(event eventstore.Event) (*handler.Statement, error) {
var (
orgID *string
idpID string
)
switch e := event.(type) {
case *org.IDPRemovedEvent:
idpID = e.ID
orgID = gu.Ptr(e.RemovedEvent.Aggregate().ResourceOwner)
case *instance.IDPRemovedEvent:
idpID = e.ID
case *org.IDPConfigRemovedEvent:
idpID = e.ConfigID
orgID = gu.Ptr(e.IDPConfigRemovedEvent.Aggregate().ResourceOwner)
case *instance.IDPConfigRemovedEvent:
idpID = e.ConfigID
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Ybcvwin2", "reduce.wrong.event.type %v", []eventstore.EventType{org.IDPRemovedEventType, instance.IDPRemovedEventType, org.IDPConfigRemovedEventType, instance.IDPConfigRemovedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-PSj7F", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
_, err := repo.Delete(ctx, v3_sql.SQLTx(tx), idpScopedCondition(repo, event.Aggregate().InstanceID, idpID, orgID))
return err
}), nil
}
func (p *relationalTablesProjection) reduceIDPChangedTemplateColumns(repo domain.IDProviderRepository, name *string, optionChanges idp.OptionChanges) database.Changes {
changes := make(database.Changes, 0, 8)
if name != nil {
changes = append(changes, repo.SetName(*name))
}
if optionChanges.IsCreationAllowed != nil {
changes = append(changes, repo.SetAllowCreation(*optionChanges.IsCreationAllowed))
}
if optionChanges.IsLinkingAllowed != nil {
changes = append(changes, repo.SetAllowLinking(*optionChanges.IsLinkingAllowed))
}
if optionChanges.IsAutoCreation != nil {
changes = append(changes, repo.SetAllowAutoCreation(*optionChanges.IsAutoCreation))
}
if optionChanges.IsAutoUpdate != nil {
changes = append(changes, repo.SetAllowAutoUpdate(*optionChanges.IsAutoUpdate))
}
if optionChanges.AutoLinkingOption != nil {
changes = append(changes, repo.SetAutoLinkingField(mapAutoLinkingField(*optionChanges.AutoLinkingOption)))
}
return changes
}
@@ -0,0 +1,164 @@
package projection
import (
"context"
"database/sql"
"encoding/json"
"slices"
"github.com/muhlemmer/gu"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/idp"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
func (p *relationalTablesProjection) reduceSAMLIDPAdded(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.SAMLIDPAddedEvent
switch e := event.(type) {
case *org.SAMLIDPAddedEvent:
idpEvent = e.SAMLIDPAddedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.SAMLIDPAddedEvent:
idpEvent = e.SAMLIDPAddedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Ys02m1", "reduce.wrong.event.type %v", []eventstore.EventType{org.SAMLIDPAddedEventType, instance.SAMLIDPAddedEventType})
}
saml := domain.SAML{
Metadata: idpEvent.Metadata,
Key: idpEvent.Key,
Certificate: idpEvent.Certificate,
Binding: idpEvent.Binding,
WithSignedRequest: idpEvent.WithSignedRequest,
NameIDFormat: idpEvent.NameIDFormat,
TransientMappingAttributeName: idpEvent.TransientMappingAttributeName,
SignatureAlgorithm: idpEvent.SignatureAlgorithm,
}
payloadJSON, err := json.Marshal(saml)
if err != nil {
return nil, err
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-ksJ3N", "reduce.wrong.db.pool %T", ex)
}
repo := repository.IDProviderRepository()
return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.IdentityProvider{
InstanceID: idpEvent.Aggregate().InstanceID,
OrgID: orgId,
ID: idpEvent.ID,
State: domain.IDPStateActive,
Name: idpEvent.Name,
Type: gu.Ptr(domain.IDPTypeSAML),
AllowCreation: idpEvent.IsCreationAllowed,
AllowAutoCreation: idpEvent.IsAutoCreation,
AllowAutoUpdate: idpEvent.IsAutoUpdate,
AllowLinking: idpEvent.IsLinkingAllowed,
AutoLinkingField: mapAutoLinkingField(idpEvent.AutoLinkingOption),
Payload: payloadJSON,
CreatedAt: event.CreatedAt(),
UpdatedAt: event.CreatedAt(),
})
}), nil
}
func (p *relationalTablesProjection) reduceSAMLIDPChanged(event eventstore.Event) (*handler.Statement, error) {
var orgId *string
var idpEvent idp.SAMLIDPChangedEvent
switch e := event.(type) {
case *org.SAMLIDPChangedEvent:
idpEvent = e.SAMLIDPChangedEvent
orgId = &idpEvent.Aggregate().ResourceOwner
case *instance.SAMLIDPChangedEvent:
idpEvent = e.SAMLIDPChangedEvent
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Y7c0fii4ad", "reduce.wrong.event.type %v", []eventstore.EventType{org.SAMLIDPChangedEventType, instance.SAMLIDPChangedEventType})
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, _ string) error {
tx, ok := ex.(*sql.Tx)
if !ok {
return zerrors.ThrowInternal(nil, "HANDL-HX6ed", "unable to cast to tx executer")
}
idpRepo := repository.IDProviderRepository()
saml, err := idpRepo.GetSAML(ctx, v3_sql.SQLTx(tx), database.WithCondition(idpScopedCondition(idpRepo, idpEvent.Agg.InstanceID, idpEvent.ID, orgId)))
if err != nil {
return err
}
changes := p.reduceIDPChangedTemplateColumns(idpRepo, idpEvent.Name, idpEvent.OptionChanges)
payload := &saml.SAML
payloadChanged := p.reduceSAMLIDPChangedColumns(payload, &idpEvent)
if payloadChanged {
payloadJSON, err := json.Marshal(payload)
if err != nil {
return err
}
changes = append(changes, idpRepo.SetPayload(string(payloadJSON)))
}
changes = append(changes, idpRepo.SetUpdatedAt(gu.Ptr(event.CreatedAt())))
_, err = idpRepo.Update(ctx, v3_sql.SQLTx(tx), idpScopedCondition(idpRepo, idpEvent.Aggregate().InstanceID, idpEvent.ID, orgId), changes...)
return err
}), nil
}
func (p *relationalTablesProjection) reduceSAMLIDPChangedColumns(payload *domain.SAML, idpEvent *idp.SAMLIDPChangedEvent) bool {
payloadChanged := false
if payload == nil || idpEvent == nil {
return payloadChanged
}
if idpEvent.Metadata != nil && !slices.Equal(idpEvent.Metadata, payload.Metadata) {
payloadChanged = true
payload.Metadata = idpEvent.Metadata
}
if idpEvent.Key != nil {
payloadChanged = true
payload.Key = idpEvent.Key
}
if idpEvent.Certificate != nil && !slices.Equal(idpEvent.Certificate, payload.Certificate) {
payloadChanged = true
payload.Certificate = idpEvent.Certificate
}
if idpEvent.Binding != nil && *idpEvent.Binding != payload.Binding {
payloadChanged = true
payload.Binding = *idpEvent.Binding
}
if idpEvent.WithSignedRequest != nil && *idpEvent.WithSignedRequest != payload.WithSignedRequest {
payloadChanged = true
payload.WithSignedRequest = *idpEvent.WithSignedRequest
}
if idpEvent.NameIDFormat != nil && (payload.NameIDFormat == nil || *idpEvent.NameIDFormat != *payload.NameIDFormat) {
payloadChanged = true
payload.NameIDFormat = idpEvent.NameIDFormat
}
if idpEvent.TransientMappingAttributeName != nil && *idpEvent.TransientMappingAttributeName != payload.TransientMappingAttributeName {
payloadChanged = true
payload.TransientMappingAttributeName = *idpEvent.TransientMappingAttributeName
}
if idpEvent.FederatedLogoutEnabled != nil && *idpEvent.FederatedLogoutEnabled != payload.FederatedLogoutEnabled {
payloadChanged = true
payload.FederatedLogoutEnabled = *idpEvent.FederatedLogoutEnabled
}
if idpEvent.SignatureAlgorithm != nil && *idpEvent.SignatureAlgorithm != payload.SignatureAlgorithm {
payloadChanged = true
payload.SignatureAlgorithm = *idpEvent.SignatureAlgorithm
}
return payloadChanged
}
File diff suppressed because it is too large Load Diff
@@ -16,47 +16,7 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
type instanceDomainRelationalProjection struct{}
func newInstanceDomainRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(instanceDomainRelationalProjection))
}
func (*instanceDomainRelationalProjection) Name() string {
return "zitadel.instance_domains"
}
func (p *instanceDomainRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: instance.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: instance.InstanceDomainAddedEventType,
Reduce: p.reduceCustomDomainAdded,
},
{
Event: instance.InstanceDomainPrimarySetEventType,
Reduce: p.reduceDomainPrimarySet,
},
{
Event: instance.InstanceDomainRemovedEventType,
Reduce: p.reduceCustomDomainRemoved,
},
{
Event: instance.TrustedDomainAddedEventType,
Reduce: p.reduceTrustedDomainAdded,
},
{
Event: instance.TrustedDomainRemovedEventType,
Reduce: p.reduceTrustedDomainRemoved,
},
},
},
}
}
func (p *instanceDomainRelationalProjection) reduceCustomDomainAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceCustomInstanceDomainAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.DomainAddedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-DU0xF", "reduce.wrong.event.type %s", instance.InstanceDomainAddedEventType)
@@ -78,7 +38,7 @@ func (p *instanceDomainRelationalProjection) reduceCustomDomainAdded(event event
}), nil
}
func (p *instanceDomainRelationalProjection) reduceDomainPrimarySet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceInstanceDomainPrimarySet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.DomainPrimarySetEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-TdEWA", "reduce.wrong.event.type %s", instance.InstanceDomainPrimarySetEventType)
@@ -103,7 +63,7 @@ func (p *instanceDomainRelationalProjection) reduceDomainPrimarySet(event events
}), nil
}
func (p *instanceDomainRelationalProjection) reduceCustomDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceCustomInstanceDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.DomainRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Hhcdl", "reduce.wrong.event.type %s", instance.InstanceDomainRemovedEventType)
@@ -125,7 +85,7 @@ func (p *instanceDomainRelationalProjection) reduceCustomDomainRemoved(event eve
}), nil
}
func (p *instanceDomainRelationalProjection) reduceTrustedDomainAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceTrustedInstanceDomainAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.TrustedDomainAddedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-svHDh", "reduce.wrong.event.type %s", instance.TrustedDomainAddedEventType)
@@ -145,7 +105,7 @@ func (p *instanceDomainRelationalProjection) reduceTrustedDomainAdded(event even
}), nil
}
func (p *instanceDomainRelationalProjection) reduceTrustedDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceTrustedInstanceDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.TrustedDomainRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-4K74E", "reduce.wrong.event.type %s", instance.TrustedDomainRemovedEventType)
@@ -15,7 +15,7 @@ import (
)
func TestInstanceDomainReducers(t *testing.T) {
handler := &instanceDomainRelationalProjection{}
handler := &relationalTablesProjection{}
rawTx, tx := getTransactions(t)
t.Cleanup(func() {
@@ -14,62 +14,12 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
const InstanceRelationalProjectionTable = "zitadel.instances"
type instanceRelationalProjection struct{}
func newInstanceRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(instanceRelationalProjection))
}
func (*instanceRelationalProjection) Name() string {
return InstanceRelationalProjectionTable
}
func (p *instanceRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: instance.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: instance.InstanceAddedEventType,
Reduce: p.reduceInstanceAdded,
},
{
Event: instance.InstanceChangedEventType,
Reduce: p.reduceInstanceChanged,
},
{
Event: instance.InstanceRemovedEventType,
Reduce: p.reduceInstanceDelete,
},
{
Event: instance.DefaultOrgSetEventType,
Reduce: p.reduceDefaultOrgSet,
},
{
Event: instance.ProjectSetEventType,
Reduce: p.reduceIAMProjectSet,
},
{
Event: instance.ManagementConsoleSetEventType,
Reduce: p.reduceManagementConsoleSet,
},
{
Event: instance.DefaultLanguageSetEventType,
Reduce: p.reduceDefaultLanguageSet,
},
},
},
}
}
func (p *instanceRelationalProjection) reduceInstanceAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceInstanceAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.InstanceAddedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-29nRr", "reduce.wrong.event.type %s", instance.InstanceAddedEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-rVUyy", "reduce.wrong.db.pool %T", ex)
@@ -83,12 +33,12 @@ func (p *instanceRelationalProjection) reduceInstanceAdded(event eventstore.Even
}), nil
}
func (p *instanceRelationalProjection) reduceInstanceChanged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceInstanceChanged(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.InstanceChangedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-so2am1", "reduce.wrong.event.type %s", instance.InstanceChangedEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-rVUyy", "reduce.wrong.db.pool %T", ex)
@@ -98,12 +48,12 @@ func (p *instanceRelationalProjection) reduceInstanceChanged(event eventstore.Ev
}), nil
}
func (p *instanceRelationalProjection) reduceInstanceDelete(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceInstanceDelete(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.InstanceRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-so2am1", "reduce.wrong.event.type %s", instance.InstanceChangedEventType)
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-so2am1", "reduce.wrong.event.type %s", instance.InstanceRemovedEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-rVUyy", "reduce.wrong.db.pool %T", ex)
@@ -113,13 +63,13 @@ func (p *instanceRelationalProjection) reduceInstanceDelete(event eventstore.Eve
}), nil
}
func (p *instanceRelationalProjection) reduceDefaultOrgSet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceDefaultOrgSet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.DefaultOrgSetEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-2n9f2", "reduce.wrong.event.type %s", instance.DefaultOrgSetEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-rVUyy", "reduce.wrong.db.pool %T", ex)
@@ -129,13 +79,13 @@ func (p *instanceRelationalProjection) reduceDefaultOrgSet(event eventstore.Even
}), nil
}
func (p *instanceRelationalProjection) reduceIAMProjectSet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceIAMProjectSet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.ProjectSetEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-30o0e", "reduce.wrong.event.type %s", instance.ProjectSetEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-rVUyy", "reduce.wrong.db.pool %T", ex)
@@ -145,13 +95,13 @@ func (p *instanceRelationalProjection) reduceIAMProjectSet(event eventstore.Even
}), nil
}
func (p *instanceRelationalProjection) reduceManagementConsoleSet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceManagementConsoleSet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.ManagementConsoleSetEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Dgf11", "reduce.wrong.event.type %s", instance.ManagementConsoleSetEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-rVUyy", "reduce.wrong.db.pool %T", ex)
@@ -161,13 +111,13 @@ func (p *instanceRelationalProjection) reduceManagementConsoleSet(event eventsto
}), nil
}
func (p *instanceRelationalProjection) reduceDefaultLanguageSet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceDefaultLanguageSet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.DefaultLanguageSetEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-30o0e", "reduce.wrong.event.type %s", instance.DefaultLanguageSetEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-rVUyy", "reduce.wrong.db.pool %T", ex)
@@ -177,7 +127,7 @@ func (p *instanceRelationalProjection) reduceDefaultLanguageSet(event eventstore
}), nil
}
func (p *instanceRelationalProjection) updateInstance(ctx context.Context, tx database.Transaction, event eventstore.Event, repo domain.InstanceRepository, changes ...database.Change) error {
func (p *relationalTablesProjection) updateInstance(ctx context.Context, tx database.Transaction, event eventstore.Event, repo domain.InstanceRepository, changes ...database.Change) error {
_, err := repo.Update(ctx, tx, event.Aggregate().ID, changes...)
if err != nil {
return err
@@ -14,52 +14,12 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
type orgDomainRelationalProjection struct{}
func newOrgDomainRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(orgDomainRelationalProjection))
}
func (*orgDomainRelationalProjection) Name() string {
return "zitadel.org_domains"
}
func (p *orgDomainRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: org.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: org.OrgDomainAddedEventType,
Reduce: p.reduceAdded,
},
{
Event: org.OrgDomainPrimarySetEventType,
Reduce: p.reducePrimarySet,
},
{
Event: org.OrgDomainRemovedEventType,
Reduce: p.reduceRemoved,
},
{
Event: org.OrgDomainVerificationAddedEventType,
Reduce: p.reduceVerificationAdded,
},
{
Event: org.OrgDomainVerifiedEventType,
Reduce: p.reduceVerified,
},
},
},
}
}
func (p *orgDomainRelationalProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrganizationDomainAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.DomainAddedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-ZX9Fw", "reduce.wrong.event.type %s", org.OrgDomainAddedEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-kGokE", "reduce.wrong.db.pool %T", ex)
@@ -74,12 +34,12 @@ func (p *orgDomainRelationalProjection) reduceAdded(event eventstore.Event) (*ha
}), nil
}
func (p *orgDomainRelationalProjection) reducePrimarySet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrganizationDomainPrimarySet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.DomainPrimarySetEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-dmFdb", "reduce.wrong.event.type %s", org.OrgDomainPrimarySetEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-h6xF0", "reduce.wrong.db.pool %T", ex)
@@ -94,12 +54,12 @@ func (p *orgDomainRelationalProjection) reducePrimarySet(event eventstore.Event)
}), nil
}
func (p *orgDomainRelationalProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrganizationDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.DomainRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-MzC0n", "reduce.wrong.event.type %s", org.OrgDomainRemovedEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-X8oS8", "reduce.wrong.db.pool %T", ex)
@@ -112,7 +72,7 @@ func (p *orgDomainRelationalProjection) reduceRemoved(event eventstore.Event) (*
}), nil
}
func (p *orgDomainRelationalProjection) reduceVerificationAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrganizationDomainVerificationAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.DomainVerificationAddedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-oGzip", "reduce.wrong.event.type %s", org.OrgDomainVerificationAddedEventType)
@@ -126,7 +86,7 @@ func (p *orgDomainRelationalProjection) reduceVerificationAdded(event eventstore
case old_domain.OrgDomainValidationTypeUnspecified:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-FJfKB", "reduce.unsupported.validation.type %v", e.ValidationType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-yF03i", "reduce.wrong.db.pool %T", ex)
@@ -142,12 +102,12 @@ func (p *orgDomainRelationalProjection) reduceVerificationAdded(event eventstore
}), nil
}
func (p *orgDomainRelationalProjection) reduceVerified(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrganizationDomainVerified(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.DomainVerifiedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-7WrI2", "reduce.wrong.event.type %s", org.OrgDomainVerifiedEventType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-0ZGqC", "reduce.wrong.db.pool %T", ex)
@@ -14,45 +14,12 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
type orgMetadataRelationalProjection struct{}
func newOrgMetadataRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(orgMetadataRelationalProjection))
}
func (*orgMetadataRelationalProjection) Name() string {
return "zitadel.org_metadata"
}
func (p *orgMetadataRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: org.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: org.MetadataSetType,
Reduce: p.reduceSet,
},
{
Event: org.MetadataRemovedType,
Reduce: p.reduceRemoved,
},
// This event cannot be tested because it was never used in the past
{
Event: org.MetadataRemovedAllType,
Reduce: p.reduceRemovedAll,
},
},
},
}
}
func (p *orgMetadataRelationalProjection) reduceSet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrganizationMetadataSet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.MetadataSetEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-xOO4e", "reduce.wrong.event.type %s", org.MetadataSetType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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)
@@ -70,12 +37,12 @@ func (p *orgMetadataRelationalProjection) reduceSet(event eventstore.Event) (*ha
}), nil
}
func (p *orgMetadataRelationalProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrganizationMetadataRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.MetadataRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-XE6TF", "reduce.wrong.event.type %s", org.MetadataRemovedType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-QKMlz", "reduce.wrong.db.pool %T", ex)
@@ -92,12 +59,12 @@ func (p *orgMetadataRelationalProjection) reduceRemoved(event eventstore.Event)
}), nil
}
func (p *orgMetadataRelationalProjection) reduceRemovedAll(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrganizationMetadataRemovedAll(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.MetadataRemovedAllEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-EmyAe", "reduce.wrong.event.type %s", org.MetadataRemovedAllType)
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-hjEHg", "reduce.wrong.db.pool %T", ex)
+5 -59
View File
@@ -9,65 +9,11 @@ import (
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
"github.com/zitadel/zitadel/internal/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/org"
"github.com/zitadel/zitadel/internal/zerrors"
)
const (
OrgRelationProjectionTable = "zitadel.organizations"
)
type orgRelationalProjection struct{}
func (*orgRelationalProjection) Name() string {
return OrgRelationProjectionTable
}
func newOrgRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(orgRelationalProjection))
}
func (p *orgRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: org.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: org.OrgAddedEventType,
Reduce: p.reduceOrgRelationalAdded,
},
{
Event: org.OrgChangedEventType,
Reduce: p.reduceOrgRelationalChanged,
},
{
Event: org.OrgDeactivatedEventType,
Reduce: p.reduceOrgRelationalDeactivated,
},
{
Event: org.OrgReactivatedEventType,
Reduce: p.reduceOrgRelationalReactivated,
},
{
Event: org.OrgRemovedEventType,
Reduce: p.reduceOrgRelationalRemoved,
},
},
},
{
Aggregate: instance.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: instance.InstanceRemovedEventType,
Reduce: reduceInstanceRemovedHelper(OrgColumnInstanceID),
},
},
},
}
}
func (p *orgRelationalProjection) reduceOrgRelationalAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrgRelationalAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgAddedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-uYq5R", "reduce.wrong.event.type %s", org.OrgAddedEventType)
@@ -91,7 +37,7 @@ func (p *orgRelationalProjection) reduceOrgRelationalAdded(event eventstore.Even
}), nil
}
func (p *orgRelationalProjection) reduceOrgRelationalChanged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrgRelationalChanged(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgChangedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Bg9om", "reduce.wrong.event.type %s", org.OrgChangedEventType)
@@ -115,7 +61,7 @@ func (p *orgRelationalProjection) reduceOrgRelationalChanged(event eventstore.Ev
}), nil
}
func (p *orgRelationalProjection) reduceOrgRelationalDeactivated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrgRelationalDeactivated(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgDeactivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-BApK5", "reduce.wrong.event.type %s", org.OrgDeactivatedEventType)
@@ -137,7 +83,7 @@ func (p *orgRelationalProjection) reduceOrgRelationalDeactivated(event eventstor
}), nil
}
func (p *orgRelationalProjection) reduceOrgRelationalReactivated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrgRelationalReactivated(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgReactivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-o38DE", "reduce.wrong.event.type %s", org.OrgReactivatedEventType)
@@ -158,7 +104,7 @@ func (p *orgRelationalProjection) reduceOrgRelationalReactivated(event eventstor
}), nil
}
func (p *orgRelationalProjection) reduceOrgRelationalRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceOrgRelationalRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*org.OrgRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-DGm9g", "reduce.wrong.event.type %s", org.OrgRemovedEventType)
@@ -13,51 +13,7 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
type projectGrantRelationalProjection struct{}
func (*projectGrantRelationalProjection) Name() string {
return "zitadel.project_grants"
}
func newProjectGrantRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(projectGrantRelationalProjection))
}
func (p *projectGrantRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: project.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: project.GrantAddedType,
Reduce: p.reduceProjectGrantAdded,
},
{
Event: project.GrantChangedType,
Reduce: p.reduceProjectGrantChanged,
},
{
Event: project.GrantCascadeChangedType,
Reduce: p.reduceProjectGrantCascadeChanged,
},
{
Event: project.GrantDeactivatedType,
Reduce: p.reduceProjectGrantDeactivated,
},
{
Event: project.GrantReactivatedType,
Reduce: p.reduceProjectGrantReactivated,
},
{
Event: project.GrantRemovedType,
Reduce: p.reduceProjectGrantRemoved,
},
},
},
}
}
func (p *projectGrantRelationalProjection) reduceProjectGrantAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectGrantAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.GrantAddedEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-5l2bWQrkKf", "reduce.wrong.event.type %s", project.GrantAddedType)
@@ -82,7 +38,7 @@ func (p *projectGrantRelationalProjection) reduceProjectGrantAdded(event eventst
}), nil
}
func (p *projectGrantRelationalProjection) reduceProjectGrantChanged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectGrantChanged(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.GrantChangedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-I2ciunHcy7", "reduce.wrong.event.type %s", project.GrantChangedType)
@@ -102,7 +58,7 @@ func (p *projectGrantRelationalProjection) reduceProjectGrantChanged(event event
}), nil
}
func (p *projectGrantRelationalProjection) reduceProjectGrantCascadeChanged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectGrantCascadeChanged(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.GrantCascadeChangedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-osXtu6jnWa", "reduce.wrong.event.type %s", project.GrantCascadeChangedType)
@@ -122,7 +78,7 @@ func (p *projectGrantRelationalProjection) reduceProjectGrantCascadeChanged(even
}), nil
}
func (p *projectGrantRelationalProjection) reduceProjectGrantDeactivated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectGrantDeactivated(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.GrantDeactivateEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-XraL17MUkr", "reduce.wrong.event.type %s", project.GrantDeactivatedType)
@@ -143,7 +99,7 @@ func (p *projectGrantRelationalProjection) reduceProjectGrantDeactivated(event e
}), nil
}
func (p *projectGrantRelationalProjection) reduceProjectGrantReactivated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectGrantReactivated(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.GrantReactivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-vGUHp6uHJ7", "reduce.wrong.event.type %s", project.GrantReactivatedType)
@@ -164,7 +120,7 @@ func (p *projectGrantRelationalProjection) reduceProjectGrantReactivated(event e
}), nil
}
func (p *projectGrantRelationalProjection) reduceProjectGrantRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectGrantRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.GrantRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-MVPgtdg1w5", "reduce.wrong.event.type %s", project.GrantRemovedType)
@@ -14,47 +14,7 @@ import (
"github.com/zitadel/zitadel/internal/zerrors"
)
type projectRelationalProjection struct{}
func (*projectRelationalProjection) Name() string {
return "zitadel.projects"
}
func newProjectRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(projectRelationalProjection))
}
func (p *projectRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: project.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: project.ProjectAddedType,
Reduce: p.reduceProjectAdded,
},
{
Event: project.ProjectChangedType,
Reduce: p.reduceProjectChanged,
},
{
Event: project.ProjectDeactivatedType,
Reduce: p.reduceProjectDeactivated,
},
{
Event: project.ProjectReactivatedType,
Reduce: p.reduceProjectReactivated,
},
{
Event: project.ProjectRemovedType,
Reduce: p.reduceProjectRemoved,
},
},
},
}
}
func (p *projectRelationalProjection) reduceProjectAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.ProjectAddedEvent)
if !ok {
return nil, zerrors.ThrowInternalf(nil, "HANDL-Oox5e", "reduce.wrong.event.type %s", project.ProjectAddedType)
@@ -81,7 +41,7 @@ func (p *projectRelationalProjection) reduceProjectAdded(event eventstore.Event)
}), nil
}
func (p *projectRelationalProjection) reduceProjectChanged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectChanged(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.ProjectChangeEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Oox5e", "reduce.wrong.event.type %s", project.ProjectChangedType)
@@ -121,7 +81,7 @@ func (p *projectRelationalProjection) reduceProjectChanged(event eventstore.Even
}), nil
}
func (p *projectRelationalProjection) reduceProjectDeactivated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectDeactivated(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.ProjectDeactivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Oox5e", "reduce.wrong.event.type %s", project.ProjectDeactivatedType)
@@ -141,7 +101,7 @@ func (p *projectRelationalProjection) reduceProjectDeactivated(event eventstore.
}), nil
}
func (p *projectRelationalProjection) reduceProjectReactivated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectReactivated(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.ProjectReactivatedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-oof4U", "reduce.wrong.event.type %s", project.ProjectReactivatedType)
@@ -161,7 +121,7 @@ func (p *projectRelationalProjection) reduceProjectReactivated(event eventstore.
}), nil
}
func (p *projectRelationalProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.ProjectRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Xae7w", "reduce.wrong.event.type %s", project.ProjectRemovedType)
@@ -21,39 +21,7 @@ const (
ProjectRoleRelationalRoleGroupCol = "role_group"
)
type projectRoleRelationalProjection struct{}
func (*projectRoleRelationalProjection) Name() string {
return ProjectRoleRelationalTable
}
func newProjectRoleRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(projectRoleRelationalProjection))
}
func (p *projectRoleRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: project.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: project.RoleAddedType,
Reduce: p.reduceProjectRoleAdded,
},
{
Event: project.RoleChangedType,
Reduce: p.reduceProjectRoleChanged,
},
{
Event: project.RoleRemovedType,
Reduce: p.reduceProjectRoleRemoved,
},
},
},
}
}
func (p *projectRoleRelationalProjection) reduceProjectRoleAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectRoleAdded(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.RoleAddedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-EiPa5", "reduce.wrong.event.type %s", project.RoleAddedType)
@@ -85,7 +53,7 @@ func (p *projectRoleRelationalProjection) reduceProjectRoleAdded(event eventstor
}), nil
}
func (p *projectRoleRelationalProjection) reduceProjectRoleChanged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectRoleChanged(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.RoleChangedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-PieJ9", "reduce.wrong.event.type %s", project.RoleChangedType)
@@ -118,7 +86,7 @@ func (p *projectRoleRelationalProjection) reduceProjectRoleChanged(event eventst
}), nil
}
func (p *projectRoleRelationalProjection) reduceProjectRoleRemoved(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceProjectRoleRemoved(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*project.RoleRemovedEvent)
if !ok {
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Ei9po", "reduce.wrong.event.type %s", project.RoleRemovedType)
+3 -42
View File
@@ -89,20 +89,7 @@ var (
HostedLoginTranslationProjection *handler.Handler
OrganizationSettingsProjection *handler.Handler
InstanceRelationalProjection *handler.Handler
OrganizationRelationalProjection *handler.Handler
InstanceDomainRelationalProjection *handler.Handler
OrganizationDomainRelationalProjection *handler.Handler
IDPTemplateRelationalProjection *handler.Handler
ProjectRelationalProjection *handler.Handler
ProjectRoleRelationalProjection *handler.Handler
OrganizationMetadataRelationalProjection *handler.Handler
AuthorizationRelationalProjection *handler.Handler
ProjectGrantRelationalProjection *handler.Handler
SessionRelationalProjection *handler.Handler
SettingsRelationalProjection *handler.Handler
UserRelationalProjection *handler.Handler
IDPIntentRelationalProjection *handler.Handler
RelationalTablesProjection *handler.Handler
ProjectGrantFields *handler.FieldHandler
OrgDomainVerifiedFields *handler.FieldHandler
@@ -220,20 +207,7 @@ func Create(ctx context.Context, sqlClient *database.DB, es handler.EventStore,
GroupProjection = newGroupProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["groups"]))
GroupUsersProjection = newGroupUsersProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["group_users"]))
InstanceRelationalProjection = newInstanceRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["instances_relational"]))
OrganizationRelationalProjection = newOrgRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["organizations_relational"]))
InstanceDomainRelationalProjection = newInstanceDomainRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["instance_domains_relational"]))
OrganizationDomainRelationalProjection = newOrgDomainRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["organization_domains_relational"]))
SettingsRelationalProjection = newSettingsRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["settings_relational"]))
IDPTemplateRelationalProjection = newIDPTemplateRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["idp_templates_relational"]))
ProjectRelationalProjection = newProjectRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["projects_relational"]))
ProjectRoleRelationalProjection = newProjectRoleRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["project_roles_relational"]))
OrganizationMetadataRelationalProjection = newOrgMetadataRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["organization_metadata_relational"]))
AuthorizationRelationalProjection = newAuthorizationRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["authorizations_relational"]))
ProjectGrantRelationalProjection = newProjectGrantRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["project_grant_relational"]))
SessionRelationalProjection = newSessionRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["session_relational"]))
UserRelationalProjection = newUserRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["user_relational"]))
IDPIntentRelationalProjection = newIDPIntentRelationalProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["idp_intent_relational"]))
RelationalTablesProjection = newRelationalTablesProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["relational_tables"]))
newProjectionsList()
newFieldsList()
@@ -419,19 +393,6 @@ func newProjectionsList() {
GroupProjection,
GroupUsersProjection,
InstanceRelationalProjection,
OrganizationRelationalProjection,
InstanceDomainRelationalProjection,
OrganizationDomainRelationalProjection,
SettingsRelationalProjection,
IDPTemplateRelationalProjection,
ProjectRelationalProjection,
ProjectRoleRelationalProjection,
OrganizationMetadataRelationalProjection,
UserRelationalProjection,
AuthorizationRelationalProjection,
ProjectGrantRelationalProjection,
SessionRelationalProjection,
IDPIntentRelationalProjection,
RelationalTablesProjection,
}
}
File diff suppressed because it is too large Load Diff
+32 -206
View File
@@ -5,138 +5,21 @@ import (
"database/sql"
"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/eventstore"
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
"github.com/zitadel/zitadel/internal/repository/instance"
"github.com/zitadel/zitadel/internal/repository/session"
"github.com/zitadel/zitadel/internal/repository/user"
"github.com/zitadel/zitadel/internal/zerrors"
)
const (
SessionsRelationalProjectionTable = "zitadel.sessions"
)
type sessionRelationalProjection struct{}
func (*sessionRelationalProjection) Name() string {
return SessionsRelationalProjectionTable
}
func newSessionRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
return handler.NewHandler(ctx, &config, new(sessionRelationalProjection))
}
func (p *sessionRelationalProjection) Reducers() []handler.AggregateReducer {
return []handler.AggregateReducer{
{
Aggregate: session.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: session.AddedType,
Reduce: p.reduceSessionAdded,
},
{
Event: session.UserCheckedType,
Reduce: p.reduceUserChecked,
},
{
Event: session.PasswordCheckedType,
Reduce: p.reducePasswordChecked,
},
{
Event: session.IntentCheckedType,
Reduce: p.reduceIntentChecked,
},
{
Event: session.WebAuthNChallengedType,
Reduce: p.reduceWebAuthNChallenged,
},
{
Event: session.WebAuthNCheckedType,
Reduce: p.reduceWebAuthNChecked,
},
{
Event: session.TOTPCheckedType,
Reduce: p.reduceTOTPChecked,
},
{
Event: session.OTPSMSChallengedType,
Reduce: p.reduceOTPSMSChallenged,
},
{
Event: session.OTPSMSCheckedType,
Reduce: p.reduceOTPSMSChecked,
},
{
Event: session.OTPEmailChallengedType,
Reduce: p.reduceOTPEmailChallenged,
},
{
Event: session.OTPEmailCheckedType,
Reduce: p.reduceOTPEmailChecked,
},
{
Event: session.RecoveryCodeCheckedType,
Reduce: p.reduceRecoveryCodeChecked,
},
{
Event: session.TokenSetType,
Reduce: p.reduceTokenSet,
},
{
Event: session.MetadataSetType,
Reduce: p.reduceMetadataSet,
},
{
Event: session.LifetimeSetType,
Reduce: p.reduceLifetimeSet,
},
{
Event: session.TerminateType,
Reduce: p.reduceSessionTerminated,
},
},
},
{
Aggregate: instance.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: instance.InstanceRemovedEventType,
Reduce: reduceInstanceRemovedHelper(SMSColumnInstanceID),
},
},
},
{
Aggregate: user.AggregateType,
EventReducers: []handler.EventReducer{
{
Event: user.HumanPasswordChangedType,
Reduce: p.reducePasswordChanged,
},
{
Event: user.UserDeactivatedType,
Reduce: p.reduceUserStateNotActive,
},
{
Event: user.UserLockedType,
Reduce: p.reduceUserStateNotActive,
},
},
},
}
}
func (p *sessionRelationalProjection) reduceSessionAdded(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionAdded(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.AddedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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)
@@ -165,12 +48,12 @@ func (p *sessionRelationalProjection) reduceSessionAdded(event eventstore.Event)
}), nil
}
func (p *sessionRelationalProjection) reduceUserChecked(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionUserChecked(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.UserCheckedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-UHE92", "reduce.wrong.db.pool %T", ex)
@@ -190,12 +73,12 @@ func (p *sessionRelationalProjection) reduceUserChecked(event eventstore.Event)
}), nil
}
func (p *sessionRelationalProjection) reducePasswordChecked(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionPasswordChecked(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.PasswordCheckedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-3krfa", "reduce.wrong.db.pool %T", ex)
@@ -214,13 +97,13 @@ func (p *sessionRelationalProjection) reducePasswordChecked(event eventstore.Eve
}), nil
}
func (p *sessionRelationalProjection) reduceIntentChecked(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionIntentChecked(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.IntentCheckedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-ajkd2", "reduce.wrong.db.pool %T", ex)
@@ -239,12 +122,12 @@ func (p *sessionRelationalProjection) reduceIntentChecked(event eventstore.Event
}), nil
}
func (p *sessionRelationalProjection) reduceWebAuthNChallenged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionWebAuthNChallenged(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.WebAuthNChallengedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-do35d", "reduce.wrong.db.pool %T", ex)
@@ -266,12 +149,12 @@ func (p *sessionRelationalProjection) reduceWebAuthNChallenged(event eventstore.
return err
}), nil
}
func (p *sessionRelationalProjection) reduceWebAuthNChecked(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionWebAuthNChecked(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.WebAuthNCheckedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-djk22", "reduce.wrong.db.pool %T", ex)
@@ -291,13 +174,13 @@ func (p *sessionRelationalProjection) reduceWebAuthNChecked(event eventstore.Eve
}), nil
}
func (p *sessionRelationalProjection) reduceTOTPChecked(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionTOTPChecked(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.TOTPCheckedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-cklr9", "reduce.wrong.db.pool %T", ex)
@@ -316,13 +199,13 @@ func (p *sessionRelationalProjection) reduceTOTPChecked(event eventstore.Event)
}), nil
}
func (p *sessionRelationalProjection) reduceOTPSMSChallenged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionOTPSMSChallenged(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.OTPSMSChallengedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-fk4f9", "reduce.wrong.db.pool %T", ex)
@@ -346,13 +229,13 @@ func (p *sessionRelationalProjection) reduceOTPSMSChallenged(event eventstore.Ev
}), nil
}
func (p *sessionRelationalProjection) reduceOTPSMSChecked(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionOTPSMSChecked(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.OTPSMSCheckedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-dk39f", "reduce.wrong.db.pool %T", ex)
@@ -371,13 +254,13 @@ func (p *sessionRelationalProjection) reduceOTPSMSChecked(event eventstore.Event
}), nil
}
func (p *sessionRelationalProjection) reduceOTPEmailChallenged(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionOTPEmailChallenged(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.OTPEmailChallengedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-fkf93", "reduce.wrong.db.pool %T", ex)
@@ -401,13 +284,13 @@ func (p *sessionRelationalProjection) reduceOTPEmailChallenged(event eventstore.
}), nil
}
func (p *sessionRelationalProjection) reduceOTPEmailChecked(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionOTPEmailChecked(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.OTPEmailCheckedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-3kll0", "reduce.wrong.db.pool %T", ex)
@@ -426,13 +309,13 @@ func (p *sessionRelationalProjection) reduceOTPEmailChecked(event eventstore.Eve
}), nil
}
func (p *sessionRelationalProjection) reduceRecoveryCodeChecked(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionRecoveryCodeChecked(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.RecoveryCodeCheckedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-fk45a", "reduce.wrong.db.pool %T", ex)
@@ -451,13 +334,13 @@ func (p *sessionRelationalProjection) reduceRecoveryCodeChecked(event eventstore
}), nil
}
func (p *sessionRelationalProjection) reduceTokenSet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionTokenSet(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.TokenSetEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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-asddt", "reduce.wrong.db.pool %T", ex)
@@ -474,7 +357,7 @@ func (p *sessionRelationalProjection) reduceTokenSet(event eventstore.Event) (*h
}), nil
}
func (p *sessionRelationalProjection) reduceMetadataSet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionMetadataSet(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.MetadataSetEvent](event)
if err != nil {
return nil, err
@@ -490,7 +373,7 @@ func (p *sessionRelationalProjection) reduceMetadataSet(event eventstore.Event)
})
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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)
@@ -507,13 +390,13 @@ func (p *sessionRelationalProjection) reduceMetadataSet(event eventstore.Event)
}), nil
}
func (p *sessionRelationalProjection) reduceLifetimeSet(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionLifetimeSet(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.LifetimeSetEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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)
@@ -530,13 +413,13 @@ func (p *sessionRelationalProjection) reduceLifetimeSet(event eventstore.Event)
}), nil
}
func (p *sessionRelationalProjection) reduceSessionTerminated(event eventstore.Event) (*handler.Statement, error) {
func (p *relationalTablesProjection) reduceSessionTerminated(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*session.TerminateEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
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)
@@ -549,60 +432,3 @@ func (p *sessionRelationalProjection) reduceSessionTerminated(event eventstore.E
return err
}), nil
}
func (p *sessionRelationalProjection) reducePasswordChanged(event eventstore.Event) (*handler.Statement, error) {
e, err := assertEvent[*user.HumanPasswordChangedEvent](event)
if err != nil {
return nil, err
}
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName 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 *sessionRelationalProjection) reduceUserStateNotActive(event eventstore.Event) (*handler.Statement, error) {
switch t := event.(type) {
case *user.UserDeactivatedEvent, *user.UserLockedEvent:
// ok
default:
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-XBglbF", "reduce.wrong.event.type %v", t)
}
return handler.NewStatement(event, func(ctx context.Context, ex handler.Executer, projectionName 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
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -17,7 +17,7 @@ import (
)
func TestUserRelationalProjection_Reducers(t *testing.T) {
handler := &userRelationalProjection{}
handler := &relationalTablesProjection{}
rawTx, tx := getTransactions(t)
t.Cleanup(func() {
require.NoError(t, rawTx.Rollback())