diff --git a/cmd/zitadel/main.go b/cmd/zitadel/main.go index c1004a077f..d36b3bbc5c 100644 --- a/cmd/zitadel/main.go +++ b/cmd/zitadel/main.go @@ -161,8 +161,8 @@ func startSetup(configPaths []string, localDevMode bool) { ctx := context.Background() - setup, err := setup.StartSetup(conf.Eventstore, conf.SystemDefaults) + setup, err := setup.StartSetupV2(conf.Eventstore, conf.SystemDefaults) logging.Log("SERVE-fD252").OnError(err).Panic("failed to start setup") - err = setup.Execute(ctx, conf.SetUp) + err = setup.ExecuteV2(ctx, conf.SetUp) logging.Log("SERVE-djs3R").OnError(err).Panic("failed to execute setup") } diff --git a/cmd/zitadel/setup.yaml b/cmd/zitadel/setup.yaml index 79611a5022..e761c2315d 100644 --- a/cmd/zitadel/setup.yaml +++ b/cmd/zitadel/setup.yaml @@ -26,53 +26,53 @@ SetUp: Step1: GlobalOrg: 'Global' IAMProject: 'Zitadel' - DefaultLoginPolicy: - AllowUsernamePassword: true - AllowRegister: true - AllowExternalIdp: true - Orgs: - - Name: 'Global' - Domain: 'global.caos.ch' - Default: true - OrgIamPolicy: true - Users: - - FirstName: 'Global Org' - LastName: 'Administrator' - UserName: 'zitadel-global-org-admin@caos.ch' - Email: 'zitadel-global-org-admin@caos.ch' - Password: 'Password1!' - Owners: - - 'zitadel-global-org-admin@caos.ch' - - Name: 'CAOS AG' - Domain: 'caos.ch' - Users: - - FirstName: 'Zitadel' - LastName: 'Administrator' - UserName: 'zitadel-admin' - Email: 'zitadel-admin@caos.ch' - Password: 'Password1!' - Owners: - - 'zitadel-admin@caos.ch' - Projects: - - Name: 'Zitadel' - OIDCApps: - - Name: 'Management-API' - - Name: 'Auth-API' - - Name: 'Admin-API' - - Name: 'Zitadel Console' - RedirectUris: - - '$ZITADEL_CONSOLE/auth/callback' - PostLogoutRedirectUris: - - '$ZITADEL_CONSOLE/signedout' - ResponseTypes: - - $ZITADEL_CONSOLE_RESPONSE_TYPE - GrantTypes: - - $ZITADEL_CONSOLE_GRANT_TYPE - ApplicationType: 'USER_AGENT' - AuthMethodType: 'NONE' - DevMode: $ZITADEL_CONSOLE_DEV_MODE - Owners: - - 'zitadel-admin@caos.ch' +# DefaultLoginPolicy: +# AllowUsernamePassword: true +# AllowRegister: true +# AllowExternalIdp: true +# Orgs: +# - Name: 'Global' +# Domain: 'global.caos.ch' +# Default: true +# OrgIamPolicy: true +# Users: +# - FirstName: 'Global Org' +# LastName: 'Administrator' +# UserName: 'zitadel-global-org-admin@caos.ch' +# Email: 'zitadel-global-org-admin@caos.ch' +# Password: 'Password1!' +# Owners: +# - 'zitadel-global-org-admin@caos.ch' +# - Name: 'CAOS AG' +# Domain: 'caos.ch' +# Users: +# - FirstName: 'Zitadel' +# LastName: 'Administrator' +# UserName: 'zitadel-admin' +# Email: 'zitadel-admin@caos.ch' +# Password: 'Password1!' +# Owners: +# - 'zitadel-admin@caos.ch' +# Projects: +# - Name: 'Zitadel' +# OIDCApps: +# - Name: 'Management-API' +# - Name: 'Auth-API' +# - Name: 'Admin-API' +# - Name: 'Zitadel Console' +# RedirectUris: +# - '$ZITADEL_CONSOLE/auth/callback' +# PostLogoutRedirectUris: +# - '$ZITADEL_CONSOLE/signedout' +# ResponseTypes: +# - $ZITADEL_CONSOLE_RESPONSE_TYPE +# GrantTypes: +# - $ZITADEL_CONSOLE_GRANT_TYPE +# ApplicationType: 'USER_AGENT' +# AuthMethodType: 'NONE' +# DevMode: $ZITADEL_CONSOLE_DEV_MODE +# Owners: +# - 'zitadel-admin@caos.ch' Step2: DefaultPasswordComplexityPolicy: MinLength: 8 diff --git a/internal/admin/repository/eventsourcing/eventstore/iam.go b/internal/admin/repository/eventsourcing/eventstore/iam.go index 462136f707..1904998a13 100644 --- a/internal/admin/repository/eventsourcing/eventstore/iam.go +++ b/internal/admin/repository/eventsourcing/eventstore/iam.go @@ -2,6 +2,7 @@ package eventstore import ( "context" + "github.com/caos/zitadel/internal/v2/query" "strings" caos_errs "github.com/caos/zitadel/internal/errors" @@ -18,7 +19,7 @@ import ( "github.com/caos/zitadel/internal/telemetry/tracing" usr_model "github.com/caos/zitadel/internal/user/model" usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing" - iam_business "github.com/caos/zitadel/internal/v2/business/iam" + "github.com/caos/zitadel/internal/v2/command" ) type IAMRepository struct { @@ -30,7 +31,8 @@ type IAMRepository struct { SystemDefaults systemdefaults.SystemDefaults Roles []string - IAMV2 *iam_business.Repository + IAMV2Command *command.CommandSide + IAMV2Query *query.QuerySide } func (repo *IAMRepository) IAMMemberByID(ctx context.Context, iamID, userID string) (*iam_model.IAMMemberView, error) { @@ -43,24 +45,24 @@ func (repo *IAMRepository) IAMMemberByID(ctx context.Context, iamID, userID stri func (repo *IAMRepository) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { member.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddMember(ctx, member) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddIAMMember(ctx, member) } return repo.IAMEventstore.AddIAMMember(ctx, member) } func (repo *IAMRepository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { member.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangeMember(ctx, member) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeIAMMember(ctx, member) } return repo.IAMEventstore.ChangeIAMMember(ctx, member) } func (repo *IAMRepository) RemoveIAMMember(ctx context.Context, userID string) error { member := iam_model.NewIAMMember(repo.SystemDefaults.IamID, userID) - if repo.IAMV2 != nil { - return repo.IAMV2.RemoveMember(ctx, member) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.RemoveIAMMember(ctx, member) } return repo.IAMEventstore.RemoveIAMMember(ctx, member) } @@ -97,8 +99,8 @@ func (repo *IAMRepository) GetIAMMemberRoles() []string { } func (repo *IAMRepository) IDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) { - if repo.IAMV2 != nil { - return repo.IAMV2.IDPConfigByID(ctx, repo.SystemDefaults.IamID, idpConfigID) + if repo.IAMV2Command != nil { + return repo.IAMV2Query.DefaultIDPConfigByID(ctx, repo.SystemDefaults.IamID, idpConfigID) } idp, err := repo.View.IDPConfigByID(idpConfigID) @@ -110,37 +112,37 @@ func (repo *IAMRepository) IDPConfigByID(ctx context.Context, idpConfigID string func (repo *IAMRepository) AddOIDCIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { idp.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddIDPConfig(ctx, idp) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddDefaultIDPConfig(ctx, idp) } return repo.IAMEventstore.AddIDPConfig(ctx, idp) } func (repo *IAMRepository) ChangeIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { idp.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangeIDPConfig(ctx, idp) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeDefaultIDPConfig(ctx, idp) } return repo.IAMEventstore.ChangeIDPConfig(ctx, idp) } func (repo *IAMRepository) DeactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) { - if repo.IAMV2 != nil { - return repo.IAMV2.DeactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.DeactivateDefaultIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID) } return repo.IAMEventstore.DeactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID) } func (repo *IAMRepository) ReactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) { - if repo.IAMV2 != nil { - return repo.IAMV2.ReactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ReactivateDefaultIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID) } return repo.IAMEventstore.ReactivateIDPConfig(ctx, repo.SystemDefaults.IamID, idpConfigID) } func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID string) error { - // if repo.IAMV2 != nil { - // return repo.IAMV2. + // if repo.IAMV2Command != nil { + // return repo.IAMV2Command. // } aggregates := make([]*es_models.Aggregate, 0) idp := iam_model.NewIDPConfig(repo.SystemDefaults.IamID, idpConfigID) @@ -184,8 +186,8 @@ func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID stri func (repo *IAMRepository) ChangeOidcIDPConfig(ctx context.Context, oidcConfig *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) { oidcConfig.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangeIDPOIDCConfig(ctx, oidcConfig) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeDefaultIDPOIDCConfig(ctx, oidcConfig) } return repo.IAMEventstore.ChangeIDPOIDCConfig(ctx, oidcConfig) } @@ -238,16 +240,16 @@ func (repo *IAMRepository) GetDefaultLabelPolicy(ctx context.Context) (*iam_mode func (repo *IAMRepository) AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddLabelPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddDefaultLabelPolicy(ctx, policy) } return repo.IAMEventstore.AddLabelPolicy(ctx, policy) } func (repo *IAMRepository) ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangeLabelPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeDefaultLabelPolicy(ctx, policy) } return repo.IAMEventstore.ChangeLabelPolicy(ctx, policy) } @@ -279,16 +281,16 @@ func (repo *IAMRepository) GetDefaultLoginPolicy(ctx context.Context) (*iam_mode func (repo *IAMRepository) AddDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddLoginPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddDefaultLoginPolicy(ctx, policy) } return repo.IAMEventstore.AddLoginPolicy(ctx, policy) } func (repo *IAMRepository) ChangeDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangeLoginPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeDefaultLoginPolicy(ctx, policy) } return repo.IAMEventstore.ChangeLoginPolicy(ctx, policy) } @@ -317,8 +319,8 @@ func (repo *IAMRepository) SearchDefaultIDPProviders(ctx context.Context, reques func (repo *IAMRepository) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) { provider.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddIDPProviderToLoginPolicy(ctx, provider) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddIDPProviderToDefaultLoginPolicy(ctx, provider) } return repo.IAMEventstore.AddIDPProviderToLoginPolicy(ctx, provider) } @@ -360,15 +362,15 @@ func (repo *IAMRepository) SearchDefaultSecondFactors(ctx context.Context) (*iam } func (repo *IAMRepository) AddSecondFactorToLoginPolicy(ctx context.Context, mfa iam_model.SecondFactorType) (iam_model.SecondFactorType, error) { - if repo.IAMV2 != nil { - return repo.IAMV2.AddSecondFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddSecondFactorToDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) } return repo.IAMEventstore.AddSecondFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) } func (repo *IAMRepository) RemoveSecondFactorFromLoginPolicy(ctx context.Context, mfa iam_model.SecondFactorType) error { - if repo.IAMV2 != nil { - return repo.IAMV2.RemoveSecondFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.RemoveSecondFactorFromDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) } return repo.IAMEventstore.RemoveSecondFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) } @@ -385,15 +387,15 @@ func (repo *IAMRepository) SearchDefaultMultiFactors(ctx context.Context) (*iam_ } func (repo *IAMRepository) AddMultiFactorToLoginPolicy(ctx context.Context, mfa iam_model.MultiFactorType) (iam_model.MultiFactorType, error) { - if repo.IAMV2 != nil { - return repo.IAMV2.AddMultiFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddMultiFactorToDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) } return repo.IAMEventstore.AddMultiFactorToLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) } func (repo *IAMRepository) RemoveMultiFactorFromLoginPolicy(ctx context.Context, mfa iam_model.MultiFactorType) error { - if repo.IAMV2 != nil { - return repo.IAMV2.RemoveMultiFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.RemoveMultiFactorFromDefaultLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) } return repo.IAMEventstore.RemoveMultiFactorFromLoginPolicy(ctx, repo.SystemDefaults.IamID, mfa) } @@ -425,16 +427,16 @@ func (repo *IAMRepository) GetDefaultPasswordComplexityPolicy(ctx context.Contex func (repo *IAMRepository) AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddPasswordComplexityPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddDefaultPasswordComplexityPolicy(ctx, policy) } return repo.IAMEventstore.AddPasswordComplexityPolicy(ctx, policy) } func (repo *IAMRepository) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangePasswordComplexityPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeDefaultPasswordComplexityPolicy(ctx, policy) } return repo.IAMEventstore.ChangePasswordComplexityPolicy(ctx, policy) } @@ -466,16 +468,16 @@ func (repo *IAMRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia func (repo *IAMRepository) AddDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddPasswordAgePolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddDefaultPasswordAgePolicy(ctx, policy) } return repo.IAMEventstore.AddPasswordAgePolicy(ctx, policy) } func (repo *IAMRepository) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangePasswordAgePolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeDefaultPasswordAgePolicy(ctx, policy) } return repo.IAMEventstore.ChangePasswordAgePolicy(ctx, policy) } @@ -507,16 +509,16 @@ func (repo *IAMRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context) func (repo *IAMRepository) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddPasswordLockoutPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddDefaultPasswordLockoutPolicy(ctx, policy) } return repo.IAMEventstore.AddPasswordLockoutPolicy(ctx, policy) } func (repo *IAMRepository) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangePasswordLockoutPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeDefaultPasswordLockoutPolicy(ctx, policy) } return repo.IAMEventstore.ChangePasswordLockoutPolicy(ctx, policy) } @@ -548,16 +550,16 @@ func (repo *IAMRepository) GetOrgIAMPolicy(ctx context.Context) (*iam_model.OrgI func (repo *IAMRepository) AddDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.AddOrgIAMPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.AddDefaultOrgIAMPolicy(ctx, policy) } return repo.IAMEventstore.AddOrgIAMPolicy(ctx, policy) } func (repo *IAMRepository) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { policy.AggregateID = repo.SystemDefaults.IamID - if repo.IAMV2 != nil { - return repo.IAMV2.ChangeOrgIAMPolicy(ctx, policy) + if repo.IAMV2Command != nil { + return repo.IAMV2Command.ChangeDefaultOrgIAMPolicy(ctx, policy) } return repo.IAMEventstore.ChangeOrgIAMPolicy(ctx, policy) } diff --git a/internal/admin/repository/eventsourcing/repository.go b/internal/admin/repository/eventsourcing/repository.go index a8fca1165f..384c39be28 100644 --- a/internal/admin/repository/eventsourcing/repository.go +++ b/internal/admin/repository/eventsourcing/repository.go @@ -2,6 +2,8 @@ package eventsourcing import ( "context" + "github.com/caos/zitadel/internal/v2/command" + "github.com/caos/zitadel/internal/v2/query" "github.com/caos/zitadel/internal/admin/repository/eventsourcing/eventstore" "github.com/caos/zitadel/internal/admin/repository/eventsourcing/handler" @@ -14,7 +16,6 @@ import ( es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing" es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing" es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" - iam_business "github.com/caos/zitadel/internal/v2/business/iam" ) type Config struct { @@ -65,7 +66,11 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r if err != nil { return nil, err } - iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) + iamV2Command, err := command.StartCommandSide(&command.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) + if err != nil { + return nil, err + } + iamV2Query, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) if err != nil { return nil, err } @@ -90,7 +95,8 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r SystemDefaults: systemDefaults, SearchLimit: conf.SearchLimit, Roles: roles, - IAMV2: iamV2, + IAMV2Command: iamV2Command, + IAMV2Query: iamV2Query, }, AdministratorRepo: eventstore.AdministratorRepo{ View: view, diff --git a/internal/api/api.go b/internal/api/api.go index a0225af53a..01e74389d4 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -6,6 +6,7 @@ import ( auth_es "github.com/caos/zitadel/internal/auth/repository/eventsourcing" "github.com/caos/zitadel/internal/telemetry/metrics" "github.com/caos/zitadel/internal/telemetry/metrics/otel" + "github.com/caos/zitadel/internal/v2/domain" view_model "github.com/caos/zitadel/internal/view/model" "go.opentelemetry.io/otel/api/metric" "net/http" @@ -98,10 +99,10 @@ func (a *API) healthHandler() http.Handler { if err != nil && !errors.IsNotFound(err) { return errors.ThrowPreconditionFailed(err, "API-dsgT2", "IAM SETUP CHECK FAILED") } - if iam == nil || iam.SetUpStarted < iam_model.StepCount-1 { + if iam == nil || iam.SetUpStarted < domain.StepCount-1 { return errors.ThrowPreconditionFailed(nil, "API-HBfs3", "IAM NOT SET UP") } - if iam.SetUpDone < iam_model.StepCount-1 { + if iam.SetUpDone < domain.StepCount-1 { return errors.ThrowPreconditionFailed(nil, "API-DASs2", "IAM SETUP RUNNING") } return nil diff --git a/internal/api/grpc/management/iam_converter.go b/internal/api/grpc/management/iam_converter.go index 255f5fd7a5..75a001ac9d 100644 --- a/internal/api/grpc/management/iam_converter.go +++ b/internal/api/grpc/management/iam_converter.go @@ -2,6 +2,7 @@ package management import ( iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/pkg/grpc/management" ) @@ -14,11 +15,11 @@ func iamFromModel(iam *iam_model.IAM) *management.Iam { } } -func iamSetupStepFromModel(step iam_model.Step) management.IamSetupStep { +func iamSetupStepFromModel(step domain.Step) management.IamSetupStep { switch step { - case iam_model.Step1: + case domain.Step1: return management.IamSetupStep_iam_setup_step_1 - case iam_model.Step2: + case domain.Step2: return management.IamSetupStep_iam_setup_step_2 // case iam_model.Step3: // return management.IamSetupStep_iam_setup_step_3 diff --git a/internal/auth/repository/eventsourcing/eventstore/iam.go b/internal/auth/repository/eventsourcing/eventstore/iam.go index 00b3c8c615..43230e345e 100644 --- a/internal/auth/repository/eventsourcing/eventstore/iam.go +++ b/internal/auth/repository/eventsourcing/eventstore/iam.go @@ -2,17 +2,17 @@ package eventstore import ( "context" + "github.com/caos/zitadel/internal/v2/query" "github.com/caos/zitadel/internal/iam/model" - iam_business "github.com/caos/zitadel/internal/v2/business/iam" ) type IAMRepository struct { IAMID string - IAMV2 *iam_business.Repository + IAMV2QuerySide *query.QuerySide } func (repo *IAMRepository) GetIAM(ctx context.Context) (*model.IAM, error) { - return repo.IAMV2.IAMByID(ctx, repo.IAMID) + return repo.IAMV2QuerySide.IAMByID(ctx, repo.IAMID) } diff --git a/internal/auth/repository/eventsourcing/handler/user_grant.go b/internal/auth/repository/eventsourcing/handler/user_grant.go index c61f831162..8aa95311db 100644 --- a/internal/auth/repository/eventsourcing/handler/user_grant.go +++ b/internal/auth/repository/eventsourcing/handler/user_grant.go @@ -5,13 +5,13 @@ import ( "strings" "github.com/caos/logging" + "github.com/caos/zitadel/internal/errors" caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" iam_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing" iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" org_model "github.com/caos/zitadel/internal/org/model" @@ -25,6 +25,7 @@ import ( usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" grant_es_model "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model" view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model" + "github.com/caos/zitadel/internal/v2/domain" ) type UserGrant struct { @@ -308,7 +309,7 @@ func (u *UserGrant) setIamProjectID() error { return err } - if iam.SetUpDone < iam_model.StepCount-1 { + if iam.SetUpDone < domain.StepCount-1 { return caos_errs.ThrowPreconditionFailed(nil, "HANDL-s5DTs", "Setup not done") } u.iamProjectID = iam.IAMProjectID diff --git a/internal/auth/repository/eventsourcing/repository.go b/internal/auth/repository/eventsourcing/repository.go index 5903edf52c..3d196ee067 100644 --- a/internal/auth/repository/eventsourcing/repository.go +++ b/internal/auth/repository/eventsourcing/repository.go @@ -20,7 +20,7 @@ import ( es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing" es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing" es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing" - iam_business "github.com/caos/zitadel/internal/v2/business/iam" + "github.com/caos/zitadel/internal/v2/query" ) type Config struct { @@ -110,7 +110,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, au return nil, err } - iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) + iamV2Query, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) if err != nil { return nil, err } @@ -182,8 +182,8 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, au SystemDefaults: systemDefaults, }, eventstore.IAMRepository{ - IAMID: systemDefaults.IamID, - IAMV2: iamV2, + IAMID: systemDefaults.IamID, + IAMV2QuerySide: iamV2Query, }, }, nil } diff --git a/internal/authz/repository/eventsourcing/eventstore/iam.go b/internal/authz/repository/eventsourcing/eventstore/iam.go index 8d2ceabb79..78c2f1c1e3 100644 --- a/internal/authz/repository/eventsourcing/eventstore/iam.go +++ b/internal/authz/repository/eventsourcing/eventstore/iam.go @@ -2,17 +2,17 @@ package eventstore import ( "context" + "github.com/caos/zitadel/internal/v2/query" "github.com/caos/zitadel/internal/iam/model" iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing" - iam_business "github.com/caos/zitadel/internal/v2/business/iam" ) type IamRepo struct { IAMID string IAMEvents *iam_event.IAMEventstore - IAMV2 *iam_business.Repository + IAMV2Query *query.QuerySide } func (repo *IamRepo) Health(ctx context.Context) error { @@ -20,5 +20,5 @@ func (repo *IamRepo) Health(ctx context.Context) error { } func (repo *IamRepo) IamByID(ctx context.Context) (*model.IAM, error) { - return repo.IAMV2.IAMByID(ctx, repo.IAMID) + return repo.IAMV2Query.IAMByID(ctx, repo.IAMID) } diff --git a/internal/authz/repository/eventsourcing/eventstore/user_grant.go b/internal/authz/repository/eventsourcing/eventstore/user_grant.go index 0d217fa9ad..6028f3e49a 100644 --- a/internal/authz/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/authz/repository/eventsourcing/eventstore/user_grant.go @@ -6,10 +6,10 @@ import ( "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/authz/repository/eventsourcing/view" caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing" grant_model "github.com/caos/zitadel/internal/usergrant/model" "github.com/caos/zitadel/internal/usergrant/repository/view/model" + "github.com/caos/zitadel/internal/v2/domain" ) type UserGrantRepo struct { @@ -72,7 +72,7 @@ func (repo *UserGrantRepo) FillIamProjectID(ctx context.Context) error { if err != nil { return err } - if iam.SetUpDone < iam_model.StepCount-1 { + if iam.SetUpDone < domain.StepCount-1 { return caos_errs.ThrowPreconditionFailed(nil, "EVENT-skiwS", "Setup not done") } repo.IamProjectID = iam.IAMProjectID diff --git a/internal/authz/repository/eventsourcing/handler/user_grant.go b/internal/authz/repository/eventsourcing/handler/user_grant.go index 58cd01d31c..1c7b829964 100644 --- a/internal/authz/repository/eventsourcing/handler/user_grant.go +++ b/internal/authz/repository/eventsourcing/handler/user_grant.go @@ -12,12 +12,12 @@ import ( "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" iam_events "github.com/caos/zitadel/internal/iam/repository/eventsourcing" iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" view_model "github.com/caos/zitadel/internal/usergrant/repository/view/model" + "github.com/caos/zitadel/internal/v2/domain" ) type UserGrant struct { @@ -224,7 +224,7 @@ func (u *UserGrant) setIamProjectID() error { if err != nil { return err } - if iam.SetUpDone < iam_model.StepCount-1 { + if iam.SetUpDone < domain.StepCount-1 { return caos_errs.ThrowPreconditionFailed(nil, "HANDL-s5DTs", "Setup not done") } u.iamProjectID = iam.IAMProjectID diff --git a/internal/authz/repository/eventsourcing/repository.go b/internal/authz/repository/eventsourcing/repository.go index b27d1b1637..922290cd2d 100644 --- a/internal/authz/repository/eventsourcing/repository.go +++ b/internal/authz/repository/eventsourcing/repository.go @@ -2,6 +2,7 @@ package eventsourcing import ( "context" + "github.com/caos/zitadel/internal/v2/query" es_user "github.com/caos/zitadel/internal/user/repository/eventsourcing" @@ -19,7 +20,6 @@ import ( "github.com/caos/zitadel/internal/id" es_key "github.com/caos/zitadel/internal/key/repository/eventsourcing" es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing" - iam_business "github.com/caos/zitadel/internal/v2/business/iam" ) type Config struct { @@ -79,7 +79,7 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (* if err != nil { return nil, err } - iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) + iamV2, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) if err != nil { return nil, err } @@ -96,9 +96,9 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults) (* IamEvents: iam, }, eventstore.IamRepo{ - IAMID: systemDefaults.IamID, - IAMEvents: iam, - IAMV2: iamV2, + IAMID: systemDefaults.IamID, + IAMEvents: iam, + IAMV2Query: iamV2, }, eventstore.TokenVerifierRepo{ //TODO: Add Token Verification Key diff --git a/internal/errors/generate/error_creator.go b/internal/errors/generate/error_creator.go index 52139196a1..2062161c77 100644 --- a/internal/errors/generate/error_creator.go +++ b/internal/errors/generate/error_creator.go @@ -59,7 +59,7 @@ func (data *Data) createTemplate(templateName string, file *os.File) { } func readErrorName() (errorName string) { - flag.StringVar(&errorName, "Name", "", "Type of the error (e.g. Internal)") + flag.StringVar(&errorName, "Name", "", "KeyType of the error (e.g. Internal)") flag.Parse() return errorName } diff --git a/internal/eventstore/v2/aggregate.go b/internal/eventstore/v2/aggregate.go index 914387488f..71d8b2bfb1 100644 --- a/internal/eventstore/v2/aggregate.go +++ b/internal/eventstore/v2/aggregate.go @@ -3,7 +3,7 @@ package eventstore type aggregater interface { //ID returns the aggreagte id ID() string - //Type returns the aggregate type + //KeyType returns the aggregate type Type() AggregateType //Events returns the events which will be pushed Events() []EventPusher @@ -74,7 +74,7 @@ func (a *Aggregate) ID() string { return a.id } -//Type implements aggregater +//KeyType implements aggregater func (a *Aggregate) Type() AggregateType { return a.typ } diff --git a/internal/eventstore/v2/event.go b/internal/eventstore/v2/event.go index 113cbb1c3f..8b1709d786 100644 --- a/internal/eventstore/v2/event.go +++ b/internal/eventstore/v2/event.go @@ -9,7 +9,7 @@ type EventPusher interface { EditorService() string //EditorUser is the user who wants to push the event EditorUser() string - //Type must return an event type which should be unique in the aggregate + //KeyType must return an event type which should be unique in the aggregate Type() EventType //Data returns the payload of the event. It represent the changed fields by the event // valid types are: @@ -25,7 +25,7 @@ type EventReader interface { EditorService() string //EditorUser is the user who pushed the event EditorUser() string - //Type is the type of the event + //KeyType is the type of the event Type() EventType AggregateID() string diff --git a/internal/eventstore/v2/event_base.go b/internal/eventstore/v2/event_base.go index e8ca680871..3046952c6c 100644 --- a/internal/eventstore/v2/event_base.go +++ b/internal/eventstore/v2/event_base.go @@ -36,7 +36,7 @@ func (e *BaseEvent) EditorUser() string { return e.User } -//Type implements EventPusher +//KeyType implements EventPusher func (e *BaseEvent) Type() EventType { return e.EventType } diff --git a/internal/eventstore/v2/playground/show_case_test.go b/internal/eventstore/v2/playground/show_case_test.go index 297dde2dfc..45c997c6ae 100644 --- a/internal/eventstore/v2/playground/show_case_test.go +++ b/internal/eventstore/v2/playground/show_case_test.go @@ -6,7 +6,7 @@ import ( "log" ) -//ReadModel is the minimum representation of a View model. +//MemberReadModel is the minimum representation of a View model. // it might be saved in a database or in memory type ReadModel struct { ProcessedSequence uint64 diff --git a/internal/eventstore/v2/read_model.go b/internal/eventstore/v2/read_model.go index 6d1e419fe6..976ab34170 100644 --- a/internal/eventstore/v2/read_model.go +++ b/internal/eventstore/v2/read_model.go @@ -2,7 +2,7 @@ package eventstore import "time" -//ReadModel is the minimum representation of a View model. +//MemberReadModel is the minimum representation of a View model. // It implements a basic reducer // it might be saved in a database or in memory type ReadModel struct { diff --git a/internal/eventstore/v2/repository/event.go b/internal/eventstore/v2/repository/event.go index 68ae39ba18..2a174caeaf 100644 --- a/internal/eventstore/v2/repository/event.go +++ b/internal/eventstore/v2/repository/event.go @@ -26,7 +26,7 @@ type Event struct { // time drifts in different services could cause integrity problems CreationDate time.Time - //Type describes the cause of the event (e.g. user.added) + //KeyType describes the cause of the event (e.g. user.added) // it should always be in past-form Type EventType diff --git a/internal/eventstore/v2/write_model.go b/internal/eventstore/v2/write_model.go index 4d46cecb35..420a8aff89 100644 --- a/internal/eventstore/v2/write_model.go +++ b/internal/eventstore/v2/write_model.go @@ -2,7 +2,7 @@ package eventstore import "time" -//WriteModel is the minimum representation of a command side view model. +//MemberWriteModel is the minimum representation of a command side view model. // It implements a basic reducer // it's purpose is to reduce events to create new ones type WriteModel struct { diff --git a/internal/iam/model/iam.go b/internal/iam/model/iam.go index f80ea3b400..19696f3437 100644 --- a/internal/iam/model/iam.go +++ b/internal/iam/model/iam.go @@ -2,6 +2,7 @@ package model import ( es_models "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/v2/domain" ) type Step int @@ -23,8 +24,8 @@ type IAM struct { es_models.ObjectRoot GlobalOrgID string IAMProjectID string - SetUpDone Step - SetUpStarted Step + SetUpDone domain.Step + SetUpStarted domain.Step Members []*IAMMember IDPs []*IDPConfig DefaultLoginPolicy *LoginPolicy diff --git a/internal/iam/model/password_complexity_policy.go b/internal/iam/model/password_complexity_policy.go index 90ee73b4cc..851343ecff 100644 --- a/internal/iam/model/password_complexity_policy.go +++ b/internal/iam/model/password_complexity_policy.go @@ -22,6 +22,8 @@ type PasswordComplexityPolicy struct { HasUppercase bool HasNumber bool HasSymbol bool + + Default bool } func (p *PasswordComplexityPolicy) IsValid() error { @@ -30,3 +32,26 @@ func (p *PasswordComplexityPolicy) IsValid() error { } return nil } + +func (p *PasswordComplexityPolicy) Check(password string) error { + if p.MinLength != 0 && uint64(len(password)) < p.MinLength { + return caos_errs.ThrowInvalidArgument(nil, "MODEL-HuJf6", "Errors.User.PasswordComplexityPolicy.MinLength") + } + + if p.HasLowercase && !hasStringLowerCase(password) { + return caos_errs.ThrowInvalidArgument(nil, "MODEL-co3Xw", "Errors.User.PasswordComplexityPolicy.HasLower") + } + + if p.HasUppercase && !hasStringUpperCase(password) { + return caos_errs.ThrowInvalidArgument(nil, "MODEL-VoaRj", "Errors.User.PasswordComplexityPolicy.HasUpper") + } + + if p.HasNumber && !hasNumber(password) { + return caos_errs.ThrowInvalidArgument(nil, "MODEL-ZBv4H", "Errors.User.PasswordComplexityPolicy.HasNumber") + } + + if p.HasSymbol && !hasSymbol(password) { + return caos_errs.ThrowInvalidArgument(nil, "MODEL-ZDLwA", "Errors.User.PasswordComplexityPolicy.HasSymbol") + } + return nil +} diff --git a/internal/iam/repository/eventsourcing/eventstore.go b/internal/iam/repository/eventsourcing/eventstore.go index 075bbb9cda..3d66ed4dcd 100644 --- a/internal/iam/repository/eventsourcing/eventstore.go +++ b/internal/iam/repository/eventsourcing/eventstore.go @@ -73,49 +73,49 @@ func (es *IAMEventstore) IAMEventsByID(ctx context.Context, id string, sequence return es.FilterEvents(ctx, query) } -func (es *IAMEventstore) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) { - iam, err := es.IAMByID(ctx, iamID) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - - if iam != nil && (iam.SetUpStarted >= step || iam.SetUpStarted != iam.SetUpDone) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "Setup already started") - } - - if iam == nil { - iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: iamID}} - } - iam.SetUpStarted = step - repoIAM := model.IAMFromModel(iam) - - createAggregate := IAMSetupStartedAggregate(es.AggregateCreator(), repoIAM) - err = es_sdk.Push(ctx, es.PushAggregates, repoIAM.AppendEvents, createAggregate) - if err != nil { - return nil, err - } - - es.iamCache.cacheIAM(repoIAM) - return model.IAMToModel(repoIAM), nil -} - -func (es *IAMEventstore) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) { - iam, err := es.IAMByID(ctx, iamID) - if err != nil { - return nil, err - } - iam.SetUpDone = step - - repoIam := model.IAMFromModel(iam) - createAggregate := IAMSetupDoneAggregate(es.AggregateCreator(), repoIam) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate) - if err != nil { - return nil, err - } - - es.iamCache.cacheIAM(repoIam) - return model.IAMToModel(repoIam), nil -} +//func (es *IAMEventstore) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) { +// iam, err := es.IAMByID(ctx, iamID) +// if err != nil && !caos_errs.IsNotFound(err) { +// return nil, err +// } +// +// if iam != nil && (iam.SetUpStarted >= step || iam.SetUpStarted != iam.SetUpDone) { +// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "Setup already started") +// } +// +// if iam == nil { +// iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: iamID}} +// } +// iam.SetUpStarted = step +// repoIAM := model.IAMFromModel(iam) +// +// createAggregate := IAMSetupStartedAggregate(es.AggregateCreator(), repoIAM) +// err = es_sdk.Push(ctx, es.PushAggregates, repoIAM.AppendEvents, createAggregate) +// if err != nil { +// return nil, err +// } +// +// es.iamCache.cacheIAM(repoIAM) +// return model.IAMToModel(repoIAM), nil +//} +// +//func (es *IAMEventstore) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) { +// iam, err := es.IAMByID(ctx, iamID) +// if err != nil { +// return nil, err +// } +// iam.SetUpDone = step +// +// repoIam := model.IAMFromModel(iam) +// createAggregate := IAMSetupDoneAggregate(es.AggregateCreator(), repoIam) +// err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, createAggregate) +// if err != nil { +// return nil, err +// } +// +// es.iamCache.cacheIAM(repoIam) +// return model.IAMToModel(repoIam), nil +//} func (es *IAMEventstore) PrepareSetupDone(ctx context.Context, iam *model.IAM, aggregate *models.Aggregate, step iam_model.Step) (*model.IAM, *models.Aggregate, func(ctx context.Context, aggregates ...*models.Aggregate) error, error) { iam.SetUpDone = model.Step(step) diff --git a/internal/iam/repository/eventsourcing/eventstore_test.go b/internal/iam/repository/eventsourcing/eventstore_test.go index c21dba9fb6..8437a1199e 100644 --- a/internal/iam/repository/eventsourcing/eventstore_test.go +++ b/internal/iam/repository/eventsourcing/eventstore_test.go @@ -1562,7 +1562,7 @@ func TestAddIdpProviderToLoginPolicy(t *testing.T) { t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) } if result.Type != tt.res.result.Type { - t.Errorf("got wrong result Type: expected: %v, actual: %v ", tt.res.result.Type, result.Type) + t.Errorf("got wrong result KeyType: expected: %v, actual: %v ", tt.res.result.Type, result.Type) } }) } diff --git a/internal/iam/repository/eventsourcing/model/iam.go b/internal/iam/repository/eventsourcing/model/iam.go index 0fc19f6dbf..464fa28f64 100644 --- a/internal/iam/repository/eventsourcing/model/iam.go +++ b/internal/iam/repository/eventsourcing/model/iam.go @@ -7,6 +7,7 @@ import ( caos_errs "github.com/caos/zitadel/internal/errors" es_models "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" ) const ( @@ -75,8 +76,8 @@ func IAMToModel(iam *IAM) *model.IAM { idps := IDPConfigsToModel(iam.IDPs) converted := &model.IAM{ ObjectRoot: iam.ObjectRoot, - SetUpStarted: model.Step(iam.SetUpStarted), - SetUpDone: model.Step(iam.SetUpDone), + SetUpStarted: domain.Step(iam.SetUpStarted), + SetUpDone: domain.Step(iam.SetUpDone), GlobalOrgID: iam.GlobalOrgID, IAMProjectID: iam.IAMProjectID, Members: members, diff --git a/internal/management/repository/eventsourcing/eventstore/iam.go b/internal/management/repository/eventsourcing/eventstore/iam.go index 1dc62fd8a4..1024913d4a 100644 --- a/internal/management/repository/eventsourcing/eventstore/iam.go +++ b/internal/management/repository/eventsourcing/eventstore/iam.go @@ -2,15 +2,15 @@ package eventstore import ( "context" + "github.com/caos/zitadel/internal/v2/query" iam_model "github.com/caos/zitadel/internal/iam/model" - iam_business "github.com/caos/zitadel/internal/v2/business/iam" ) type IAMRepository struct { - IAMV2 *iam_business.Repository + IAMV2Query *query.QuerySide } func (repo *IAMRepository) IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) { - return repo.IAMV2.IAMByID(ctx, id) + return repo.IAMV2Query.IAMByID(ctx, id) } diff --git a/internal/management/repository/eventsourcing/repository.go b/internal/management/repository/eventsourcing/repository.go index 50ac45d7c1..d82df93f6a 100644 --- a/internal/management/repository/eventsourcing/repository.go +++ b/internal/management/repository/eventsourcing/repository.go @@ -2,6 +2,7 @@ package eventsourcing import ( "context" + "github.com/caos/zitadel/internal/v2/query" sd "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/config/types" @@ -17,7 +18,6 @@ import ( es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing" es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" es_grant "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing" - iam_business "github.com/caos/zitadel/internal/v2/business/iam" ) type Config struct { @@ -75,7 +75,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe if err != nil { return nil, err } - iamV2, err := iam_business.StartRepository(&iam_business.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) + iamV2Query, err := query.StartQuerySide(&query.Config{Eventstore: esV2, SystemDefaults: systemDefaults}) if err != nil { return nil, err } @@ -98,7 +98,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe UserRepo: eventstore.UserRepo{es, conf.SearchLimit, user, org, usergrant, view, systemDefaults}, UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view}, IAMRepository: eventstore.IAMRepository{ - IAMV2: iamV2, + IAMV2Query: iamV2Query, }, }, nil } diff --git a/internal/notification/providers/email/message.go b/internal/notification/providers/email/message.go index fcd9928355..fdb81b1649 100644 --- a/internal/notification/providers/email/message.go +++ b/internal/notification/providers/email/message.go @@ -32,9 +32,9 @@ func (msg *EmailMessage) GetContent() string { } //default mime-type is html - mime := "MIME-version: 1.0;" + lineBreak + "Content-Type: text/html; charset=\"UTF-8\";" + lineBreak + lineBreak + mime := "MIME-version: 1.0;" + lineBreak + "Content-KeyType: text/html; charset=\"UTF-8\";" + lineBreak + lineBreak if !isHTML(msg.Content) { - mime = "MIME-version: 1.0;" + lineBreak + "Content-Type: text/plain; charset=\"UTF-8\";" + lineBreak + lineBreak + mime = "MIME-version: 1.0;" + lineBreak + "Content-KeyType: text/plain; charset=\"UTF-8\";" + lineBreak + lineBreak } subject := "Subject: " + msg.Subject + lineBreak message += subject + mime + lineBreak + msg.Content diff --git a/internal/org/repository/eventsourcing/eventstore_test.go b/internal/org/repository/eventsourcing/eventstore_test.go index 9470a5f218..b0c1430b8b 100644 --- a/internal/org/repository/eventsourcing/eventstore_test.go +++ b/internal/org/repository/eventsourcing/eventstore_test.go @@ -2637,7 +2637,7 @@ func TestAddIdpProviderToLoginPolicy(t *testing.T) { t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) } if result.Type != tt.res.result.Type { - t.Errorf("got wrong result Type: expected: %v, actual: %v ", tt.res.result.Type, result.Type) + t.Errorf("got wrong result KeyType: expected: %v, actual: %v ", tt.res.result.Type, result.Type) } }) } diff --git a/internal/org/repository/eventsourcing/login_policy_test.go b/internal/org/repository/eventsourcing/login_policy_test.go index fb11d413cb..e4c11d5215 100644 --- a/internal/org/repository/eventsourcing/login_policy_test.go +++ b/internal/org/repository/eventsourcing/login_policy_test.go @@ -314,7 +314,7 @@ func TestLoginPolicyIdpProviderAddedAggregate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyIDPProviderAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx) + agg, err := LoginPolicyIDPProviderAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "iamID")(tt.args.ctx) if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { t.Errorf("got wrong err: %v ", err) return @@ -509,7 +509,7 @@ func TestLoginPolicySecondFactorAddedAggregate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicySecondFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx) + agg, err := LoginPolicySecondFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "iamID")(tt.args.ctx) if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { t.Errorf("got wrong err: %v ", err) return @@ -682,7 +682,7 @@ func TestLoginPolicyMultiFactorAddedAggregate(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyMultiFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "IAMID")(tt.args.ctx) + agg, err := LoginPolicyMultiFactorAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new, "iamID")(tt.args.ctx) if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { t.Errorf("got wrong err: %v ", err) return diff --git a/internal/setup/config.go b/internal/setup/config.go index 93e0d4926b..be3e19099a 100644 --- a/internal/setup/config.go +++ b/internal/setup/config.go @@ -7,28 +7,28 @@ import ( type IAMSetUp struct { Step1 *Step1 - Step2 *Step2 - Step3 *Step3 - Step4 *Step4 - Step5 *Step5 - Step6 *Step6 - Step7 *Step7 - Step8 *Step8 + //Step2 *Step2 + //Step3 *Step3 + //Step4 *Step4 + //Step5 *Step5 + //Step6 *Step6 + //Step7 *Step7 + //Step8 *Step8 } -func (setup *IAMSetUp) steps(currentDone iam_model.Step) ([]step, error) { - steps := make([]step, 0) +func (setup *IAMSetUp) steps(currentDone iam_model.Step) ([]stepV2, error) { + steps := make([]stepV2, 0) missingSteps := make([]iam_model.Step, 0) - for _, step := range []step{ + for _, step := range []stepV2{ setup.Step1, - setup.Step2, - setup.Step3, - setup.Step4, - setup.Step5, - setup.Step6, - setup.Step7, - setup.Step8, + //setup.Step2, + //setup.Step3, + //setup.Step4, + //setup.Step5, + //setup.Step6, + //setup.Step7, + //setup.Step8, } { if step.step() <= currentDone { continue diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 717cd0258f..1e854698d6 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -3,24 +3,12 @@ package setup import ( "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/config/systemdefaults" - "github.com/caos/zitadel/internal/errors" - caos_errs "github.com/caos/zitadel/internal/errors" - es_int "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" - iam_model "github.com/caos/zitadel/internal/iam/model" - es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing" iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing" - es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing" org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing" - proj_model "github.com/caos/zitadel/internal/project/model" - es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing" proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing" - es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" + "github.com/caos/zitadel/internal/v2/command" ) type Setup struct { @@ -29,6 +17,8 @@ type Setup struct { OrgEvents *org_event.OrgEventstore UserEvents *usr_event.UserEventstore ProjectEvents *proj_event.ProjectEventstore + + Commands *command.CommandSide } const ( @@ -48,168 +38,169 @@ const ( OIDCAuthMethodTypePost = "POST" ) -func StartSetup(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) { - setup := &Setup{ - iamID: sd.IamID, - } - es, err := es_int.Start(esConfig) - if err != nil { - return nil, err - } - - setup.IamEvents, err = es_iam.StartIAM(es_iam.IAMConfig{ - Eventstore: es, - Cache: esConfig.Cache, - }, sd) - if err != nil { - return nil, err - } - - setup.OrgEvents = es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: sd.Domain}, sd) - - setup.ProjectEvents, err = es_proj.StartProject(es_proj.ProjectConfig{ - Eventstore: es, - Cache: esConfig.Cache, - }, sd) - if err != nil { - return nil, err - } - - setup.UserEvents, err = es_usr.StartUser(es_usr.UserConfig{ - Eventstore: es, - Cache: esConfig.Cache, - }, sd) - if err != nil { - return nil, err - } - - return setup, nil -} - -func (s *Setup) Execute(ctx context.Context, setUpConfig IAMSetUp) error { - logging.Log("SETUP-hwG32").Info("starting setup") - - iam, err := s.IamEvents.IAMByID(ctx, s.iamID) - if err != nil && !caos_errs.IsNotFound(err) { - return err - } - if iam != nil && (iam.SetUpDone == iam_model.StepCount-1 || iam.SetUpStarted != iam.SetUpDone) { - logging.Log("SETUP-cWEsn").Info("all steps done") - return nil - } - - if iam == nil { - iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: s.iamID}} - } - - steps, err := setUpConfig.steps(iam.SetUpDone) - if err != nil || len(steps) == 0 { - return err - } - - ctx = setSetUpContextData(ctx, s.iamID) - - for _, step := range steps { - step.init(s) - if step.step() != iam.SetUpDone+1 { - logging.LogWithFields("SETUP-rxRM1", "step", step.step(), "previous", iam.SetUpDone).Warn("wrong step order") - return errors.ThrowPreconditionFailed(nil, "SETUP-wwAqO", "too few steps for this zitadel verison") - } - iam, err = s.IamEvents.StartSetup(ctx, s.iamID, step.step()) - if err != nil { - return err - } - - iam, err = step.execute(ctx) - if err != nil { - return err - } - - err = s.validateExecutedStep(ctx) - if err != nil { - return err - } - } - - logging.Log("SETUP-ds31h").Info("setup done") - return nil -} - -func (s *Setup) validateExecutedStep(ctx context.Context) error { - iam, err := s.IamEvents.IAMByID(ctx, s.iamID) - if err != nil { - return err - } - if iam.SetUpStarted != iam.SetUpDone { - return errors.ThrowInternal(nil, "SETUP-QeukK", "started step is not equal to done") - } - return nil -} - -func getOIDCResponseTypes(responseTypes []string) []proj_model.OIDCResponseType { - types := make([]proj_model.OIDCResponseType, len(responseTypes)) - for i, t := range responseTypes { - types[i] = getOIDCResponseType(t) - } - return types -} - -func getOIDCResponseType(responseType string) proj_model.OIDCResponseType { - switch responseType { - case OIDCResponseTypeCode: - return proj_model.OIDCResponseTypeCode - case OIDCResponseTypeIDToken: - return proj_model.OIDCResponseTypeIDToken - case OIDCResponseTypeToken: - return proj_model.OIDCResponseTypeIDTokenToken - } - return proj_model.OIDCResponseTypeCode -} - -func getOIDCGrantTypes(grantTypes []string) []proj_model.OIDCGrantType { - types := make([]proj_model.OIDCGrantType, len(grantTypes)) - for i, t := range grantTypes { - types[i] = getOIDCGrantType(t) - } - return types -} - -func getOIDCGrantType(grantTypes string) proj_model.OIDCGrantType { - switch grantTypes { - case OIDCGrantTypeAuthorizationCode: - return proj_model.OIDCGrantTypeAuthorizationCode - case OIDCGrantTypeImplicit: - return proj_model.OIDCGrantTypeImplicit - case OIDCGrantTypeRefreshToken: - return proj_model.OIDCGrantTypeRefreshToken - } - return proj_model.OIDCGrantTypeAuthorizationCode -} - -func getOIDCApplicationType(appType string) proj_model.OIDCApplicationType { - switch appType { - case OIDCApplicationTypeNative: - return proj_model.OIDCApplicationTypeNative - case OIDCApplicationTypeUserAgent: - return proj_model.OIDCApplicationTypeUserAgent - case OIDCApplicationTypeWeb: - return proj_model.OIDCApplicationTypeWeb - } - return proj_model.OIDCApplicationTypeWeb -} - -func getOIDCAuthMethod(authMethod string) proj_model.OIDCAuthMethodType { - switch authMethod { - case OIDCAuthMethodTypeNone: - return proj_model.OIDCAuthMethodTypeNone - case OIDCAuthMethodTypeBasic: - return proj_model.OIDCAuthMethodTypeBasic - case OIDCAuthMethodTypePost: - return proj_model.OIDCAuthMethodTypePost - } - return proj_model.OIDCAuthMethodTypeBasic -} - +// +//func StartSetup(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) { +// setup := &Setup{ +// iamID: sd.IamID, +// } +// es, err := es_int.Start(esConfig) +// if err != nil { +// return nil, err +// } +// +// setup.IamEvents, err = es_iam.StartIAM(es_iam.IAMConfig{ +// Eventstore: es, +// Cache: esConfig.Cache, +// }, sd) +// if err != nil { +// return nil, err +// } +// +// setup.OrgEvents = es_org.StartOrg(es_org.OrgConfig{Eventstore: es, IAMDomain: sd.Domain}, sd) +// +// setup.ProjectEvents, err = es_proj.StartProject(es_proj.ProjectConfig{ +// Eventstore: es, +// Cache: esConfig.Cache, +// }, sd) +// if err != nil { +// return nil, err +// } +// +// setup.UserEvents, err = es_usr.StartUser(es_usr.UserConfig{ +// Eventstore: es, +// Cache: esConfig.Cache, +// }, sd) +// if err != nil { +// return nil, err +// } +// +// return setup, nil +//} +// +//func (s *Setup) Execute(ctx context.Context, setUpConfig IAMSetUp) error { +// logging.Log("SETUP-hwG32").Info("starting setup") +// +// iam, err := s.IamEvents.IAMByID(ctx, s.iamID) +// if err != nil && !caos_errs.IsNotFound(err) { +// return err +// } +// if iam != nil && (iam.SetUpDone == domain.Step(iam_model.StepCount)-1 || iam.SetUpStarted != iam.SetUpDone) { +// logging.Log("SETUP-cWEsn").Info("all steps done") +// return nil +// } +// +// if iam == nil { +// iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: s.iamID}} +// } +// +// steps, err := setUpConfig.steps(iam_model.Step(iam.SetUpDone)) +// if err != nil || len(steps) == 0 { +// return err +// } +// +// ctx = setSetUpContextData(ctx, s.iamID) +// +// for _, step := range steps { +// step.init(s) +// if step.step() != iam_model.Step(iam.SetUpDone)+1 { +// logging.LogWithFields("SETUP-rxRM1", "step", step.step(), "previous", iam.SetUpDone).Warn("wrong step order") +// return errors.ThrowPreconditionFailed(nil, "SETUP-wwAqO", "too few steps for this zitadel verison") +// } +// iam, err = s.IamEvents.StartSetup(ctx, s.iamID, step.step()) +// if err != nil { +// return err +// } +// +// iam, err = step.execute(ctx) +// if err != nil { +// return err +// } +// +// err = s.validateExecutedStep(ctx) +// if err != nil { +// return err +// } +// } +// +// logging.Log("SETUP-ds31h").Info("setup done") +// return nil +//} +// +//func (s *Setup) validateExecutedStep(ctx context.Context) error { +// iam, err := s.IamEvents.IAMByID(ctx, s.iamID) +// if err != nil { +// return err +// } +// if iam.SetUpStarted != iam.SetUpDone { +// return errors.ThrowInternal(nil, "SETUP-QeukK", "started step is not equal to done") +// } +// return nil +//} +// +//func getOIDCResponseTypes(responseTypes []string) []proj_model.OIDCResponseType { +// types := make([]proj_model.OIDCResponseType, len(responseTypes)) +// for i, t := range responseTypes { +// types[i] = getOIDCResponseType(t) +// } +// return types +//} +// +//func getOIDCResponseType(responseType string) proj_model.OIDCResponseType { +// switch responseType { +// case OIDCResponseTypeCode: +// return proj_model.OIDCResponseTypeCode +// case OIDCResponseTypeIDToken: +// return proj_model.OIDCResponseTypeIDToken +// case OIDCResponseTypeToken: +// return proj_model.OIDCResponseTypeIDTokenToken +// } +// return proj_model.OIDCResponseTypeCode +//} +// +//func getOIDCGrantTypes(grantTypes []string) []proj_model.OIDCGrantType { +// types := make([]proj_model.OIDCGrantType, len(grantTypes)) +// for i, t := range grantTypes { +// types[i] = getOIDCGrantType(t) +// } +// return types +//} +// +//func getOIDCGrantType(grantTypes string) proj_model.OIDCGrantType { +// switch grantTypes { +// case OIDCGrantTypeAuthorizationCode: +// return proj_model.OIDCGrantTypeAuthorizationCode +// case OIDCGrantTypeImplicit: +// return proj_model.OIDCGrantTypeImplicit +// case OIDCGrantTypeRefreshToken: +// return proj_model.OIDCGrantTypeRefreshToken +// } +// return proj_model.OIDCGrantTypeAuthorizationCode +//} +// +//func getOIDCApplicationType(appType string) proj_model.OIDCApplicationType { +// switch appType { +// case OIDCApplicationTypeNative: +// return proj_model.OIDCApplicationTypeNative +// case OIDCApplicationTypeUserAgent: +// return proj_model.OIDCApplicationTypeUserAgent +// case OIDCApplicationTypeWeb: +// return proj_model.OIDCApplicationTypeWeb +// } +// return proj_model.OIDCApplicationTypeWeb +//} +// +//func getOIDCAuthMethod(authMethod string) proj_model.OIDCAuthMethodType { +// switch authMethod { +// case OIDCAuthMethodTypeNone: +// return proj_model.OIDCAuthMethodTypeNone +// case OIDCAuthMethodTypeBasic: +// return proj_model.OIDCAuthMethodTypeBasic +// case OIDCAuthMethodTypePost: +// return proj_model.OIDCAuthMethodTypePost +// } +// return proj_model.OIDCAuthMethodTypeBasic +//} +// func setSetUpContextData(ctx context.Context, orgID string) context.Context { return authz.SetCtxData(ctx, authz.CtxData{UserID: SetupUser, OrgID: orgID}) } diff --git a/internal/setup/setup_v2.go b/internal/setup/setup_v2.go new file mode 100644 index 0000000000..a485029335 --- /dev/null +++ b/internal/setup/setup_v2.go @@ -0,0 +1,104 @@ +package setup + +import ( + "context" + + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/config/systemdefaults" + caos_errs "github.com/caos/zitadel/internal/errors" + es_int "github.com/caos/zitadel/internal/eventstore" + "github.com/caos/zitadel/internal/eventstore/models" + iam_model "github.com/caos/zitadel/internal/iam/model" + es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing" + "github.com/caos/zitadel/internal/v2/command" + "github.com/caos/zitadel/internal/v2/domain" +) + +func StartSetupV2(esConfig es_int.Config, sd systemdefaults.SystemDefaults) (*Setup, error) { + setup := &Setup{ + iamID: sd.IamID, + } + es, err := es_int.Start(esConfig) + if err != nil { + return nil, err + } + + setup.IamEvents, err = es_iam.StartIAM(es_iam.IAMConfig{ + Eventstore: es, + Cache: esConfig.Cache, + }, sd) + if err != nil { + return nil, err + } + + setup.Commands, err = command.StartCommandSide(&command.Config{ + Eventstore: es.V2(), + SystemDefaults: sd, + }) + if err != nil { + return nil, err + } + + return setup, nil +} + +func (s *Setup) ExecuteV2(ctx context.Context, setUpConfig IAMSetUp) error { + logging.Log("SETUP-JAK2q").Info("starting setup") + + iam, err := s.IamEvents.IAMByID(ctx, s.iamID) + if err != nil && !caos_errs.IsNotFound(err) { + return err + } + if iam != nil && (iam.SetUpDone == domain.StepCount-1 || iam.SetUpStarted != iam.SetUpDone) { + logging.Log("SETUP-VA2k1").Info("all steps done") + return nil + } + + if iam == nil { + iam = &iam_model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: s.iamID}} + } + + steps, err := setUpConfig.steps(iam_model.Step(iam.SetUpDone)) + if err != nil || len(steps) == 0 { + return err + } + + ctx = setSetUpContextData(ctx, s.iamID) + + for _, step := range steps { + //step.init(s) + if step.step() != iam_model.Step(iam.SetUpDone+1) { + logging.LogWithFields("SETUP-rxRM1", "step", step.step(), "previous", iam.SetUpDone).Warn("wrong step order") + return caos_errs.ThrowPreconditionFailed(nil, "SETUP-wwAqO", "too few steps for this zitadel verison") + } + iam, err = s.Commands.StartSetup(ctx, s.iamID, domain.Step(step.step())) + if err != nil { + return err + } + + err = step.execute(ctx, iam.AggregateID, *s.Commands) + if err != nil { + return err + } + + err = s.validateExecutedStep(ctx) + if err != nil { + return err + } + } + + logging.Log("SETUP-ds31h").Info("setup done") + return nil +} + +func (s *Setup) validateExecutedStep(ctx context.Context) error { + iam, err := s.IamEvents.IAMByID(ctx, s.iamID) + if err != nil { + return err + } + if iam.SetUpStarted != iam.SetUpDone { + return caos_errs.ThrowInternal(nil, "SETUP-QeukK", "started step is not equal to done") + } + return nil +} diff --git a/internal/setup/step.go b/internal/setup/step.go index f9e497058f..821dbd2d4c 100644 --- a/internal/setup/step.go +++ b/internal/setup/step.go @@ -4,6 +4,7 @@ import ( "context" iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/command" ) type step interface { @@ -12,3 +13,9 @@ type step interface { init(*Setup) isNil() bool } + +type stepV2 interface { + step() iam_model.Step + execute(context.Context, string, command.CommandSide) error + isNil() bool +} diff --git a/internal/setup/step1.go b/internal/setup/step1.go index e7d982723a..5ba31b9b10 100644 --- a/internal/setup/step1.go +++ b/internal/setup/step1.go @@ -4,322 +4,287 @@ import ( "context" "github.com/caos/logging" - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" + iam_model "github.com/caos/zitadel/internal/iam/model" - org_model "github.com/caos/zitadel/internal/org/model" - proj_model "github.com/caos/zitadel/internal/project/model" - usr_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/v2/command" ) type Step1 struct { - GlobalOrg string - IAMProject string - DefaultLoginPolicy LoginPolicy - Orgs []Org - Owners []string + //GlobalOrg string + //IAMProject string + //DefaultLoginPolicy LoginPolicy + //Orgs []Org + //Owners []string + command.Step1 - setup *Setup - createdUsers map[string]*usr_model.User - createdOrgs map[string]*org_model.Org - createdProjects map[string]*proj_model.Project - pwComplexityPolicy *iam_model.PasswordComplexityPolicyView + //setup *Setup + //createdUsers map[string]*usr_model.User + //createdOrgs map[string]*org_model.Org + //createdProjects map[string]*proj_model.Project + //pwComplexityPolicy *iam_model.PasswordComplexityPolicyView } func (s *Step1) isNil() bool { return s == nil } -func (step *Step1) step() iam_model.Step { +func (s *Step1) step() iam_model.Step { return iam_model.Step1 } -func (step *Step1) init(setup *Setup) { - step.setup = setup - step.createdUsers = make(map[string]*usr_model.User) - step.createdOrgs = make(map[string]*org_model.Org) - step.createdProjects = make(map[string]*proj_model.Project) -} +//func (s *Step1) init(setup *Setup) { +// s.setup = setup +// s.createdUsers = make(map[string]*usr_model.User) +// s.createdOrgs = make(map[string]*org_model.Org) +// s.createdProjects = make(map[string]*proj_model.Project) +//} -func (step *Step1) execute(ctx context.Context) (*iam_model.IAM, error) { - err := step.loginPolicy(ctx, step.DefaultLoginPolicy) +func (s *Step1) execute(ctx context.Context, iamID string, commands command.CommandSide) error { + err := commands.SetupStep1(ctx, iamID, s.Step1) if err != nil { - logging.Log("SETUP-Hdu8S").WithError(err).Error("unable to create login policy") - return nil, err - } - - step.pwComplexityPolicy = new(iam_model.PasswordComplexityPolicyView) - - err = step.orgs(ctx, step.Orgs) - if err != nil { - logging.Log("SETUP-p4oWq").WithError(err).Error("unable to set up orgs") - return nil, err - } - - ctx = setSetUpContextData(ctx, step.setup.iamID) - err = step.iamOwners(ctx, step.Owners) - if err != nil { - logging.Log("SETUP-WHr01").WithError(err).Error("unable to set up iam owners") - return nil, err - } - - err = step.setGlobalOrg(ctx, step.GlobalOrg) - if err != nil { - logging.Log("SETUP-0874m").WithError(err).Error("unable to set global org") - return nil, err - } - - err = step.setIamProject(ctx, step.IAMProject) - if err != nil { - logging.Log("SETUP-kaWjq").WithError(err).Error("unable to set zitadel project") - return nil, err - } - - iam, err := step.setup.IamEvents.SetupDone(ctx, step.setup.iamID, step.step()) - if err != nil { - logging.Log("SETUP-de342").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam, nil -} - -func (step *Step1) loginPolicy(ctx context.Context, policy LoginPolicy) error { - logging.Log("SETUP-4djul").Info("setting up login policy") - loginPolicy := &iam_model.LoginPolicy{ - ObjectRoot: models.ObjectRoot{ - AggregateID: step.setup.iamID, - }, - AllowRegister: policy.AllowRegister, - AllowUsernamePassword: policy.AllowUsernamePassword, - AllowExternalIdp: policy.AllowExternalIdp, - } - _, err := step.setup.IamEvents.AddLoginPolicy(ctx, loginPolicy) - return err -} - -func (step *Step1) orgs(ctx context.Context, orgs []Org) error { - logging.Log("SETUP-dsTh3").Info("setting up orgs") - for _, iamOrg := range orgs { - org, err := step.org(ctx, iamOrg) - if err != nil { - logging.LogWithFields("SETUP-IlLif", "Org", iamOrg.Name).WithError(err).Error("unable to create org") - return err - } - step.createdOrgs[iamOrg.Name] = org - logging.LogWithFields("SETUP-HR2gh", "name", org.Name, "ID", org.AggregateID).Info("created organisation") - - var policy *iam_model.OrgIAMPolicyView - if iamOrg.OrgIamPolicy { - policy, err = step.iamorgpolicy(ctx, org) - if err != nil { - logging.LogWithFields("SETUP-IlLif", "Org IAM Policy", iamOrg.Name).WithError(err).Error("unable to create iam org policy") - return err - } - } else { - policy = &iam_model.OrgIAMPolicyView{ - UserLoginMustBeDomain: true, - } - } - - ctx = setSetUpContextData(ctx, org.AggregateID) - err = step.users(ctx, iamOrg.Users, policy) - if err != nil { - logging.LogWithFields("SETUP-8zfwz", "Org", iamOrg.Name).WithError(err).Error("unable to set up org users") - return err - } - - err = step.orgOwners(ctx, org, iamOrg.Owners) - if err != nil { - logging.LogWithFields("SETUP-0874m", "Org", iamOrg.Name).WithError(err).Error("unable to set up org owners") - return err - } - - err = step.projects(ctx, iamOrg.Projects, step.createdUsers[iamOrg.Owners[0]].AggregateID) - if err != nil { - logging.LogWithFields("SETUP-wUzqY", "Org", iamOrg.Name).WithError(err).Error("unable to set up org projects") - return err - } - } - logging.Log("SETUP-dgjT4").Info("orgs set up") - return nil -} - -func (step *Step1) org(ctx context.Context, org Org) (*org_model.Org, error) { - ctx = setSetUpContextData(ctx, "") - createOrg := &org_model.Org{ - Name: org.Name, - Domains: []*org_model.OrgDomain{{Domain: org.Domain}}, - } - return step.setup.OrgEvents.CreateOrg(ctx, createOrg, nil) -} - -func (step *Step1) iamorgpolicy(ctx context.Context, org *org_model.Org) (*iam_model.OrgIAMPolicyView, error) { - ctx = setSetUpContextData(ctx, org.AggregateID) - policy := &iam_model.OrgIAMPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID}, - UserLoginMustBeDomain: false, - } - createdpolicy, err := step.setup.OrgEvents.AddOrgIAMPolicy(ctx, policy) - if err != nil { - return nil, err - } - return &iam_model.OrgIAMPolicyView{ - AggregateID: org.AggregateID, - UserLoginMustBeDomain: createdpolicy.UserLoginMustBeDomain, - }, nil -} - -func (step *Step1) iamOwners(ctx context.Context, owners []string) error { - logging.Log("SETUP-dtxfj").Info("setting iam owners") - for _, iamOwner := range owners { - user, ok := step.createdUsers[iamOwner] - if !ok { - logging.LogWithFields("SETUP-8siew", "Owner", iamOwner).Error("unable to add user to iam members") - return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-su6L3", "unable to add user to iam members") - } - _, err := step.setup.IamEvents.AddIAMMember(ctx, &iam_model.IAMMember{ObjectRoot: models.ObjectRoot{AggregateID: step.setup.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}}) - if err != nil { - logging.Log("SETUP-LM7rI").WithError(err).Error("unable to add iam administrator to iam members as owner") - return err - } - } - logging.Log("SETUP-fg5aq").Info("iam owners set") - return nil -} - -func (step *Step1) setGlobalOrg(ctx context.Context, globalOrgName string) error { - logging.Log("SETUP-dsj75").Info("setting global org") - globalOrg, ok := step.createdOrgs[globalOrgName] - if !ok { - logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", globalOrgName).Error("global org not created") - return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", globalOrgName) - } - - if _, err := step.setup.IamEvents.SetGlobalOrg(ctx, step.setup.iamID, globalOrg.AggregateID); err != nil { - logging.Log("SETUP-uGMA3").WithError(err).Error("unable to set global org on iam") + logging.Log("SETUP-de342").WithField("step", s.step()).WithError(err).Error("unable to finish setup") return err } - logging.Log("SETUP-d32h1").Info("global org set") return nil } -func (step *Step1) setIamProject(ctx context.Context, iamProjectName string) error { - logging.Log("SETUP-HE3qa").Info("setting iam project") - iamProject, ok := step.createdProjects[iamProjectName] - if !ok { - logging.LogWithFields("SETUP-SJFWP", "IAM Project", iamProjectName).Error("iam project created") - return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", iamProjectName) - } - - if _, err := step.setup.IamEvents.SetIAMProject(ctx, step.setup.iamID, iamProject.AggregateID); err != nil { - logging.Log("SETUP-i1pNh").WithError(err).Error("unable to set iam project on iam") - return err - } - logging.Log("SETUP-d7WEU").Info("iam project set") - return nil -} - -func (step *Step1) users(ctx context.Context, users []User, orgPolicy *iam_model.OrgIAMPolicyView) error { - for _, user := range users { - created, err := step.user(ctx, user, orgPolicy) - if err != nil { - logging.LogWithFields("SETUP-9soer", "Email", user.Email).WithError(err).Error("unable to create iam user") - return err - } - step.createdUsers[user.Email] = created - } - return nil -} - -func (step *Step1) user(ctx context.Context, user User, orgPolicy *iam_model.OrgIAMPolicyView) (*usr_model.User, error) { - createUser := &usr_model.User{ - UserName: user.UserName, - Human: &usr_model.Human{ - Profile: &usr_model.Profile{ - FirstName: user.FirstName, - LastName: user.LastName, - }, - Email: &usr_model.Email{ - EmailAddress: user.Email, - IsEmailVerified: true, - }, - Password: &usr_model.Password{ - SecretString: user.Password, - }, - }, - } - return step.setup.UserEvents.CreateUser(ctx, createUser, step.pwComplexityPolicy, orgPolicy) -} - -func (step *Step1) orgOwners(ctx context.Context, org *org_model.Org, owners []string) error { - for _, orgOwner := range owners { - user, ok := step.createdUsers[orgOwner] - if !ok { - logging.LogWithFields("SETUP-s9ilr", "Owner", orgOwner).Error("unable to add user to org members") - return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-s0prs", "unable to add user to org members: %v", orgOwner) - } - err := step.orgOwner(ctx, org, user) - if err != nil { - logging.Log("SETUP-s90oe").WithError(err).Error("unable to add global org admin to members of global org") - return err - } - } - return nil -} - -func (step *Step1) orgOwner(ctx context.Context, org *org_model.Org, user *usr_model.User) error { - addMember := &org_model.OrgMember{ - ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID}, - UserID: user.AggregateID, - Roles: []string{OrgOwnerRole}, - } - _, err := step.setup.OrgEvents.AddOrgMember(ctx, addMember) - return err -} - -func (step *Step1) projects(ctx context.Context, projects []Project, ownerID string) error { - ctxData := authz.GetCtxData(ctx) - ctxData.UserID = ownerID - projectCtx := authz.SetCtxData(ctx, ctxData) - - for _, project := range projects { - createdProject, err := step.project(projectCtx, project) - if err != nil { - return err - } - step.createdProjects[createdProject.Name] = createdProject - for _, oidc := range project.OIDCApps { - app, err := step.oidcApp(ctx, createdProject, oidc) - if err != nil { - return err - } - logging.LogWithFields("SETUP-asd32f", "name", app.Name, "clientID", app.OIDCConfig.ClientID).Info("created OIDC application") - } - } - return nil -} - -func (step *Step1) project(ctx context.Context, project Project) (*proj_model.Project, error) { - addProject := &proj_model.Project{ - Name: project.Name, - } - return step.setup.ProjectEvents.CreateProject(ctx, addProject, false) -} - -func (step *Step1) oidcApp(ctx context.Context, project *proj_model.Project, oidc OIDCApp) (*proj_model.Application, error) { - addOIDCApp := &proj_model.Application{ - ObjectRoot: models.ObjectRoot{AggregateID: project.AggregateID}, - Name: oidc.Name, - OIDCConfig: &proj_model.OIDCConfig{ - RedirectUris: oidc.RedirectUris, - ResponseTypes: getOIDCResponseTypes(oidc.ResponseTypes), - GrantTypes: getOIDCGrantTypes(oidc.GrantTypes), - ApplicationType: getOIDCApplicationType(oidc.ApplicationType), - AuthMethodType: getOIDCAuthMethod(oidc.AuthMethodType), - PostLogoutRedirectUris: oidc.PostLogoutRedirectUris, - DevMode: oidc.DevMode, - }, - } - return step.setup.ProjectEvents.AddApplication(ctx, addOIDCApp) -} +// +//func (step *Step1) loginPolicy(ctx context.Context, policy LoginPolicy) error { +// logging.Log("SETUP-4djul").Info("setting up login policy") +// loginPolicy := &iam_model.LoginPolicy{ +// ObjectRoot: models.ObjectRoot{ +// AggregateID: step.setup.iamID, +// }, +// AllowRegister: policy.AllowRegister, +// AllowUsernamePassword: policy.AllowUsernamePassword, +// AllowExternalIdp: policy.AllowExternalIdp, +// } +// _, err := step.setup.Commands.AddDefaultLoginPolicy(ctx, loginPolicy) +// return err +//} +// +//func (step *Step1) orgs(ctx context.Context, orgs []Org) error { +// logging.Log("SETUP-dsTh3").Info("setting up orgs") +// for _, iamOrg := range orgs { +// org, err := step.org(ctx, iamOrg) +// if err != nil { +// logging.LogWithFields("SETUP-IlLif", "Org", iamOrg.Name).WithError(err).Error("unable to create org") +// return err +// } +// step.createdOrgs[iamOrg.Name] = org +// logging.LogWithFields("SETUP-HR2gh", "name", org.Name, "ID", org.AggregateID).Info("created organisation") +// +// var policy *iam_model.OrgIAMPolicyView +// if iamOrg.OrgIamPolicy { +// policy, err = step.iamorgpolicy(ctx, org) +// if err != nil { +// logging.LogWithFields("SETUP-IlLif", "Org IAM Policy", iamOrg.Name).WithError(err).Error("unable to create iam org policy") +// return err +// } +// } else { +// policy = &iam_model.OrgIAMPolicyView{ +// UserLoginMustBeDomain: true, +// } +// } +// +// ctx = setSetUpContextData(ctx, org.AggregateID) +// err = step.users(ctx, iamOrg.Users, policy) +// if err != nil { +// logging.LogWithFields("SETUP-8zfwz", "Org", iamOrg.Name).WithError(err).Error("unable to set up org users") +// return err +// } +// +// err = step.orgOwners(ctx, org, iamOrg.Owners) +// if err != nil { +// logging.LogWithFields("SETUP-0874m", "Org", iamOrg.Name).WithError(err).Error("unable to set up org owners") +// return err +// } +// +// err = step.projects(ctx, iamOrg.Projects, step.createdUsers[iamOrg.Owners[0]].AggregateID) +// if err != nil { +// logging.LogWithFields("SETUP-wUzqY", "Org", iamOrg.Name).WithError(err).Error("unable to set up org projects") +// return err +// } +// } +// logging.Log("SETUP-dgjT4").Info("orgs set up") +// return nil +//} +// +//func (step *Step1) org(ctx context.Context, org Org) (*org_model.Org, error) { +// ctx = setSetUpContextData(ctx, "") +// createOrg := &org_model.Org{ +// Name: org.Name, +// Domains: []*org_model.OrgDomain{{Domain: org.Domain}}, +// } +// return step.setup.OrgEvents.CreateOrg(ctx, createOrg, nil) +//} +// +//func (step *Step1) iamorgpolicy(ctx context.Context, org *org_model.Org) (*iam_model.OrgIAMPolicyView, error) { +// ctx = setSetUpContextData(ctx, org.AggregateID) +// policy := &iam_model.OrgIAMPolicy{ +// ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID}, +// UserLoginMustBeDomain: false, +// } +// createdpolicy, err := step.setup.OrgEvents.AddOrgIAMPolicy(ctx, policy) +// if err != nil { +// return nil, err +// } +// return &iam_model.OrgIAMPolicyView{ +// AggregateID: org.AggregateID, +// UserLoginMustBeDomain: createdpolicy.UserLoginMustBeDomain, +// }, nil +//} +// +//func (step *Step1) iamOwners(ctx context.Context, owners []string) error { +// logging.Log("SETUP-dtxfj").Info("setting iam owners") +// for _, iamOwner := range owners { +// user, ok := step.createdUsers[iamOwner] +// if !ok { +// logging.LogWithFields("SETUP-8siew", "Owner", iamOwner).Error("unable to add user to iam members") +// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-su6L3", "unable to add user to iam members") +// } +// _, err := step.setup.Commands.AddIAMMember(ctx, &iam_model.IAMMember{ObjectRoot: models.ObjectRoot{AggregateID: step.setup.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}}) +// if err != nil { +// logging.Log("SETUP-LM7rI").WithError(err).Error("unable to add iam administrator to iam members as owner") +// return err +// } +// } +// logging.Log("SETUP-fg5aq").Info("iam owners set") +// return nil +//} +// +//func (step *Step1) setGlobalOrg(ctx context.Context, globalOrgName string) error { +// logging.Log("SETUP-dsj75").Info("setting global org") +// globalOrg, ok := step.createdOrgs[globalOrgName] +// if !ok { +// logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", globalOrgName).Error("global org not created") +// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", globalOrgName) +// } +// +// if _, err := step.setup.IamEvents.SetGlobalOrg(ctx, step.setup.iamID, globalOrg.AggregateID); err != nil { +// logging.Log("SETUP-uGMA3").WithError(err).Error("unable to set global org on iam") +// return err +// } +// logging.Log("SETUP-d32h1").Info("global org set") +// return nil +//} +// +//func (step *Step1) setIamProject(ctx context.Context, iamProjectName string) error { +// logging.Log("SETUP-HE3qa").Info("setting iam project") +// iamProject, ok := step.createdProjects[iamProjectName] +// if !ok { +// logging.LogWithFields("SETUP-SJFWP", "IAM Project", iamProjectName).Error("iam project created") +// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", iamProjectName) +// } +// +// if _, err := step.setup.IamEvents.SetIAMProject(ctx, step.setup.iamID, iamProject.AggregateID); err != nil { +// logging.Log("SETUP-i1pNh").WithError(err).Error("unable to set iam project on iam") +// return err +// } +// logging.Log("SETUP-d7WEU").Info("iam project set") +// return nil +//} +// +//func (step *Step1) users(ctx context.Context, users []User, orgPolicy *iam_model.OrgIAMPolicyView) error { +// for _, user := range users { +// created, err := step.user(ctx, user, orgPolicy) +// if err != nil { +// logging.LogWithFields("SETUP-9soer", "Email", user.Email).WithError(err).Error("unable to create iam user") +// return err +// } +// step.createdUsers[user.Email] = created +// } +// return nil +//} +// +//func (step *Step1) user(ctx context.Context, user User, orgPolicy *iam_model.OrgIAMPolicyView) (*usr_model.User, error) { +// createUser := &usr_model.User{ +// UserName: user.UserName, +// Human: &usr_model.Human{ +// Profile: &usr_model.Profile{ +// FirstName: user.FirstName, +// LastName: user.LastName, +// }, +// Email: &usr_model.Email{ +// EmailAddress: user.Email, +// IsEmailVerified: true, +// }, +// Password: &usr_model.Password{ +// SecretString: user.Password, +// }, +// }, +// } +// return step.setup.UserEvents.CreateUser(ctx, createUser, step.pwComplexityPolicy, orgPolicy) +//} +// +//func (step *Step1) orgOwners(ctx context.Context, org *org_model.Org, owners []string) error { +// for _, orgOwner := range owners { +// user, ok := step.createdUsers[orgOwner] +// if !ok { +// logging.LogWithFields("SETUP-s9ilr", "Owner", orgOwner).Error("unable to add user to org members") +// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-s0prs", "unable to add user to org members: %v", orgOwner) +// } +// err := step.orgOwner(ctx, org, user) +// if err != nil { +// logging.Log("SETUP-s90oe").WithError(err).Error("unable to add global org admin to members of global org") +// return err +// } +// } +// return nil +//} +// +//func (step *Step1) orgOwner(ctx context.Context, org *org_model.Org, user *usr_model.User) error { +// addMember := &org_model.OrgMember{ +// ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID}, +// UserID: user.AggregateID, +// Roles: []string{OrgOwnerRole}, +// } +// _, err := step.setup.OrgEvents.AddOrgMember(ctx, addMember) +// return err +//} +// +//func (step *Step1) projects(ctx context.Context, projects []Project, ownerID string) error { +// ctxData := authz.GetCtxData(ctx) +// ctxData.UserID = ownerID +// projectCtx := authz.SetCtxData(ctx, ctxData) +// +// for _, project := range projects { +// createdProject, err := step.project(projectCtx, project) +// if err != nil { +// return err +// } +// step.createdProjects[createdProject.Name] = createdProject +// for _, oidc := range project.OIDCApps { +// app, err := step.oidcApp(ctx, createdProject, oidc) +// if err != nil { +// return err +// } +// logging.LogWithFields("SETUP-asd32f", "name", app.Name, "clientID", app.OIDCConfig.ClientID).Info("created OIDC application") +// } +// } +// return nil +//} +// +//func (step *Step1) project(ctx context.Context, project Project) (*proj_model.Project, error) { +// addProject := &proj_model.Project{ +// Name: project.Name, +// } +// return step.setup.ProjectEvents.CreateProject(ctx, addProject, false) +//} +// +//func (step *Step1) oidcApp(ctx context.Context, project *proj_model.Project, oidc OIDCApp) (*proj_model.Application, error) { +// addOIDCApp := &proj_model.Application{ +// ObjectRoot: models.ObjectRoot{AggregateID: project.AggregateID}, +// Name: oidc.Name, +// OIDCConfig: &proj_model.OIDCConfig{ +// RedirectUris: oidc.RedirectUris, +// ResponseTypes: getOIDCResponseTypes(oidc.ResponseTypes), +// GrantTypes: getOIDCGrantTypes(oidc.GrantTypes), +// ApplicationType: getOIDCApplicationType(oidc.ApplicationType), +// AuthMethodType: getOIDCAuthMethod(oidc.AuthMethodType), +// PostLogoutRedirectUris: oidc.PostLogoutRedirectUris, +// DevMode: oidc.DevMode, +// }, +// } +// return step.setup.ProjectEvents.AddApplication(ctx, addOIDCApp) +//} diff --git a/internal/setup/step2.go b/internal/setup/step2.go index 6517b35c84..bac8d0583f 100644 --- a/internal/setup/step2.go +++ b/internal/setup/step2.go @@ -2,11 +2,13 @@ package setup import ( "context" + "github.com/caos/logging" + "github.com/caos/zitadel/internal/eventstore/models" - es_sdk "github.com/caos/zitadel/internal/eventstore/sdk" iam_model "github.com/caos/zitadel/internal/iam/model" iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" + "github.com/caos/zitadel/internal/v2/command" ) type Step2 struct { @@ -27,23 +29,25 @@ func (step *Step2) init(setup *Setup) { step.setup = setup } -func (step *Step2) execute(ctx context.Context) (*iam_model.IAM, error) { - iam, agg, err := step.passwordComplexityPolicy(ctx, &step.DefaultPasswordComplexityPolicy) - if err != nil { - logging.Log("SETUP-Ms9fl").WithField("step", step.step()).WithError(err).Error("unable to finish setup (pw complexity policy)") - return nil, err - } - iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) - if err != nil { - logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)") - return nil, err - } - err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg) - if err != nil { - logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam_es_model.IAMToModel(iam), nil +func (step *Step2) execute(ctx context.Context, commands command.CommandSide) error { + //commands.SetupStep2(ctx, ) + //iam, agg, err := step.passwordComplexityPolicy(ctx, &step.DefaultPasswordComplexityPolicy) + //if err != nil { + // logging.Log("SETUP-Ms9fl").WithField("step", step.step()).WithError(err).Error("unable to finish setup (pw complexity policy)") + // return nil, err + //} + //iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) + //if err != nil { + // logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup (prepare setup done)") + // return nil, err + //} + //err = es_sdk.PushAggregates(ctx, push, iam.AppendEvents, agg) + //if err != nil { + // logging.Log("SETUP-V8sui").WithField("step", step.step()).WithError(err).Error("unable to finish setup") + // return nil, err + //} + //return iam_es_model.IAMToModel(iam), nil + return nil } func (step *Step2) passwordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_es_model.IAM, *models.Aggregate, error) { diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index ac68d86282..1749bdc67c 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -17,15 +17,21 @@ Errors: NotLocked: Benutzer ist nicht gesperrt NoChanges: Keine Änderungen gefunden InitCodeNotFound: Kein Initialisierungs Code gefunden - ProfileNotFound: Profil nicht gefunden - ProfileInvalid: Profildaten sind ungültig - EmailNotFound: Email nicht gefunden - EmailInvalid: Email ist ungültig - EmailAlreadyVerified: Email ist bereits verifiziert + Profile: + NotFound: Profil nicht gefunden + NotChanged: Profile nicht verändert + Invalid: Profildaten sind ungültig + Email: + NotFound: Email nicht gefunden + Invalid: Email ist ungültig + AlreadyVerified: Email ist bereits verifiziert + NotChanged: Email wurde nicht geändert PhoneNotFound: Telfonnummer nicht gefunden PhoneInvalid: Telefonnummer ist ungültig PhoneAlreadyVerified: Telefonnummer bereits verifiziert - AddressNotFound: Addresse nicht gefunden + Address: + NotFound: Addresse nicht gefunden + NotChanged: Addresse wurde nicht geändert NotHuman: Der Benutzer muss eine Person sein NotMachine: Der Benutzer muss technisch sein NotAllowedToLink: Der Benutzer darf nicht mit einem externen Login Provider verlinkt werden @@ -164,6 +170,8 @@ Errors: GrantHasNotExistingRole: Eine der Rollen existiert nicht auf dem Projekt UserIDMisisng: User ID fehlt IAM: + Member: + RolesNotChanged: Rollen wurden nicht verändert MemberInvalid: Member ist ungültig MemberAlreadyExisting: Member existiert bereits MemberNotExisting: Member existiert nicht @@ -179,6 +187,7 @@ Errors: IdpProviderInvalid: Idp Provider ist ungültig LoginPolicy: NotFound: Default Login Policy konnte nicht gefunden + NotChanged: Default Login Policy wurde nicht verändert NotExisting: Default Login Policy existiert nicht AlreadyExists: Default Login Policy existiert bereits IdpProviderAlreadyExisting: Idp Provider existiert bereits @@ -187,28 +196,41 @@ Errors: AlreadyExists: Multifaktor existiert bereits NotExisting: Multifaktor existiert nicht Unspecified: Multifaktor ungültig + IDP: + AlreadyExists: Identitäts Provider existiert bereits + NotExisting: Identitäts Provider existiert nicht + IDPConfig: + AlreadyExists: Identitäts Provider Konfiguration existiert bereits + NotExisting: Identitäts Provider Konfiguration existiert nicht + NotInactive: Identitäts Provider Konfiguration nicht inaktive + NotActive: Identitäts Provider Konfiguration nicht aktive LabelPolicy: NotFound: Default Private Label Policy konnte nicht gefunden + NotChanged: Default Private Label Policy wurde nicht verändert PasswordComplexityPolicy: NotFound: Default Password Complexity Policy konnte nicht gefunden werden NotExisting: Default Password Complexity Policy existiert nicht AlreadyExists: Default Password Complexity Policy existiert bereits Empty: Default Password Complexity Policy leer + NotChanged: Default Password Complexity Policy wurde nicht verändert PasswordAgePolicy: NotFound: Default Password Age Policy konnte nicht gefunden werden NotExisting: Default Password Age Policy existiert nicht AlreadyExists: Default Password Age Policy existiert bereits Empty: Default Password Age Policy leer + NotChanged: Default Password Age Policy wurde nicht verändert PasswordLockoutPolicy: NotFound: Default Password Lockout Policy konnte nicht gefunden werden NotExisting: Default Password Lockout Policy existiert nicht AlreadyExists: Default Password Lockout Policy existiert bereits Empty: Default Password Lockout Policy leer + NotChanged: Default Password Lockout Policy wurde nicht verändert OrgIAMPolicy: NotFound: Default Org IAM Policy konnte nicht gefunden werden NotExisting: Default Org IAM Policy existiert nicht AlreadyExists: Default Org IAM Policy existiert bereits Empty: Default Org IAM Policy leer + NotChanged: Default Org IAM Policy wurde nicht verändert Policy: AlreadyExists: Policy existiert bereits UserGrant: diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index fd6a101090..6ae31d5862 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -17,15 +17,21 @@ Errors: NotLocked: User is not locked NoChanges: No changes found InitCodeNotFound: Initialization Code not found - ProfileNotFound: Profile not found - ProfileInvalid: Profildata invalid - EmailNotFound: Email not found - EmailInvalid: Email is invalid - EmailAlreadyVerified: Email is alredy verified + Profile: + NotFound: Profile not found + NotChanged: Profile not changed + Invalid: Profildata invalid + Email: + NotFound: Email not found + Invalid: Email is invalid + AlreadyVerified: Email is alredy verified + NotChanged: Email not changed PhoneNotFound: Phone not found PhoneInvalid: Phone is invalid PhoneAlreadyVerified: Phone already verified - AddressNotFound: Address not found + Address: + NotFound: Address not found + NotChanged: Address not changed NotHuman: The User must be personal NotMachine: The User must be technical NotAllowedToLink: User is not allowed to link with external login provider @@ -164,6 +170,8 @@ Errors: GrantHasNotExistingRole: One role doesn't exist on project UserIDMisisng: User ID missing IAM: + Member: + RolesNotChanged: Roles habe not been changed MemberInvalid: Member is invalid MemberAlreadyExisting: Member already exists MemberNotExisting: Member does not exist @@ -179,6 +187,7 @@ Errors: IdpProviderInvalid: Idp Provider is invalid LoginPolicy: NotFound: Default Login Policy not found + NotChanged: Default Login Policy has not been changed NotExisting: Default Login Policy not existig AlreadyExists: Default Login Policy already exists IdpProviderAlreadyExisting: Idp Provider already existing @@ -187,28 +196,38 @@ Errors: AlreadyExists: Multifactor already exists NotExisting: Multifactor not existing Unspecified: Multifactor invalid + IDPConfig: + AlreadyExists: Identity Provider Configuration already exists + NotExisting: Identity Provider Configuration doesn't exist + NotInactive: Identity Provider Configuration not inactive + NotActive: Identity Provider Configuration not active LabelPolicy: NotFound: Default Private Label Policy not found + NotChanged: Default Private Label Policy has not been changed PasswordComplexityPolicy: NotFound: Default Private Label Policy not found NotExisting: Default Password Complexity Policy not existing AlreadyExists: Default Password Complexity Policy already existing Empty: Default Password Complexity Policy empty + NotChanged: Default Password Complexity Policy has not been changed PasswordAgePolicy: NotFound: Default Password Age Policy not found NotExisting: Default Password Age Policy not existing AlreadyExists: Default Password Age Policy already existing Empty: Default Password Age Policy empty + NotChanged: Default Password Age Policy has not been changed PasswordLockoutPolicy: NotFound: Default Password Lockout Policy not found NotExisting: Default Password Lockout Policy not existing AlreadyExists: Default Password Lockout Policy already existing Empty: Default Password Lockout Policy empty + NotChanged: Default Password Lockout Policy has not been changed OrgIAMPolicy: NotFound: Org IAM Policy not found Empty: Org IAM Policy is empty NotExisting: Org IAM Policy not existing AlreadyExists: Org IAM Policy already exists + NotChanged: Org IAM Policy has not been changed Policy: AlreadyExists: Policy already exists UserGrant: diff --git a/internal/user/model/user_human.go b/internal/user/model/user_human.go index c1af161fd5..838f3b753f 100644 --- a/internal/user/model/user_human.go +++ b/internal/user/model/user_human.go @@ -2,6 +2,8 @@ package model import ( "bytes" + caos_errors "github.com/caos/zitadel/internal/errors" + "strings" "time" iam_model "github.com/caos/zitadel/internal/iam/model" @@ -11,6 +13,8 @@ import ( ) type Human struct { + es_models.ObjectRoot + *Password *Profile *Email @@ -44,6 +48,19 @@ const ( GenderDiverse ) +func (u *Human) CheckOrgIAMPolicy(userName string, policy *iam_model.OrgIAMPolicy) error { + if policy == nil { + return caos_errors.ThrowPreconditionFailed(nil, "MODEL-zSH7j", "Errors.Users.OrgIamPolicyNil") + } + if policy.UserLoginMustBeDomain && strings.Contains(userName, "@") { + return caos_errors.ThrowPreconditionFailed(nil, "MODEL-se4sJ", "Errors.User.EmailAsUsernameNotAllowed") + } + if !policy.UserLoginMustBeDomain && u.Profile != nil && userName == "" && u.Email != nil { + userName = u.EmailAddress + } + return nil +} + func (u *Human) SetNamesAsDisplayname() { if u.Profile != nil && u.DisplayName == "" && u.FirstName != "" && u.LastName != "" { u.DisplayName = u.FirstName + " " + u.LastName diff --git a/internal/user/repository/eventsourcing/eventstore.go b/internal/user/repository/eventsourcing/eventstore.go index 447351435f..5d23d50447 100644 --- a/internal/user/repository/eventsourcing/eventstore.go +++ b/internal/user/repository/eventsourcing/eventstore.go @@ -862,13 +862,13 @@ func (es *UserEventstore) ProfileByID(ctx context.Context, userID string) (*usr_ if user.Profile != nil { return user.Profile, nil } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-dk23f", "Errors.User.ProfileNotFound") + return nil, caos_errs.ThrowNotFound(nil, "EVENT-dk23f", "Errors.User.Profile.NotFound") } func (es *UserEventstore) ChangeProfile(ctx context.Context, profile *usr_model.Profile) (*usr_model.Profile, error) { profile.SetNamesAsDisplayname() if !profile.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-d82i3", "Errors.User.ProfileInvalid") + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-d82i3", "Errors.User.Profile.Invalid") } user, err := es.HumanByID(ctx, profile.AggregateID) if err != nil { @@ -897,12 +897,12 @@ func (es *UserEventstore) EmailByID(ctx context.Context, userID string) (*usr_mo if user.Email != nil { return user.Email, nil } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-dki89", "Errors.User.EmailNotFound") + return nil, caos_errs.ThrowNotFound(nil, "EVENT-dki89", "Errors.User.Email.NotFound") } func (es *UserEventstore) ChangeEmail(ctx context.Context, email *usr_model.Email) (*usr_model.Email, error) { if !email.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-lco09", "Errors.User.EmailInvalid") + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-lco09", "Errors.User.Email.Invalid") } user, err := es.HumanByID(ctx, email.AggregateID) if err != nil { @@ -975,10 +975,10 @@ func (es *UserEventstore) CreateEmailVerificationCode(ctx context.Context, userI return errors.ThrowPreconditionFailed(nil, "EVENT-E3fbw", "Errors.User.NotInitialised") } if user.Email == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.EmailNotFound") + return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.Email.NotFound") } if user.IsEmailVerified { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.EmailAlreadyVerified") + return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.Email.AlreadyVerified") } emailCode := new(usr_model.EmailCode) @@ -1158,7 +1158,7 @@ func (es *UserEventstore) AddressByID(ctx context.Context, userID string) (*usr_ if user.Address != nil { return user.Address, nil } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-so9wa", "Errors.User.AddressNotFound") + return nil, caos_errs.ThrowNotFound(nil, "EVENT-so9wa", "Errors.User.Address.NotFound") } func (es *UserEventstore) ChangeAddress(ctx context.Context, address *usr_model.Address) (*usr_model.Address, error) { diff --git a/internal/v2/business/iam/converter.go b/internal/v2/business/iam/converter.go deleted file mode 100644 index f3fd5f0547..0000000000 --- a/internal/v2/business/iam/converter.go +++ /dev/null @@ -1,280 +0,0 @@ -package iam - -import ( - "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/v2/repository/iam" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/label" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/login" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/login/idpprovider" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/org_iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_age" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_complexity" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_lockout" - "github.com/caos/zitadel/internal/v2/repository/idp/oidc" - "github.com/caos/zitadel/internal/v2/repository/member" -) - -func readModelToIAM(readModel *iam_repo.ReadModel) *model.IAM { - return &model.IAM{ - ObjectRoot: readModelToObjectRoot(readModel.ReadModel), - GlobalOrgID: readModel.GlobalOrgID, - IAMProjectID: readModel.ProjectID, - SetUpDone: model.Step(readModel.SetUpDone), - SetUpStarted: model.Step(readModel.SetUpStarted), - Members: readModelToMembers(&readModel.Members), - DefaultLabelPolicy: readModelToLabelPolicy(&readModel.DefaultLabelPolicy), - DefaultLoginPolicy: readModelToLoginPolicy(&readModel.DefaultLoginPolicy), - DefaultOrgIAMPolicy: readModelToOrgIAMPolicy(&readModel.DefaultOrgIAMPolicy), - DefaultPasswordAgePolicy: readModelToPasswordAgePolicy(&readModel.DefaultPasswordAgePolicy), - DefaultPasswordComplexityPolicy: readModelToPasswordComplexityPolicy(&readModel.DefaultPasswordComplexityPolicy), - DefaultPasswordLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy), - IDPs: readModelToIDPConfigs(&readModel.IDPs), - } -} - -func readModelToMembers(readModel *iam_repo.MembersReadModel) []*model.IAMMember { - members := make([]*model.IAMMember, len(readModel.Members)) - - for i, member := range readModel.Members { - members[i] = &model.IAMMember{ - ObjectRoot: readModelToObjectRoot(member.ReadModel), - Roles: member.Roles, - UserID: member.UserID, - } - } - - return members -} - -func readModelToLabelPolicy(readModel *label.ReadModel) *model.LabelPolicy { - return &model.LabelPolicy{ - ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel), - PrimaryColor: readModel.PrimaryColor, - SecondaryColor: readModel.SecondaryColor, - Default: true, - //TODO: State: int32, - } -} - -func readModelToLoginPolicy(readModel *login.ReadModel) *model.LoginPolicy { - return &model.LoginPolicy{ - ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel), - AllowExternalIdp: readModel.AllowExternalIDP, - AllowRegister: readModel.AllowRegister, - AllowUsernamePassword: readModel.AllowUserNamePassword, - Default: true, - //TODO: IDPProviders: []*model.IDPProvider, - //TODO: State: int32, - } -} -func readModelToOrgIAMPolicy(readModel *org_iam.ReadModel) *model.OrgIAMPolicy { - return &model.OrgIAMPolicy{ - ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel), - UserLoginMustBeDomain: readModel.UserLoginMustBeDomain, - Default: true, - //TODO: State: int32, - } -} -func readModelToPasswordAgePolicy(readModel *password_age.ReadModel) *model.PasswordAgePolicy { - return &model.PasswordAgePolicy{ - ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel), - ExpireWarnDays: uint64(readModel.ExpireWarnDays), - MaxAgeDays: uint64(readModel.MaxAgeDays), - //TODO: State: int32, - } -} -func readModelToPasswordComplexityPolicy(readModel *password_complexity.ReadModel) *model.PasswordComplexityPolicy { - return &model.PasswordComplexityPolicy{ - ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel), - HasLowercase: readModel.HasLowercase, - HasNumber: readModel.HasNumber, - HasSymbol: readModel.HasSymbol, - HasUppercase: readModel.HasUpperCase, - MinLength: uint64(readModel.MinLength), - //TODO: State: int32, - } -} -func readModelToPasswordLockoutPolicy(readModel *password_lockout.ReadModel) *model.PasswordLockoutPolicy { - return &model.PasswordLockoutPolicy{ - ObjectRoot: readModelToObjectRoot(readModel.ReadModel.ReadModel), - MaxAttempts: uint64(readModel.MaxAttempts), - ShowLockOutFailures: readModel.ShowLockOutFailures, - //TODO: State: int32, - } -} - -func readModelToObjectRoot(readModel eventstore.ReadModel) models.ObjectRoot { - return models.ObjectRoot{ - AggregateID: readModel.AggregateID, - ChangeDate: readModel.ChangeDate, - CreationDate: readModel.CreationDate, - ResourceOwner: readModel.ResourceOwner, - Sequence: readModel.ProcessedSequence, - } -} - -func writeModelToObjectRoot(writeModel eventstore.WriteModel) models.ObjectRoot { - return models.ObjectRoot{ - AggregateID: writeModel.AggregateID, - ChangeDate: writeModel.ChangeDate, - ResourceOwner: writeModel.ResourceOwner, - Sequence: writeModel.ProcessedSequence, - } -} - -func readModelToMember(readModel *member.ReadModel) *model.IAMMember { - return &model.IAMMember{ - ObjectRoot: readModelToObjectRoot(readModel.ReadModel), - Roles: readModel.Roles, - UserID: readModel.UserID, - } -} - -func writeModelToMember(writeModel *iam.MemberWriteModel) *model.IAMMember { - return &model.IAMMember{ - ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel.WriteModel), - Roles: writeModel.Roles, - UserID: writeModel.UserID, - } -} - -func writeModelToLoginPolicy(wm *login.WriteModel) *model.LoginPolicy { - return &model.LoginPolicy{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel), - AllowUsernamePassword: wm.AllowUserNamePassword, - AllowRegister: wm.AllowRegister, - AllowExternalIdp: wm.AllowExternalIDP, - ForceMFA: wm.ForceMFA, - PasswordlessType: model.PasswordlessType(wm.PasswordlessType), - } -} - -func writeModelToLabelPolicy(wm *label.WriteModel) *model.LabelPolicy { - return &model.LabelPolicy{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel), - PrimaryColor: wm.PrimaryColor, - SecondaryColor: wm.SecondaryColor, - } -} - -func writeModelToOrgIAMPolicy(wm *org_iam.WriteModel) *model.OrgIAMPolicy { - return &model.OrgIAMPolicy{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel), - UserLoginMustBeDomain: wm.UserLoginMustBeDomain, - } -} - -func writeModelToPasswordAgePolicy(wm *password_age.WriteModel) *model.PasswordAgePolicy { - return &model.PasswordAgePolicy{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel), - MaxAgeDays: wm.MaxAgeDays, - ExpireWarnDays: wm.ExpireWarnDays, - } -} - -func writeModelToPasswordComplexityPolicy(wm *password_complexity.WriteModel) *model.PasswordComplexityPolicy { - return &model.PasswordComplexityPolicy{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel), - MinLength: wm.MinLength, - HasLowercase: wm.HasLowercase, - HasUppercase: wm.HasUpperCase, - HasNumber: wm.HasNumber, - HasSymbol: wm.HasSymbol, - } -} - -func writeModelToPasswordLockoutPolicy(wm *password_lockout.WriteModel) *model.PasswordLockoutPolicy { - return &model.PasswordLockoutPolicy{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel), - MaxAttempts: wm.MaxAttempts, - ShowLockOutFailures: wm.ShowLockOutFailures, - } -} - -func readModelToIDPConfigView(rm *iam.IDPConfigReadModel) *model.IDPConfigView { - return &model.IDPConfigView{ - AggregateID: rm.AggregateID, - ChangeDate: rm.ChangeDate, - CreationDate: rm.CreationDate, - IDPConfigID: rm.ConfigID, - IDPProviderType: model.IDPProviderType(rm.ProviderType), - IsOIDC: rm.OIDCConfig != nil, - Name: rm.Name, - OIDCClientID: rm.OIDCConfig.ClientID, - OIDCClientSecret: rm.OIDCConfig.ClientSecret, - OIDCIDPDisplayNameMapping: model.OIDCMappingField(rm.OIDCConfig.IDPDisplayNameMapping), - OIDCIssuer: rm.OIDCConfig.Issuer, - OIDCScopes: rm.OIDCConfig.Scopes, - OIDCUsernameMapping: model.OIDCMappingField(rm.OIDCConfig.UserNameMapping), - Sequence: rm.ProcessedSequence, - State: model.IDPConfigState(rm.State), - StylingType: model.IDPStylingType(rm.StylingType), - } -} - -func readModelToIDPConfigs(rm *iam.IDPConfigsReadModel) []*model.IDPConfig { - configs := make([]*model.IDPConfig, len(rm.Configs)) - for i, config := range rm.Configs { - configs[i] = readModelToIDPConfig(&iam.IDPConfigReadModel{ConfigReadModel: *config}) - } - return configs -} - -func readModelToIDPConfig(rm *iam.IDPConfigReadModel) *model.IDPConfig { - return &model.IDPConfig{ - ObjectRoot: readModelToObjectRoot(rm.ReadModel), - OIDCConfig: readModelToIDPOIDCConfig(rm.OIDCConfig), - IDPConfigID: rm.ConfigID, - Name: rm.Name, - State: model.IDPConfigState(rm.State), - StylingType: model.IDPStylingType(rm.StylingType), - } -} - -func readModelToIDPOIDCConfig(rm *oidc.ConfigReadModel) *model.OIDCIDPConfig { - return &model.OIDCIDPConfig{ - ObjectRoot: readModelToObjectRoot(rm.ReadModel), - ClientID: rm.ClientID, - ClientSecret: rm.ClientSecret, - ClientSecretString: string(rm.ClientSecret.Crypted), - IDPConfigID: rm.IDPConfigID, - IDPDisplayNameMapping: model.OIDCMappingField(rm.IDPDisplayNameMapping), - Issuer: rm.Issuer, - Scopes: rm.Scopes, - UsernameMapping: model.OIDCMappingField(rm.UserNameMapping), - } -} - -func writeModelToIDPConfig(wm *iam.IDPConfigWriteModel) *model.IDPConfig { - return &model.IDPConfig{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel), - OIDCConfig: writeModelToIDPOIDCConfig(wm.OIDCConfig), - IDPConfigID: wm.ConfigID, - Name: wm.Name, - State: model.IDPConfigState(wm.State), - StylingType: model.IDPStylingType(wm.StylingType), - } -} - -func writeModelToIDPOIDCConfig(wm *oidc.ConfigWriteModel) *model.OIDCIDPConfig { - return &model.OIDCIDPConfig{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel), - ClientID: wm.ClientID, - IDPConfigID: wm.IDPConfigID, - IDPDisplayNameMapping: model.OIDCMappingField(wm.IDPDisplayNameMapping), - Issuer: wm.Issuer, - Scopes: wm.Scopes, - UsernameMapping: model.OIDCMappingField(wm.UserNameMapping), - } -} - -func writeModelToIDPProvider(wm *idpprovider.WriteModel) *model.IDPProvider { - return &model.IDPProvider{ - ObjectRoot: writeModelToObjectRoot(wm.WriteModel.WriteModel), - IDPConfigID: wm.IDPConfigID, - Type: model.IDPProviderType(wm.IDPProviderType), - } -} diff --git a/internal/v2/business/iam/idp_config.go b/internal/v2/business/iam/idp_config.go deleted file mode 100644 index d4762e6eeb..0000000000 --- a/internal/v2/business/iam/idp_config.go +++ /dev/null @@ -1,130 +0,0 @@ -package iam - -import ( - "context" - - "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/idp" - "github.com/caos/zitadel/internal/v2/repository/idp/oidc" -) - -func (r *Repository) IDPConfigByID(ctx context.Context, iamID, idpConfigID string) (*iam_model.IDPConfigView, error) { - idpConfig := iam.NewIDPConfigReadModel(iamID, idpConfigID) - err := r.eventstore.FilterToQueryReducer(ctx, idpConfig) - if err != nil { - return nil, err - } - - return readModelToIDPConfigView(idpConfig), nil -} - -func (r *Repository) AddIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { - if config.OIDCConfig == nil { - return nil, errors.ThrowInvalidArgument(nil, "IAM-eUpQU", "Errors.idp.config.notset") - } - - idpConfigID, err := r.idGenerator.Next() - if err != nil { - return nil, err - } - - //TODO: check name unique on aggregate - - clientSecret, err := crypto.Crypt([]byte(config.OIDCConfig.ClientSecretString), r.secretCrypto) - if err != nil { - return nil, err - } - - writeModel, err := r.pushIDPWriteModel(ctx, config.AggregateID, idpConfigID, func(a *iam.Aggregate, _ *iam.IDPConfigWriteModel) *iam.Aggregate { - return a. - PushIDPConfigAdded( - ctx, - idpConfigID, - config.Name, - idp.ConfigType(config.Type), - idp.StylingType(config.StylingType)). - PushIDPOIDCConfigAdded( - ctx, - config.OIDCConfig.ClientID, - idpConfigID, - config.OIDCConfig.Issuer, - clientSecret, - oidc.MappingField(config.OIDCConfig.IDPDisplayNameMapping), - oidc.MappingField(config.OIDCConfig.UsernameMapping), - config.OIDCConfig.Scopes...) - }) - if err != nil { - return nil, err - } - - return writeModelToIDPConfig(writeModel), nil -} - -func (r *Repository) ChangeIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { - writeModel, err := r.pushIDPWriteModel(ctx, config.AggregateID, config.IDPConfigID, func(a *iam.Aggregate, writeModel *iam.IDPConfigWriteModel) *iam.Aggregate { - return a.PushIDPConfigChanged( - ctx, - writeModel, - config.IDPConfigID, - config.Name, - idp.ConfigType(config.Type), - idp.StylingType(config.StylingType)) - }) - if err != nil { - return nil, err - } - - return writeModelToIDPConfig(writeModel), nil -} - -func (r *Repository) DeactivateIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) { - writeModel, err := r.pushIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *iam.IDPConfigWriteModel) *iam.Aggregate { - return a.PushIDPConfigDeactivated(ctx, idpID) - }) - if err != nil { - return nil, err - } - - return writeModelToIDPConfig(writeModel), nil -} - -func (r *Repository) ReactivateIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) { - writeModel, err := r.pushIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *iam.IDPConfigWriteModel) *iam.Aggregate { - return a.PushIDPConfigReactivated(ctx, idpID) - }) - if err != nil { - return nil, err - } - - return writeModelToIDPConfig(writeModel), nil -} - -func (r *Repository) RemoveIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) { - writeModel, err := r.pushIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *iam.IDPConfigWriteModel) *iam.Aggregate { - return a.PushIDPConfigRemoved(ctx, idpID) - }) - if err != nil { - return nil, err - } - - return writeModelToIDPConfig(writeModel), nil -} - -func (r *Repository) pushIDPWriteModel(ctx context.Context, iamID, idpID string, eventSetter func(*iam.Aggregate, *iam.IDPConfigWriteModel) *iam.Aggregate) (*iam.IDPConfigWriteModel, error) { - writeModel := iam.NewIDPConfigWriteModel(iamID, idpID) - err := r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - - aggregate := eventSetter(iam.AggregateFromWriteModel(&writeModel.WriteModel), writeModel) - err = r.eventstore.PushAggregate(ctx, writeModel, aggregate) - if err != nil { - return nil, err - } - - return writeModel, nil -} diff --git a/internal/v2/business/iam/idp_oidc_config.go b/internal/v2/business/iam/idp_oidc_config.go deleted file mode 100644 index ca5da4a6ec..0000000000 --- a/internal/v2/business/iam/idp_oidc_config.go +++ /dev/null @@ -1,44 +0,0 @@ -package iam - -import ( - "context" - - "github.com/caos/zitadel/internal/crypto" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/idp/oidc" -) - -func (r *Repository) ChangeIDPOIDCConfig(ctx context.Context, config *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) { - writeModel := iam.NewIDPOIDCConfigWriteModel(config.AggregateID, config.IDPConfigID) - err := r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - - var clientSecret *crypto.CryptoValue - if config.ClientSecretString != "" { - clientSecret, err = crypto.Crypt([]byte(config.ClientSecretString), r.secretCrypto) - if err != nil { - return nil, err - } - } - - aggregate := iam.AggregateFromWriteModel(&writeModel.WriteModel). - PushIDPOIDCConfigChanged( - ctx, - writeModel, - config.ClientID, - config.Issuer, - clientSecret, - oidc.MappingField(config.IDPDisplayNameMapping), - oidc.MappingField(config.UsernameMapping), - config.Scopes...) - - err = r.eventstore.PushAggregate(ctx, writeModel, aggregate) - if err != nil { - return nil, err - } - - return writeModelToIDPOIDCConfig(&writeModel.ConfigWriteModel), nil -} diff --git a/internal/v2/business/iam/org_iam_policy.go b/internal/v2/business/iam/org_iam_policy.go deleted file mode 100644 index 990dc8da6b..0000000000 --- a/internal/v2/business/iam/org_iam_policy.go +++ /dev/null @@ -1,60 +0,0 @@ -package iam - -import ( - "context" - caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/telemetry/tracing" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/org_iam" -) - -func (r *Repository) AddOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - addedPolicy := org_iam.NewWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) - if err != nil { - return nil, err - } - if addedPolicy != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.OrgIAMPolicy.AlreadyExists") - } - - iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel). - PushOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToOrgIAMPolicy(addedPolicy), nil -} - -func (r *Repository) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - existingPolicy, err := r.orgIAMPolicyWriteModelByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel). - PushOrgIAMPolicyChangedFromExisting(ctx, existingPolicy, policy.UserLoginMustBeDomain) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToOrgIAMPolicy(existingPolicy), nil -} - -func (r *Repository) orgIAMPolicyWriteModelByID(ctx context.Context, iamID string) (policy *org_iam.WriteModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - writeModel := org_iam.NewWriteModel(iamID) - err = r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - return writeModel, nil -} diff --git a/internal/v2/business/iam/policy_label.go b/internal/v2/business/iam/policy_label.go deleted file mode 100644 index 62b246ff2a..0000000000 --- a/internal/v2/business/iam/policy_label.go +++ /dev/null @@ -1,69 +0,0 @@ -package iam - -import ( - "context" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/telemetry/tracing" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/label" - - iam_model "github.com/caos/zitadel/internal/iam/model" -) - -func (r *Repository) AddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - if !policy.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mv0s", "Errors.IAM.LabelPolicyInvalid") - } - - addedPolicy := label.NewWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) - if err != nil { - return nil, err - } - if addedPolicy != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LabelPolicy.AlreadyExists") - } - - iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel). - PushLabelPolicyAddedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToLabelPolicy(addedPolicy), nil -} - -func (r *Repository) ChangeLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - if !policy.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-6M0od", "Errors.IAM.LabelPolicyInvalid") - } - - existingPolicy, err := r.labelPolicyWriteModelByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel). - PushLabelPolicyChangedFromExisting(ctx, existingPolicy, policy.PrimaryColor, policy.SecondaryColor) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToLabelPolicy(existingPolicy), nil -} - -func (r *Repository) labelPolicyWriteModelByID(ctx context.Context, iamID string) (policy *label.WriteModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - writeModel := label.NewWriteModel(iamID) - err = r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - return writeModel, nil -} diff --git a/internal/v2/business/iam/policy_login.go b/internal/v2/business/iam/policy_login.go deleted file mode 100644 index ef4ce35f07..0000000000 --- a/internal/v2/business/iam/policy_login.go +++ /dev/null @@ -1,160 +0,0 @@ -package iam - -import ( - "context" - caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/telemetry/tracing" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" - iam_login "github.com/caos/zitadel/internal/v2/repository/iam/policy/login" - iam_factor "github.com/caos/zitadel/internal/v2/repository/iam/policy/login/factors" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/login/idpprovider" - "github.com/caos/zitadel/internal/v2/repository/policy/login" - "github.com/caos/zitadel/internal/v2/repository/policy/login/factors" - idpprovider2 "github.com/caos/zitadel/internal/v2/repository/policy/login/idpprovider" -) - -func (r *Repository) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - if !policy.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mv0s", "Errors.IAM.LoginPolicyInvalid") - } - - addedPolicy := iam_login.NewWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) - if err != nil { - return nil, err - } - if addedPolicy != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.AlreadyExists") - } - - iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel). - PushLoginPolicyAddedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIdp, policy.ForceMFA, login.PasswordlessType(policy.PasswordlessType)) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToLoginPolicy(addedPolicy), nil -} - -func (r *Repository) ChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - if !policy.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-6M0od", "Errors.IAM.LoginPolicyInvalid") - } - - existingPolicy, err := r.loginPolicyWriteModelByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel). - PushLoginPolicyChangedFromExisting(ctx, existingPolicy, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIdp, policy.ForceMFA, login.PasswordlessType(policy.PasswordlessType)) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToLoginPolicy(existingPolicy), nil -} - -func (r *Repository) AddIDPProviderToLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) { - writeModel := idpprovider.NewWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID) - err := r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - - aggregate := iam_repo.AggregateFromWriteModel(&writeModel.WriteModel.WriteModel). - PushLoginPolicyIDPProviderAddedEvent(ctx, idpProvider.IDPConfigID, idpprovider2.Type(idpProvider.Type)) - - if err = r.eventstore.PushAggregate(ctx, writeModel, aggregate); err != nil { - return nil, err - } - - return writeModelToIDPProvider(writeModel), nil -} - -func (r *Repository) RemoveIDPProviderFromLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) error { - writeModel := idpprovider.NewWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID) - err := r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return err - } - aggregate := iam_repo.AggregateFromWriteModel(&writeModel.WriteModel.WriteModel). - PushLoginPolicyIDPProviderAddedEvent(ctx, idpProvider.IDPConfigID, idpprovider2.Type(idpProvider.Type)) - - return r.eventstore.PushAggregate(ctx, writeModel, aggregate) -} - -func (r *Repository) AddSecondFactorToLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.SecondFactorType) (iam_model.SecondFactorType, error) { - writeModel := iam_factor.NewSecondFactorWriteModel(iamID) - err := r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return iam_model.SecondFactorTypeUnspecified, err - } - - aggregate := iam_repo.AggregateFromWriteModel(&writeModel.SecondFactorWriteModel.WriteModel). - PushLoginPolicySecondFactorAdded(ctx, factors.SecondFactorType(secondFactor)) - - if err = r.eventstore.PushAggregate(ctx, writeModel, aggregate); err != nil { - return iam_model.SecondFactorTypeUnspecified, err - } - - return iam_model.SecondFactorType(writeModel.MFAType), nil -} - -func (r *Repository) RemoveSecondFactorFromLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.SecondFactorType) error { - writeModel := iam_factor.NewSecondFactorWriteModel(iamID) - err := r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return err - } - aggregate := iam_repo.AggregateFromWriteModel(&writeModel.SecondFactorWriteModel.WriteModel). - PushLoginPolicySecondFactorRemoved(ctx, factors.SecondFactorType(secondFactor)) - - return r.eventstore.PushAggregate(ctx, writeModel, aggregate) -} - -func (r *Repository) AddMultiFactorToLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.MultiFactorType) (iam_model.MultiFactorType, error) { - writeModel := iam_factor.NewMultiFactorWriteModel(iamID) - err := r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return iam_model.MultiFactorTypeUnspecified, err - } - - aggregate := iam_repo.AggregateFromWriteModel(&writeModel.MultiFactoryWriteModel.WriteModel). - PushLoginPolicyMultiFactorAdded(ctx, factors.MultiFactorType(secondFactor)) - - if err = r.eventstore.PushAggregate(ctx, writeModel, aggregate); err != nil { - return iam_model.MultiFactorTypeUnspecified, err - } - - return iam_model.MultiFactorType(writeModel.MultiFactoryWriteModel.MFAType), nil -} - -func (r *Repository) RemoveMultiFactorFromLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.MultiFactorType) error { - writeModel := iam_factor.NewMultiFactorWriteModel(iamID) - err := r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return err - } - aggregate := iam_repo.AggregateFromWriteModel(&writeModel.MultiFactoryWriteModel.WriteModel). - PushLoginPolicyMultiFactorRemoved(ctx, factors.MultiFactorType(secondFactor)) - - return r.eventstore.PushAggregate(ctx, writeModel, aggregate) -} - -func (r *Repository) loginPolicyWriteModelByID(ctx context.Context, iamID string) (policy *iam_login.WriteModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - writeModel := iam_login.NewWriteModel(iamID) - err = r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - return writeModel, nil -} diff --git a/internal/v2/business/iam/policy_password_age.go b/internal/v2/business/iam/policy_password_age.go deleted file mode 100644 index c10f1aec48..0000000000 --- a/internal/v2/business/iam/policy_password_age.go +++ /dev/null @@ -1,60 +0,0 @@ -package iam - -import ( - "context" - caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/telemetry/tracing" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_age" -) - -func (r *Repository) AddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - addedPolicy := password_age.NewWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) - if err != nil { - return nil, err - } - if addedPolicy != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-6L0pd", "Errors.IAM.PasswordAgePolicy.AlreadyExists") - } - - iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel). - PushPasswordAgePolicyAddedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToPasswordAgePolicy(addedPolicy), nil -} - -func (r *Repository) ChangePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - existingPolicy, err := r.passwordAgePolicyWriteModelByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel). - PushPasswordAgePolicyChangedFromExisting(ctx, existingPolicy, policy.ExpireWarnDays, policy.MaxAgeDays) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToPasswordAgePolicy(existingPolicy), nil -} - -func (r *Repository) passwordAgePolicyWriteModelByID(ctx context.Context, iamID string) (policy *password_age.WriteModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - writeModel := password_age.NewWriteModel(iamID) - err = r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - return writeModel, nil -} diff --git a/internal/v2/business/iam/policy_password_complexity.go b/internal/v2/business/iam/policy_password_complexity.go deleted file mode 100644 index cfbadfa3b7..0000000000 --- a/internal/v2/business/iam/policy_password_complexity.go +++ /dev/null @@ -1,68 +0,0 @@ -package iam - -import ( - "context" - caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/telemetry/tracing" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_complexity" -) - -func (r *Repository) AddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - if err := policy.IsValid(); err != nil { - return nil, err - } - - addedPolicy := password_complexity.NewWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) - if err != nil { - return nil, err - } - if addedPolicy != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordComplexityPolicy.AlreadyExists") - } - - iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel). - PushPasswordComplexityPolicyAddedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToPasswordComplexityPolicy(addedPolicy), nil -} - -func (r *Repository) ChangePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - if err := policy.IsValid(); err != nil { - return nil, err - } - - existingPolicy, err := r.passwordComplexityPolicyWriteModelByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel). - PushPasswordComplexityPolicyChangedFromExisting(ctx, existingPolicy, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToPasswordComplexityPolicy(existingPolicy), nil -} - -func (r *Repository) passwordComplexityPolicyWriteModelByID(ctx context.Context, iamID string) (policy *password_complexity.WriteModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - writeModel := password_complexity.NewWriteModel(iamID) - err = r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - return writeModel, nil -} diff --git a/internal/v2/business/iam/policy_password_lockout.go b/internal/v2/business/iam/policy_password_lockout.go deleted file mode 100644 index 888416a574..0000000000 --- a/internal/v2/business/iam/policy_password_lockout.go +++ /dev/null @@ -1,60 +0,0 @@ -package iam - -import ( - "context" - caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/telemetry/tracing" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_lockout" -) - -func (r *Repository) AddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - addedPolicy := password_lockout.NewWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) - if err != nil { - return nil, err - } - if addedPolicy != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists") - } - - iamAgg := iam_repo.AggregateFromWriteModel(&addedPolicy.WriteModel.WriteModel). - PushPasswordLockoutPolicyAddedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures) - - err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToPasswordLockoutPolicy(addedPolicy), nil -} - -func (r *Repository) ChangePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - existingPolicy, err := r.passwordLockoutPolicyWriteModelByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - iamAgg := iam_repo.AggregateFromWriteModel(&existingPolicy.WriteModel.WriteModel). - PushPasswordLockoutPolicyChangedFromExisting(ctx, existingPolicy, policy.MaxAttempts, policy.ShowLockOutFailures) - - err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) - if err != nil { - return nil, err - } - - return writeModelToPasswordLockoutPolicy(existingPolicy), nil -} - -func (r *Repository) passwordLockoutPolicyWriteModelByID(ctx context.Context, iamID string) (policy *password_lockout.WriteModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - writeModel := password_lockout.NewWriteModel(iamID) - err = r.eventstore.FilterToQueryReducer(ctx, writeModel) - if err != nil { - return nil, err - } - return writeModel, nil -} diff --git a/internal/v2/business/iam/setup.go b/internal/v2/business/iam/setup.go deleted file mode 100644 index 38d82f61c3..0000000000 --- a/internal/v2/business/iam/setup.go +++ /dev/null @@ -1,50 +0,0 @@ -package iam - -import ( - "context" - - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" -) - -func (r *Repository) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) { - iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepStartedEvent(ctx, iam_repo.Step(step))) - if err != nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed") - } - return iam, nil -} - -func (r *Repository) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) { - iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepDoneEvent(ctx, iam_repo.Step(step))) - if err != nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed") - } - return iam, nil -} - -func (r *Repository) setup(ctx context.Context, iamID string, step iam_repo.Step, event eventstore.EventPusher) (*iam_model.IAM, error) { - iam, err := r.iamByID(ctx, iamID) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - - if iam != nil && (iam.SetUpStarted >= iam_repo.Step(step) || iam.SetUpStarted != iam.SetUpDone) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error") - } - - aggregate := iam_repo.AggregateFromReadModel(iam). - PushEvents(event) - - events, err := r.eventstore.PushAggregates(ctx, aggregate) - if err != nil { - return nil, err - } - - if err = iam.AppendAndReduce(events...); err != nil { - return nil, err - } - return readModelToIAM(iam), nil -} diff --git a/internal/v2/business/org/repository.go b/internal/v2/business/org/repository.go deleted file mode 100644 index 9e45aaf013..0000000000 --- a/internal/v2/business/org/repository.go +++ /dev/null @@ -1,99 +0,0 @@ -package org - -import ( - "context" - - "github.com/caos/zitadel/internal/eventstore/v2" - iam_model "github.com/caos/zitadel/internal/iam/model" -) - -type Repository struct { - eventstore *eventstore.Eventstore -} - -type Config struct { - Eventstore *eventstore.Eventstore -} - -func StartRepository(config *Config) *Repository { - return &Repository{ - eventstore: config.Eventstore, - } -} - -func (r *Repository) GetMyOrgIamPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) { - return nil, nil -} - -func (r *Repository) GetLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) { - return nil, nil -} -func (r *Repository) GetDefaultLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) { - return nil, nil -} -func (r *Repository) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - return nil, nil -} -func (r *Repository) ChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - return nil, nil -} -func (r *Repository) RemoveLoginPolicy(ctx context.Context) error { - return nil -} -func (r *Repository) SearchIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) { - return nil, nil -} -func (r *Repository) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) { - return nil, nil -} -func (r *Repository) RemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) error { - return nil -} - -func (r *Repository) GetPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) { - return nil, nil -} -func (r *Repository) GetDefaultPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) { - return nil, nil -} -func (r *Repository) AddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - return nil, nil -} -func (r *Repository) ChangePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - return nil, nil -} -func (r *Repository) RemovePasswordComplexityPolicy(ctx context.Context) error { - return nil -} - -func (r *Repository) GetPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error) { - return nil, nil -} -func (r *Repository) GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error) { - return nil, nil -} -func (r *Repository) AddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - return nil, nil -} -func (r *Repository) ChangePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - return nil, nil -} -func (r *Repository) RemovePasswordAgePolicy(ctx context.Context) error { - return nil -} - -func (r *Repository) GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) { - return nil, nil -} -func (r *Repository) GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) { - return nil, nil -} -func (r *Repository) AddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - return nil, nil -} -func (r *Repository) ChangePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - return nil, nil -} -func (r *Repository) RemovePasswordLockoutPolicy(ctx context.Context) error { - return nil -} diff --git a/internal/v2/command/command.go b/internal/v2/command/command.go new file mode 100644 index 0000000000..b73b24e2b8 --- /dev/null +++ b/internal/v2/command/command.go @@ -0,0 +1,72 @@ +package command + +import ( + "context" + + sd "github.com/caos/zitadel/internal/config/systemdefaults" + "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/id" + "github.com/caos/zitadel/internal/telemetry/tracing" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type CommandSide struct { + eventstore *eventstore.Eventstore + idGenerator id.Generator + iamID string + + idpConfigSecretCrypto crypto.Crypto + + userPasswordAlg crypto.HashAlgorithm + initializeUserCode crypto.Generator + emailVerificationCode crypto.Generator + phoneVerificationCode crypto.Generator + passwordVerificationCode crypto.Generator + machineKeyAlg crypto.EncryptionAlgorithm + machineKeySize int +} + +type Config struct { + Eventstore *eventstore.Eventstore + SystemDefaults sd.SystemDefaults +} + +func StartCommandSide(config *Config) (repo *CommandSide, err error) { + repo = &CommandSide{ + eventstore: config.Eventstore, + idGenerator: id.SonyFlakeGenerator, + iamID: config.SystemDefaults.IamID, + } + iam_repo.RegisterEventMappers(repo.eventstore) + + repo.idpConfigSecretCrypto, err = crypto.NewAESCrypto(config.SystemDefaults.IDPConfigVerificationKey) + if err != nil { + return nil, err + } + aesCrypto, err := crypto.NewAESCrypto(config.SystemDefaults.UserVerificationKey) + if err != nil { + return nil, err + } + repo.initializeUserCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.InitializeUserCode, aesCrypto) + repo.emailVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.EmailVerificationCode, aesCrypto) + repo.phoneVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.PhoneVerificationCode, aesCrypto) + repo.passwordVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.PasswordVerificationCode, aesCrypto) + repo.userPasswordAlg = crypto.NewBCrypt(config.SystemDefaults.SecretGenerators.PasswordSaltCost) + repo.machineKeyAlg = aesCrypto + repo.machineKeySize = int(config.SystemDefaults.SecretGenerators.MachineKeySize) + return repo, nil +} + +func (r *CommandSide) iamByID(ctx context.Context, id string) (_ *IAMWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMriteModel(id) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + + return writeModel, nil +} diff --git a/internal/v2/command/iam_converter.go b/internal/v2/command/iam_converter.go new file mode 100644 index 0000000000..da7fb73564 --- /dev/null +++ b/internal/v2/command/iam_converter.go @@ -0,0 +1,118 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/iam/model" +) + +func writeModelToObjectRoot(writeModel eventstore.WriteModel) models.ObjectRoot { + return models.ObjectRoot{ + AggregateID: writeModel.AggregateID, + ChangeDate: writeModel.ChangeDate, + ResourceOwner: writeModel.ResourceOwner, + Sequence: writeModel.ProcessedSequence, + } +} + +func writeModelToIAM(wm *IAMWriteModel) *model.IAM { + return &model.IAM{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + SetUpStarted: wm.SetUpStarted, + SetUpDone: wm.SetUpDone, + GlobalOrgID: wm.GlobalOrgID, + IAMProjectID: wm.ProjectID, + } +} + +func writeModelToMember(writeModel *IAMMemberWriteModel) *model.IAMMember { + return &model.IAMMember{ + ObjectRoot: writeModelToObjectRoot(writeModel.MemberWriteModel.WriteModel), + Roles: writeModel.Roles, + UserID: writeModel.UserID, + } +} + +func writeModelToLoginPolicy(wm *IAMLoginPolicyWriteModel) *model.LoginPolicy { + return &model.LoginPolicy{ + ObjectRoot: writeModelToObjectRoot(wm.LoginPolicyWriteModel.WriteModel), + AllowUsernamePassword: wm.AllowUserNamePassword, + AllowRegister: wm.AllowRegister, + AllowExternalIdp: wm.AllowExternalIDP, + ForceMFA: wm.ForceMFA, + PasswordlessType: model.PasswordlessType(wm.PasswordlessType), + } +} + +func writeModelToLabelPolicy(wm *IAMLabelPolicyWriteModel) *model.LabelPolicy { + return &model.LabelPolicy{ + ObjectRoot: writeModelToObjectRoot(wm.LabelPolicyWriteModel.WriteModel), + PrimaryColor: wm.PrimaryColor, + SecondaryColor: wm.SecondaryColor, + } +} + +func writeModelToOrgIAMPolicy(wm *IAMOrgIAMPolicyWriteModel) *model.OrgIAMPolicy { + return &model.OrgIAMPolicy{ + ObjectRoot: writeModelToObjectRoot(wm.PolicyOrgIAMWriteModel.WriteModel), + UserLoginMustBeDomain: wm.UserLoginMustBeDomain, + } +} + +func writeModelToPasswordAgePolicy(wm *IAMPasswordAgePolicyWriteModel) *model.PasswordAgePolicy { + return &model.PasswordAgePolicy{ + ObjectRoot: writeModelToObjectRoot(wm.PasswordAgePolicyWriteModel.WriteModel), + MaxAgeDays: wm.MaxAgeDays, + ExpireWarnDays: wm.ExpireWarnDays, + } +} + +func writeModelToPasswordComplexityPolicy(wm *IAMPasswordComplexityPolicyWriteModel) *model.PasswordComplexityPolicy { + return &model.PasswordComplexityPolicy{ + ObjectRoot: writeModelToObjectRoot(wm.PasswordComplexityPolicyWriteModel.WriteModel), + MinLength: wm.MinLength, + HasLowercase: wm.HasLowercase, + HasUppercase: wm.HasUpperCase, + HasNumber: wm.HasNumber, + HasSymbol: wm.HasSymbol, + } +} + +func writeModelToPasswordLockoutPolicy(wm *IAMPasswordLockoutPolicyWriteModel) *model.PasswordLockoutPolicy { + return &model.PasswordLockoutPolicy{ + ObjectRoot: writeModelToObjectRoot(wm.PasswordLockoutPolicyWriteModel.WriteModel), + MaxAttempts: wm.MaxAttempts, + ShowLockOutFailures: wm.ShowLockOutFailures, + } +} + +func writeModelToIDPConfig(wm *IAMIDPConfigWriteModel) *model.IDPConfig { + return &model.IDPConfig{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + OIDCConfig: writeModelToIDPOIDCConfig(wm.OIDCConfig), + IDPConfigID: wm.ConfigID, + Name: wm.Name, + State: model.IDPConfigState(wm.State), + StylingType: model.IDPStylingType(wm.StylingType), + } +} + +func writeModelToIDPOIDCConfig(wm *OIDCConfigWriteModel) *model.OIDCIDPConfig { + return &model.OIDCIDPConfig{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + ClientID: wm.ClientID, + IDPConfigID: wm.IDPConfigID, + IDPDisplayNameMapping: model.OIDCMappingField(wm.IDPDisplayNameMapping), + Issuer: wm.Issuer, + Scopes: wm.Scopes, + UsernameMapping: model.OIDCMappingField(wm.UserNameMapping), + } +} + +func writeModelToIDPProvider(wm *IAMIdentityProviderWriteModel) *model.IDPProvider { + return &model.IDPProvider{ + ObjectRoot: writeModelToObjectRoot(wm.IdentityProviderWriteModel.WriteModel), + IDPConfigID: wm.IDPConfigID, + Type: model.IDPProviderType(wm.IDPProviderType), + } +} diff --git a/internal/v2/command/iam_idp_config.go b/internal/v2/command/iam_idp_config.go new file mode 100644 index 0000000000..382a954ea2 --- /dev/null +++ b/internal/v2/command/iam_idp_config.go @@ -0,0 +1,159 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/telemetry/tracing" + "github.com/caos/zitadel/internal/v2/domain" + + "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/repository/iam" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) AddDefaultIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { + if config.OIDCConfig == nil { + return nil, errors.ThrowInvalidArgument(nil, "IAM-eUpQU", "Errors.idp.config.notset") + } + + idpConfigID, err := r.idGenerator.Next() + if err != nil { + return nil, err + } + //TODO: check name unique on aggregate + addedConfig := NewIAMIDPConfigWriteModel(config.AggregateID, idpConfigID) + + clientSecret, err := crypto.Crypt([]byte(config.OIDCConfig.ClientSecretString), r.idpConfigSecretCrypto) + if err != nil { + return nil, err + } + + iamAgg := IAMAggregateFromWriteModel(&addedConfig.WriteModel) + iamAgg.PushEvents( + iam_repo.NewIDPConfigAddedEvent( + ctx, + idpConfigID, + config.Name, + domain.IDPConfigType(config.Type), + domain.IDPConfigStylingType(config.StylingType), + ), + ) + iamAgg.PushEvents( + iam_repo.NewIDPOIDCConfigAddedEvent( + ctx, config.OIDCConfig.ClientID, + idpConfigID, + config.OIDCConfig.Issuer, + clientSecret, + domain.OIDCMappingField(config.OIDCConfig.IDPDisplayNameMapping), + domain.OIDCMappingField(config.OIDCConfig.UsernameMapping), + config.OIDCConfig.Scopes..., + ), + ) + err = r.eventstore.PushAggregate(ctx, addedConfig, iamAgg) + if err != nil { + return nil, err + } + return writeModelToIDPConfig(addedConfig), nil +} + +func (r *CommandSide) ChangeDefaultIDPConfig(ctx context.Context, config *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { + existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, config.AggregateID, config.IDPConfigID) + if err != nil { + return nil, err + } + if existingIDP.State == domain.IDPConfigStateRemoved || existingIDP.State == domain.IDPConfigStateUnspecified { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotExisting") + } + + changedEvent, hasChanged := existingIDP.NewChangedEvent(ctx, config.IDPConfigID, config.Name, domain.IDPConfigStylingType(config.StylingType)) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") + } + iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg) + if err != nil { + return nil, err + } + return writeModelToIDPConfig(existingIDP), nil +} + +func (r *CommandSide) DeactivateDefaultIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) { + existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, iamID, idpID) + if err != nil { + return nil, err + } + if existingIDP.State != domain.IDPConfigStateActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotActive") + } + iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel) + iamAgg.PushEvents(iam_repo.NewIDPConfigDeactivatedEvent(ctx, idpID)) + + err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg) + if err != nil { + return nil, err + } + return writeModelToIDPConfig(existingIDP), nil +} + +func (r *CommandSide) ReactivateDefaultIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) { + existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, iamID, idpID) + if err != nil { + return nil, err + } + if existingIDP.State != domain.IDPConfigStateInactive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-5Mo0d", "Errors.IAM.IDPConfig.NotInactive") + } + iamAgg := IAMAggregateFromWriteModel(&existingIDP.WriteModel) + iamAgg.PushEvents(iam_repo.NewIDPConfigReactivatedEvent(ctx, idpID)) + + err = r.eventstore.PushAggregate(ctx, existingIDP, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToIDPConfig(existingIDP), nil +} + +func (r *CommandSide) RemoveDefaultIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) { + writeModel, err := r.pushDefaultIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *IAMIDPConfigWriteModel) *iam.Aggregate { + a.Aggregate = *a.PushEvents(iam_repo.NewIDPConfigRemovedEvent(ctx, idpID)) + return a + }) + if err != nil { + return nil, err + } + + return writeModelToIDPConfig(writeModel), nil +} + +func (r *CommandSide) pushDefaultIDPWriteModel(ctx context.Context, iamID, idpID string, eventSetter func(*iam.Aggregate, *IAMIDPConfigWriteModel) *iam.Aggregate) (*IAMIDPConfigWriteModel, error) { + writeModel := NewIAMIDPConfigWriteModel(iamID, idpID) + err := r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + + aggregate := eventSetter(IAMAggregateFromWriteModel(&writeModel.WriteModel), writeModel) + err = r.eventstore.PushAggregate(ctx, writeModel, aggregate) + if err != nil { + return nil, err + } + + return writeModel, nil +} + +func (r *CommandSide) iamIDPConfigWriteModelByID(ctx context.Context, iamID, idpID string) (policy *IAMIDPConfigWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMIDPConfigWriteModel(iamID, idpID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_idp_config_model.go b/internal/v2/command/iam_idp_config_model.go new file mode 100644 index 0000000000..49445de46e --- /dev/null +++ b/internal/v2/command/iam_idp_config_model.go @@ -0,0 +1,100 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMIDPConfigWriteModel struct { + IDPConfigWriteModel +} + +func NewIAMIDPConfigWriteModel(iamID, configID string) *IAMIDPConfigWriteModel { + return &IAMIDPConfigWriteModel{ + IDPConfigWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + ConfigID: configID, + }, + } +} + +func (wm *IAMIDPConfigWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.AggregateID) +} + +func (wm *IAMIDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.IDPConfigAddedEvent: + if wm.ConfigID != e.ConfigID { + continue + } + wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigAddedEvent) + case *iam.IDPConfigChangedEvent: + if wm.ConfigID != e.ConfigID { + continue + } + wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigChangedEvent) + case *iam.IDPConfigDeactivatedEvent: + if wm.ConfigID != e.ConfigID { + continue + } + wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigDeactivatedEvent) + case *iam.IDPConfigReactivatedEvent: + if wm.ConfigID != e.ConfigID { + continue + } + wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigReactivatedEvent) + case *iam.IDPConfigRemovedEvent: + if wm.ConfigID != e.ConfigID { + continue + } + wm.IDPConfigWriteModel.AppendEvents(&e.IDPConfigRemovedEvent) + case *iam.IDPOIDCConfigAddedEvent: + if wm.ConfigID != e.IDPConfigID { + continue + } + wm.IDPConfigWriteModel.AppendEvents(&e.OIDCConfigAddedEvent) + case *iam.IDPOIDCConfigChangedEvent: + if wm.ConfigID != e.IDPConfigID { + continue + } + wm.IDPConfigWriteModel.AppendEvents(&e.OIDCConfigChangedEvent) + } + } +} + +func (wm *IAMIDPConfigWriteModel) Reduce() error { + return wm.IDPConfigWriteModel.Reduce() +} + +func (wm *IAMIDPConfigWriteModel) AppendAndReduce(events ...eventstore.EventReader) error { + wm.AppendEvents(events...) + return wm.Reduce() +} + +func (wm *IAMIDPConfigWriteModel) NewChangedEvent( + ctx context.Context, + configID, + name string, + stylingType domain.IDPConfigStylingType, +) (*iam.IDPConfigChangedEvent, bool) { + + hasChanged := false + changedEvent := iam.NewIDPConfigChangedEvent(ctx) + changedEvent.ConfigID = configID + if wm.Name != name { + hasChanged = true + changedEvent.Name = name + } + if stylingType.Valid() && wm.StylingType != stylingType { + hasChanged = true + changedEvent.StylingType = stylingType + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/iam_idp_oidc_config.go b/internal/v2/command/iam_idp_oidc_config.go new file mode 100644 index 0000000000..d78ef231a0 --- /dev/null +++ b/internal/v2/command/iam_idp_oidc_config.go @@ -0,0 +1,47 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/v2/domain" + + iam_model "github.com/caos/zitadel/internal/iam/model" +) + +func (r *CommandSide) ChangeDefaultIDPOIDCConfig(ctx context.Context, config *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) { + existingConfig := NewIDPOIDCConfigWriteModel(config.AggregateID, config.IDPConfigID) + err := r.eventstore.FilterToQueryReducer(ctx, existingConfig) + if err != nil { + return nil, err + } + + if existingConfig.State == domain.IDPConfigStateRemoved || existingConfig.State == domain.IDPConfigStateUnspecified { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-67J9d", "Errors.IAM.IDPConfig.AlreadyExists") + } + + changedEvent, hasChanged, err := existingConfig.NewChangedEvent( + ctx, + config.ClientID, + config.Issuer, + config.ClientSecretString, + r.idpConfigSecretCrypto, + domain.OIDCMappingField(config.IDPDisplayNameMapping), + domain.OIDCMappingField(config.UsernameMapping), + config.Scopes...) + if err != nil { + return nil, err + } + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") + } + + iamAgg := IAMAggregateFromWriteModel(&existingConfig.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingConfig, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToIDPOIDCConfig(&existingConfig.OIDCConfigWriteModel), nil +} diff --git a/internal/v2/command/iam_idp_oidc_config_model.go b/internal/v2/command/iam_idp_oidc_config_model.go new file mode 100644 index 0000000000..247dc32892 --- /dev/null +++ b/internal/v2/command/iam_idp_oidc_config_model.go @@ -0,0 +1,115 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/iam" + "reflect" +) + +type IDPOIDCConfigWriteModel struct { + OIDCConfigWriteModel +} + +func NewIDPOIDCConfigWriteModel(iamID, idpConfigID string) *IDPOIDCConfigWriteModel { + return &IDPOIDCConfigWriteModel{ + OIDCConfigWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + IDPConfigID: idpConfigID, + }, + } +} + +func (wm *IDPOIDCConfigWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.IDPOIDCConfigAddedEvent: + if wm.IDPConfigID != e.IDPConfigID { + continue + } + wm.OIDCConfigWriteModel.AppendEvents(&e.OIDCConfigAddedEvent) + case *iam.IDPOIDCConfigChangedEvent: + if wm.IDPConfigID != e.IDPConfigID { + continue + } + wm.OIDCConfigWriteModel.AppendEvents(&e.OIDCConfigChangedEvent) + case *iam.IDPConfigReactivatedEvent: + if wm.IDPConfigID != e.ConfigID { + continue + } + wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigReactivatedEvent) + case *iam.IDPConfigDeactivatedEvent: + if wm.IDPConfigID != e.ConfigID { + continue + } + wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigDeactivatedEvent) + case *iam.IDPConfigRemovedEvent: + if wm.IDPConfigID != e.ConfigID { + continue + } + wm.OIDCConfigWriteModel.AppendEvents(&e.IDPConfigRemovedEvent) + default: + wm.OIDCConfigWriteModel.AppendEvents(e) + } + } +} + +func (wm *IDPOIDCConfigWriteModel) Reduce() error { + if err := wm.OIDCConfigWriteModel.Reduce(); err != nil { + return err + } + return wm.WriteModel.Reduce() +} + +func (wm *IDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.AggregateID) +} + +func (wm *IDPOIDCConfigWriteModel) NewChangedEvent( + ctx context.Context, + clientID, + issuer, + clientSecretString string, + secretCrypto crypto.Crypto, + idpDisplayNameMapping, + userNameMapping domain.OIDCMappingField, + scopes ...string, +) (*iam.IDPOIDCConfigChangedEvent, bool, error) { + hasChanged := false + changedEvent := iam.NewIDPOIDCConfigChangedEvent(ctx) + var clientSecret *crypto.CryptoValue + var err error + if clientSecretString != "" { + clientSecret, err = crypto.Crypt([]byte(clientSecretString), secretCrypto) + if err != nil { + return nil, false, err + } + changedEvent.ClientSecret = clientSecret + } + if wm.ClientID != clientID { + hasChanged = true + changedEvent.ClientID = clientID + } + if wm.Issuer != issuer { + hasChanged = true + changedEvent.Issuer = issuer + } + if idpDisplayNameMapping.Valid() && wm.IDPDisplayNameMapping != idpDisplayNameMapping { + hasChanged = true + changedEvent.IDPDisplayNameMapping = idpDisplayNameMapping + } + if userNameMapping.Valid() && wm.UserNameMapping != userNameMapping { + hasChanged = true + changedEvent.UserNameMapping = userNameMapping + } + if reflect.DeepEqual(wm.Scopes, scopes) { + hasChanged = true + changedEvent.Scopes = scopes + } + return changedEvent, hasChanged, nil +} diff --git a/internal/v2/business/iam/member.go b/internal/v2/command/iam_member.go similarity index 50% rename from internal/v2/business/iam/member.go rename to internal/v2/command/iam_member.go index 66358f4d68..40e604385b 100644 --- a/internal/v2/business/iam/member.go +++ b/internal/v2/command/iam_member.go @@ -1,7 +1,8 @@ -package iam +package command import ( "context" + "reflect" "github.com/caos/zitadel/internal/errors" caos_errs "github.com/caos/zitadel/internal/errors" @@ -10,14 +11,14 @@ import ( iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) -func (r *Repository) AddMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { +func (r *CommandSide) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { //TODO: check if roles valid if !member.IsValid() { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-W8m4l", "Errors.IAM.MemberInvalid") } - addedMember := iam_repo.NewMemberWriteModel(member.AggregateID, member.UserID) + addedMember := NewIAMMemberWriteModel(member.AggregateID, member.UserID) err := r.eventstore.FilterToQueryReducer(ctx, addedMember) if err != nil { return nil, err @@ -26,8 +27,8 @@ func (r *Repository) AddMember(ctx context.Context, member *iam_model.IAMMember) return nil, errors.ThrowAlreadyExists(nil, "IAM-PtXi1", "Errors.IAM.Member.AlreadyExists") } - iamAgg := iam_repo.AggregateFromWriteModel(&addedMember.WriteModel.WriteModel). - PushMemberAdded(ctx, member.UserID, member.Roles...) + iamAgg := IAMAggregateFromWriteModel(&addedMember.MemberWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewMemberAddedEvent(ctx, member.UserID, member.Roles...)) err = r.eventstore.PushAggregate(ctx, addedMember, iamAgg) if err != nil { @@ -37,23 +38,26 @@ func (r *Repository) AddMember(ctx context.Context, member *iam_model.IAMMember) return writeModelToMember(addedMember), nil } -//ChangeMember updates an existing member -func (r *Repository) ChangeMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { +//ChangeIAMMember updates an existing member +func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { //TODO: check if roles valid if !member.IsValid() { return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.MemberInvalid") } - existingMember, err := r.memberWriteModelByID(ctx, member.AggregateID, member.UserID) + existingMember, err := r.iamMemberWriteModelByID(ctx, member.AggregateID, member.UserID) if err != nil { return nil, err } - iam := iam_repo.AggregateFromWriteModel(&existingMember.WriteModel.WriteModel). - PushMemberChangedFromExisting(ctx, existingMember, member.Roles...) + if reflect.DeepEqual(existingMember.Roles, member.Roles) { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.Member.RolesNotChanged") + } + iamAgg := IAMAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewMemberChangedEvent(ctx, member.UserID, member.Roles...)) - events, err := r.eventstore.PushAggregates(ctx, iam) + events, err := r.eventstore.PushAggregates(ctx, iamAgg) if err != nil { return nil, err } @@ -66,8 +70,8 @@ func (r *Repository) ChangeMember(ctx context.Context, member *iam_model.IAMMemb return writeModelToMember(existingMember), nil } -func (r *Repository) RemoveMember(ctx context.Context, member *iam_model.IAMMember) error { - m, err := r.memberWriteModelByID(ctx, member.AggregateID, member.UserID) +func (r *CommandSide) RemoveIAMMember(ctx context.Context, member *iam_model.IAMMember) error { + m, err := r.iamMemberWriteModelByID(ctx, member.AggregateID, member.UserID) if err != nil && !errors.IsNotFound(err) { return err } @@ -75,30 +79,17 @@ func (r *Repository) RemoveMember(ctx context.Context, member *iam_model.IAMMemb return nil } - iamAgg := iam_repo.AggregateFromWriteModel(&m.WriteModel.WriteModel). - PushEvents(iam_repo.NewMemberRemovedEvent(ctx, member.UserID)) + iamAgg := IAMAggregateFromWriteModel(&m.MemberWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewMemberRemovedEvent(ctx, member.UserID)) return r.eventstore.PushAggregate(ctx, m, iamAgg) } -func (r *Repository) MemberByID(ctx context.Context, iamID, userID string) (member *iam_repo.MemberReadModel, err error) { +func (r *CommandSide) iamMemberWriteModelByID(ctx context.Context, iamID, userID string) (member *IAMMemberWriteModel, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - member = iam_repo.NewMemberReadModel(iamID, userID) - err = r.eventstore.FilterToQueryReducer(ctx, member) - if err != nil { - return nil, err - } - - return member, nil -} - -func (r *Repository) memberWriteModelByID(ctx context.Context, iamID, userID string) (member *iam_repo.MemberWriteModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - writeModel := iam_repo.NewMemberWriteModel(iamID, userID) + writeModel := NewIAMMemberWriteModel(iamID, userID) err = r.eventstore.FilterToQueryReducer(ctx, writeModel) if err != nil { return nil, err diff --git a/internal/v2/command/iam_member_model.go b/internal/v2/command/iam_member_model.go new file mode 100644 index 0000000000..67519de626 --- /dev/null +++ b/internal/v2/command/iam_member_model.go @@ -0,0 +1,52 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMMemberWriteModel struct { + MemberWriteModel +} + +func NewIAMMemberWriteModel(iamID, userID string) *IAMMemberWriteModel { + return &IAMMemberWriteModel{ + MemberWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + UserID: userID, + }, + } +} + +func (wm *IAMMemberWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.MemberAddedEvent: + if e.UserID != wm.MemberWriteModel.UserID { + continue + } + wm.MemberWriteModel.AppendEvents(&e.MemberAddedEvent) + case *iam.MemberChangedEvent: + if e.UserID != wm.MemberWriteModel.UserID { + continue + } + wm.MemberWriteModel.AppendEvents(&e.MemberChangedEvent) + case *iam.MemberRemovedEvent: + if e.UserID != wm.MemberWriteModel.UserID { + continue + } + wm.MemberWriteModel.AppendEvents(&e.MemberRemovedEvent) + } + } +} + +func (wm *IAMMemberWriteModel) Reduce() error { + return wm.MemberWriteModel.Reduce() +} + +func (wm *IAMMemberWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.MemberWriteModel.AggregateID) +} diff --git a/internal/v2/command/iam_model.go b/internal/v2/command/iam_model.go new file mode 100644 index 0000000000..14bd79af6c --- /dev/null +++ b/internal/v2/command/iam_model.go @@ -0,0 +1,77 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMWriteModel struct { + eventstore.WriteModel + + SetUpStarted domain.Step + SetUpDone domain.Step + + GlobalOrgID string + ProjectID string +} + +func NewIAMriteModel(iamID string) *IAMWriteModel { + return &IAMWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + } +} + +func (wm *IAMWriteModel) AppendEvents(events ...eventstore.EventReader) { + wm.WriteModel.AppendEvents(events...) + //for _, event := range events { + // switch e := event.(type) { + // case *iam.LabelPolicyAddedEvent: + // wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyAddedEvent) + // case *iam.LabelPolicyChangedEvent: + // wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyChangedEvent) + // } + //} +} + +func (wm *IAMWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *iam.ProjectSetEvent: + wm.ProjectID = e.ProjectID + case *iam.GlobalOrgSetEvent: + wm.GlobalOrgID = e.OrgID + case *iam.SetupStepEvent: + if e.Done { + wm.SetUpDone = e.Step + } else { + wm.SetUpStarted = e.Step + } + } + } + return nil +} + +func (wm *IAMWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.AggregateID) +} + +// +//func (wm *IAMLabelPolicyWriteModel) HasChanged(primaryColor, secondaryColor string) bool { +// if primaryColor != "" && wm.PrimaryColor != primaryColor { +// return true +// } +// if secondaryColor != "" && wm.SecondaryColor != secondaryColor { +// return true +// } +// return false +//} + +func IAMAggregateFromWriteModel(wm *eventstore.WriteModel) *iam.Aggregate { + return &iam.Aggregate{ + Aggregate: *eventstore.AggregateFromWriteModel(wm, iam.AggregateType, iam.AggregateVersion), + } +} diff --git a/internal/v2/command/iam_policy_label.go b/internal/v2/command/iam_policy_label.go new file mode 100644 index 0000000000..1d44e1942c --- /dev/null +++ b/internal/v2/command/iam_policy_label.go @@ -0,0 +1,76 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/telemetry/tracing" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { + if !policy.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-5Mv0s", "Errors.IAM.LabelPolicyInvalid") + } + + addedPolicy := NewIAMLabelPolicyWriteModel(policy.AggregateID) + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LabelPolicy.AlreadyExists") + } + + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewLabelPolicyAddedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor)) + + err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToLabelPolicy(addedPolicy), nil +} + +func (r *CommandSide) ChangeDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { + if !policy.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-6M0od", "Errors.IAM.LabelPolicyInvalid") + } + + existingPolicy, err := r.defaultLabelPolicyWriteModelByID(ctx, policy.AggregateID) + if err != nil { + return nil, err + } + + if !existingPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0K9dq", "Errors.IAM.LabelPolicy.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") + } + + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToLabelPolicy(existingPolicy), nil +} + +func (r *CommandSide) defaultLabelPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMLabelPolicyWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMLabelPolicyWriteModel(iamID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_policy_label_model.go b/internal/v2/command/iam_policy_label_model.go new file mode 100644 index 0000000000..8d745d4044 --- /dev/null +++ b/internal/v2/command/iam_policy_label_model.go @@ -0,0 +1,60 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMLabelPolicyWriteModel struct { + LabelPolicyWriteModel +} + +func NewIAMLabelPolicyWriteModel(iamID string) *IAMLabelPolicyWriteModel { + return &IAMLabelPolicyWriteModel{ + LabelPolicyWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *IAMLabelPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.LabelPolicyAddedEvent: + wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyAddedEvent) + case *iam.LabelPolicyChangedEvent: + wm.LabelPolicyWriteModel.AppendEvents(&e.LabelPolicyChangedEvent) + } + } +} + +func (wm *IAMLabelPolicyWriteModel) Reduce() error { + return wm.LabelPolicyWriteModel.Reduce() +} + +func (wm *IAMLabelPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.LabelPolicyWriteModel.AggregateID) +} + +func (wm *IAMLabelPolicyWriteModel) NewChangedEvent( + ctx context.Context, + primaryColor, + secondaryColor string, +) (*iam.LabelPolicyChangedEvent, bool) { + + hasChanged := false + changedEvent := iam.NewLabelPolicyChangedEvent(ctx) + if wm.PrimaryColor != primaryColor { + hasChanged = true + changedEvent.PrimaryColor = primaryColor + } + if wm.SecondaryColor != secondaryColor { + hasChanged = true + changedEvent.SecondaryColor = secondaryColor + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/iam_policy_login.go b/internal/v2/command/iam_policy_login.go new file mode 100644 index 0000000000..61bfaf05a8 --- /dev/null +++ b/internal/v2/command/iam_policy_login.go @@ -0,0 +1,183 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/telemetry/tracing" + "github.com/caos/zitadel/internal/v2/domain" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) AddDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { + addedPolicy := NewIAMLoginPolicyWriteModel(policy.AggregateID) + iamAgg, err := r.addDefaultLoginPolicy(ctx, addedPolicy, policy) + if err != nil { + return nil, err + } + err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToLoginPolicy(addedPolicy), nil +} + +func (r *CommandSide) addDefaultLoginPolicy(ctx context.Context, addedPolicy *IAMLoginPolicyWriteModel, policy *iam_model.LoginPolicy) (*iam_repo.Aggregate, error) { + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.AlreadyExists") + } + + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.LoginPolicyWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewLoginPolicyAddedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIdp, policy.ForceMFA, domain.PasswordlessType(policy.PasswordlessType))) + + return iamAgg, nil +} + +func (r *CommandSide) ChangeDefaultLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { + if !policy.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-6M0od", "Errors.IAM.LoginPolicyInvalid") + } + + existingPolicy, err := r.defaultLoginPolicyWriteModelByID(ctx, policy.AggregateID) + if err != nil { + return nil, err + } + if !existingPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-M0sif", "Errors.IAM.LoginPolicy.NotFound") + } + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.AllowUsernamePassword, policy.AllowRegister, policy.AllowExternalIdp, policy.ForceMFA, domain.PasswordlessType(policy.PasswordlessType)) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-5M9vdd", "Errors.IAM.LoginPolicy.NotChanged") + } + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToLoginPolicy(existingPolicy), nil +} + +func (r *CommandSide) AddIDPProviderToDefaultLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) { + idpModel := NewIAMIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID) + err := r.eventstore.FilterToQueryReducer(ctx, idpModel) + if err != nil { + return nil, err + } + if idpModel.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.IDP.AlreadyExists") + } + + iamAgg := IAMAggregateFromWriteModel(&idpModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewIdentityProviderAddedEvent(ctx, idpProvider.IDPConfigID, domain.IdentityProviderType(idpProvider.Type))) + + if err = r.eventstore.PushAggregate(ctx, idpModel, iamAgg); err != nil { + return nil, err + } + + return writeModelToIDPProvider(idpModel), nil +} + +func (r *CommandSide) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) error { + idpModel := NewIAMIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID) + err := r.eventstore.FilterToQueryReducer(ctx, idpModel) + if err != nil { + return err + } + if !idpModel.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-39fjs", "Errors.IAM.LoginPolicy.IDP.NotExisting") + } + iamAgg := IAMAggregateFromWriteModel(&idpModel.IdentityProviderWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewIdentityProviderRemovedEvent(ctx, idpProvider.IDPConfigID)) + + return r.eventstore.PushAggregate(ctx, idpModel, iamAgg) +} + +func (r *CommandSide) AddSecondFactorToDefaultLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.SecondFactorType) (iam_model.SecondFactorType, error) { + secondFactorModel := NewIAMSecondFactorWriteModel(iamID) + err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel) + if err != nil { + return iam_model.SecondFactorTypeUnspecified, err + } + + if secondFactorModel.IsActive { + return iam_model.SecondFactorTypeUnspecified, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") + } + + iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewLoginPolicySecondFactorAddedEvent(ctx, domain.SecondFactorType(secondFactor))) + + if err = r.eventstore.PushAggregate(ctx, secondFactorModel, iamAgg); err != nil { + return iam_model.SecondFactorTypeUnspecified, err + } + + return iam_model.SecondFactorType(secondFactorModel.MFAType), nil +} + +func (r *CommandSide) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Context, iamID string, secondFactor iam_model.SecondFactorType) error { + secondFactorModel := NewIAMSecondFactorWriteModel(iamID) + err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel) + if err != nil { + return err + } + if !secondFactorModel.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-3M9od", "Errors.IAM.LoginPolicy.MFA.NotExisting") + } + iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewLoginPolicySecondFactorRemovedEvent(ctx, domain.SecondFactorType(secondFactor))) + + return r.eventstore.PushAggregate(ctx, secondFactorModel, iamAgg) +} + +func (r *CommandSide) AddMultiFactorToDefaultLoginPolicy(ctx context.Context, iamID string, multiFactor iam_model.MultiFactorType) (iam_model.MultiFactorType, error) { + multiFactorModel := NewIAMMultiFactorWriteModel(iamID) + err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel) + if err != nil { + return iam_model.MultiFactorTypeUnspecified, err + } + if multiFactorModel.IsActive { + return iam_model.MultiFactorTypeUnspecified, caos_errs.ThrowAlreadyExists(nil, "IAM-3M9od", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") + } + iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewLoginPolicyMultiFactorAddedEvent(ctx, domain.MultiFactorType(multiFactor))) + + if err = r.eventstore.PushAggregate(ctx, multiFactorModel, iamAgg); err != nil { + return iam_model.MultiFactorTypeUnspecified, err + } + + return iam_model.MultiFactorType(multiFactorModel.MultiFactoryWriteModel.MFAType), nil +} + +func (r *CommandSide) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Context, iamID string, multiFactor iam_model.MultiFactorType) error { + multiFactorModel := NewIAMMultiFactorWriteModel(iamID) + err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel) + if err != nil { + return err + } + if multiFactorModel.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-3M9df", "Errors.IAM.LoginPolicy.MFA.NotExisting") + } + iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewLoginPolicyMultiFactorRemovedEvent(ctx, domain.MultiFactorType(multiFactor))) + + return r.eventstore.PushAggregate(ctx, multiFactorModel, iamAgg) +} + +func (r *CommandSide) defaultLoginPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMLoginPolicyWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMLoginPolicyWriteModel(iamID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_policy_login_factors_model.go b/internal/v2/command/iam_policy_login_factors_model.go new file mode 100644 index 0000000000..d8aa092e8b --- /dev/null +++ b/internal/v2/command/iam_policy_login_factors_model.go @@ -0,0 +1,70 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMSecondFactorWriteModel struct { + SecondFactorWriteModel +} + +func NewIAMSecondFactorWriteModel(iamID string) *IAMSecondFactorWriteModel { + return &IAMSecondFactorWriteModel{ + SecondFactorWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *IAMSecondFactorWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.LoginPolicySecondFactorAddedEvent: + wm.WriteModel.AppendEvents(&e.SecondFactorAddedEvent) + } + } +} + +func (wm *IAMSecondFactorWriteModel) Reduce() error { + return wm.WriteModel.Reduce() +} + +func (wm *IAMSecondFactorWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.WriteModel.AggregateID) +} + +type IAMMultiFactorWriteModel struct { + MultiFactoryWriteModel +} + +func NewIAMMultiFactorWriteModel(iamID string) *IAMMultiFactorWriteModel { + return &IAMMultiFactorWriteModel{ + MultiFactoryWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *IAMMultiFactorWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.LoginPolicyMultiFactorAddedEvent: + wm.WriteModel.AppendEvents(&e.MultiFactorAddedEvent) + } + } +} + +func (wm *IAMMultiFactorWriteModel) Reduce() error { + return wm.WriteModel.Reduce() +} + +func (wm *IAMMultiFactorWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.WriteModel.AggregateID) +} diff --git a/internal/v2/command/iam_policy_login_identity_provider.go b/internal/v2/command/iam_policy_login_identity_provider.go new file mode 100644 index 0000000000..5c04266933 --- /dev/null +++ b/internal/v2/command/iam_policy_login_identity_provider.go @@ -0,0 +1,42 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMIdentityProviderWriteModel struct { + IdentityProviderWriteModel +} + +func NewIAMIdentityProviderWriteModel(iamID, idpConfigID string) *IAMIdentityProviderWriteModel { + return &IAMIdentityProviderWriteModel{ + IdentityProviderWriteModel: IdentityProviderWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + IDPConfigID: idpConfigID, + }, + } +} + +func (wm *IAMIdentityProviderWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.IdentityProviderAddedEvent: + if e.IDPConfigID != wm.IDPConfigID { + continue + } + wm.IdentityProviderWriteModel.AppendEvents(&e.IdentityProviderAddedEvent) + } + } +} + +func (wm *IAMIdentityProviderWriteModel) Reduce() error { + return wm.IdentityProviderWriteModel.Reduce() +} + +func (wm *IAMIdentityProviderWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.AggregateID) +} diff --git a/internal/v2/command/iam_policy_login_model.go b/internal/v2/command/iam_policy_login_model.go new file mode 100644 index 0000000000..ff669e70ac --- /dev/null +++ b/internal/v2/command/iam_policy_login_model.go @@ -0,0 +1,80 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMLoginPolicyWriteModel struct { + LoginPolicyWriteModel +} + +func NewIAMLoginPolicyWriteModel(iamID string) *IAMLoginPolicyWriteModel { + return &IAMLoginPolicyWriteModel{ + LoginPolicyWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *IAMLoginPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.LoginPolicyAddedEvent: + wm.LoginPolicyWriteModel.AppendEvents(&e.LoginPolicyAddedEvent) + case *iam.LoginPolicyChangedEvent: + wm.LoginPolicyWriteModel.AppendEvents(&e.LoginPolicyChangedEvent) + } + } +} + +func (wm *IAMLoginPolicyWriteModel) IsValid() bool { + return wm.AggregateID != "" +} + +func (wm *IAMLoginPolicyWriteModel) Reduce() error { + return wm.LoginPolicyWriteModel.Reduce() +} + +func (wm *IAMLoginPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.LoginPolicyWriteModel.AggregateID) +} + +func (wm *IAMLoginPolicyWriteModel) NewChangedEvent( + ctx context.Context, + allowUsernamePassword, + allowRegister, + allowExternalIDP, + forceMFA bool, + passwordlessType domain.PasswordlessType, +) (*iam.LoginPolicyChangedEvent, bool) { + + hasChanged := false + changedEvent := iam.NewLoginPolicyChangedEvent(ctx) + if wm.AllowUserNamePassword == allowUsernamePassword { + hasChanged = true + changedEvent.AllowUserNamePassword = allowUsernamePassword + } + if wm.AllowRegister == allowRegister { + hasChanged = true + changedEvent.AllowRegister = allowRegister + } + if wm.AllowExternalIDP == allowExternalIDP { + hasChanged = true + changedEvent.AllowExternalIDP = allowExternalIDP + } + if wm.ForceMFA != forceMFA { + hasChanged = true + changedEvent.ForceMFA = forceMFA + } + if passwordlessType.Valid() && wm.PasswordlessType != passwordlessType { + hasChanged = true + changedEvent.PasswordlessType = passwordlessType + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/iam_policy_org_iam.go b/internal/v2/command/iam_policy_org_iam.go new file mode 100644 index 0000000000..8c328cccaa --- /dev/null +++ b/internal/v2/command/iam_policy_org_iam.go @@ -0,0 +1,77 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/telemetry/tracing" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) GetDefaultOrgIAMPolicy(ctx context.Context, aggregateID string) (*iam_model.OrgIAMPolicy, error) { + policyWriteModel := NewIAMOrgIAMPolicyWriteModel(aggregateID) + err := r.eventstore.FilterToQueryReducer(ctx, policyWriteModel) + if err != nil { + return nil, err + } + policy := writeModelToOrgIAMPolicy(policyWriteModel) + policy.Default = true + return policy, nil +} + +func (r *CommandSide) AddDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { + addedPolicy := NewIAMOrgIAMPolicyWriteModel(policy.AggregateID) + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.OrgIAMPolicy.AlreadyExists") + } + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.PolicyOrgIAMWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain)) + + err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToOrgIAMPolicy(addedPolicy), nil +} + +func (r *CommandSide) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { + existingPolicy, err := r.defaultOrgIAMPolicyWriteModelByID(ctx, policy.AggregateID) + if err != nil { + return nil, err + } + if !existingPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0Pl0d", "Errors.IAM.OrgIAMPolicy.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.UserLoginMustBeDomain) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") + } + + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToOrgIAMPolicy(existingPolicy), nil +} + +func (r *CommandSide) defaultOrgIAMPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMOrgIAMPolicyWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMOrgIAMPolicyWriteModel(iamID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_policy_org_iam_model.go b/internal/v2/command/iam_policy_org_iam_model.go new file mode 100644 index 0000000000..8ecbda2f72 --- /dev/null +++ b/internal/v2/command/iam_policy_org_iam_model.go @@ -0,0 +1,51 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMOrgIAMPolicyWriteModel struct { + PolicyOrgIAMWriteModel +} + +func NewIAMOrgIAMPolicyWriteModel(iamID string) *IAMOrgIAMPolicyWriteModel { + return &IAMOrgIAMPolicyWriteModel{ + PolicyOrgIAMWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *IAMOrgIAMPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.OrgIAMPolicyAddedEvent: + wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyAddedEvent) + case *iam.OrgIAMPolicyChangedEvent: + wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyChangedEvent) + } + } +} + +func (wm *IAMOrgIAMPolicyWriteModel) Reduce() error { + return wm.PolicyOrgIAMWriteModel.Reduce() +} + +func (wm *IAMOrgIAMPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID) +} + +func (wm *IAMOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLoginMustBeDomain bool) (*iam.OrgIAMPolicyChangedEvent, bool) { + hasChanged := false + changedEvent := iam.NewOrgIAMPolicyChangedEvent(ctx) + if wm.UserLoginMustBeDomain != userLoginMustBeDomain { + hasChanged = true + changedEvent.UserLoginMustBeDomain = userLoginMustBeDomain + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/iam_policy_password_age.go b/internal/v2/command/iam_policy_password_age.go new file mode 100644 index 0000000000..8946b8cc9e --- /dev/null +++ b/internal/v2/command/iam_policy_password_age.go @@ -0,0 +1,67 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/telemetry/tracing" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) AddDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { + addedPolicy := NewIAMPasswordAgePolicyWriteModel(policy.AggregateID) + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.PasswordAgePolicy.AlreadyExists") + } + + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.PasswordAgePolicyWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewPasswordAgePolicyAddedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays)) + + err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToPasswordAgePolicy(addedPolicy), nil +} + +func (r *CommandSide) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { + existingPolicy, err := r.defaultPasswordAgePolicyWriteModelByID(ctx, policy.AggregateID) + if err != nil { + return nil, err + } + if !existingPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0oPew", "Errors.IAM.PasswordAgePolicy.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") + } + + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordAgePolicyWriteModel.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToPasswordAgePolicy(existingPolicy), nil +} + +func (r *CommandSide) defaultPasswordAgePolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordAgePolicyWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMPasswordAgePolicyWriteModel(iamID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_policy_password_age_model.go b/internal/v2/command/iam_policy_password_age_model.go new file mode 100644 index 0000000000..f7dcfaafd6 --- /dev/null +++ b/internal/v2/command/iam_policy_password_age_model.go @@ -0,0 +1,55 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMPasswordAgePolicyWriteModel struct { + PasswordAgePolicyWriteModel +} + +func NewIAMPasswordAgePolicyWriteModel(iamID string) *IAMPasswordAgePolicyWriteModel { + return &IAMPasswordAgePolicyWriteModel{ + PasswordAgePolicyWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *IAMPasswordAgePolicyWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.PasswordAgePolicyAddedEvent: + wm.PasswordAgePolicyWriteModel.AppendEvents(&e.PasswordAgePolicyAddedEvent) + case *iam.PasswordAgePolicyChangedEvent: + wm.PasswordAgePolicyWriteModel.AppendEvents(&e.PasswordAgePolicyChangedEvent) + } + } +} + +func (wm *IAMPasswordAgePolicyWriteModel) Reduce() error { + return wm.PasswordAgePolicyWriteModel.Reduce() +} + +func (wm *IAMPasswordAgePolicyWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.PasswordAgePolicyWriteModel.AggregateID) +} + +func (wm *IAMPasswordAgePolicyWriteModel) NewChangedEvent(ctx context.Context, expireWarnDays, maxAgeDays uint64) (*iam.PasswordAgePolicyChangedEvent, bool) { + hasChanged := false + changedEvent := iam.NewPasswordAgePolicyChangedEvent(ctx) + if wm.ExpireWarnDays != expireWarnDays { + hasChanged = true + changedEvent.ExpireWarnDays = expireWarnDays + } + if wm.MaxAgeDays != maxAgeDays { + hasChanged = true + changedEvent.MaxAgeDays = maxAgeDays + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/iam_policy_password_complexity.go b/internal/v2/command/iam_policy_password_complexity.go new file mode 100644 index 0000000000..274e4a3c38 --- /dev/null +++ b/internal/v2/command/iam_policy_password_complexity.go @@ -0,0 +1,94 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/telemetry/tracing" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) GetDefaultPasswordComplexityPolicy(ctx context.Context, aggregateID string) (*iam_model.PasswordComplexityPolicy, error) { + policyWriteModel := NewIAMPasswordComplexityPolicyWriteModel(aggregateID) + err := r.eventstore.FilterToQueryReducer(ctx, policyWriteModel) + if err != nil { + return nil, err + } + policy := writeModelToPasswordComplexityPolicy(policyWriteModel) + policy.Default = true + return policy, nil +} + +func (r *CommandSide) AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { + addedPolicy := NewIAMPasswordComplexityPolicyWriteModel(policy.AggregateID) + iamAgg, err := r.addDefaultPasswordComplexityPolicy(ctx, addedPolicy, policy) + if err != nil { + return nil, err + } + + err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToPasswordComplexityPolicy(addedPolicy), nil +} + +func (r *CommandSide) addDefaultPasswordComplexityPolicy(ctx context.Context, addedPolicy *IAMPasswordComplexityPolicyWriteModel, policy *iam_model.PasswordComplexityPolicy) (*iam_repo.Aggregate, error) { + if err := policy.IsValid(); err != nil { + return nil, err + } + + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordComplexityPolicy.AlreadyExists") + } + + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.PasswordComplexityPolicyWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewPasswordComplexityPolicyAddedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol)) + + return iamAgg, nil +} + +func (r *CommandSide) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { + if err := policy.IsValid(); err != nil { + return nil, err + } + + existingPolicy, err := r.defaultPasswordComplexityPolicyWriteModelByID(ctx, policy.AggregateID) + if err != nil { + return nil, err + } + if !existingPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0oPew", "Errors.IAM.PasswordAgePolicy.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.MinLength, policy.HasLowercase, policy.HasUppercase, policy.HasNumber, policy.HasSymbol) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.LabelPolicy.NotChanged") + } + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordComplexityPolicyWriteModel.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToPasswordComplexityPolicy(existingPolicy), nil +} + +func (r *CommandSide) defaultPasswordComplexityPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordComplexityPolicyWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMPasswordComplexityPolicyWriteModel(iamID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_policy_password_complexity_model.go b/internal/v2/command/iam_policy_password_complexity_model.go new file mode 100644 index 0000000000..b9b03e5457 --- /dev/null +++ b/internal/v2/command/iam_policy_password_complexity_model.go @@ -0,0 +1,75 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMPasswordComplexityPolicyWriteModel struct { + PasswordComplexityPolicyWriteModel +} + +func NewIAMPasswordComplexityPolicyWriteModel(iamID string) *IAMPasswordComplexityPolicyWriteModel { + return &IAMPasswordComplexityPolicyWriteModel{ + PasswordComplexityPolicyWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *IAMPasswordComplexityPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.PasswordComplexityPolicyAddedEvent: + wm.PasswordComplexityPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent) + case *iam.PasswordComplexityPolicyChangedEvent: + wm.PasswordComplexityPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent) + } + } +} + +func (wm *IAMPasswordComplexityPolicyWriteModel) Reduce() error { + return wm.PasswordComplexityPolicyWriteModel.Reduce() +} + +func (wm *IAMPasswordComplexityPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID) +} + +func (wm *IAMPasswordComplexityPolicyWriteModel) NewChangedEvent( + ctx context.Context, + minLength uint64, + hasLowercase, + hasUppercase, + hasNumber, + hasSymbol bool, +) (*iam.PasswordComplexityPolicyChangedEvent, bool) { + + hasChanged := false + changedEvent := iam.NewPasswordComplexityPolicyChangedEvent(ctx) + if wm.MinLength != minLength { + hasChanged = true + changedEvent.MinLength = minLength + } + if wm.HasLowercase != hasLowercase { + hasChanged = true + changedEvent.HasLowercase = hasLowercase + } + if wm.HasUpperCase != hasUppercase { + hasChanged = true + changedEvent.HasUpperCase = hasUppercase + } + if wm.HasNumber != hasNumber { + hasChanged = true + changedEvent.HasNumber = hasNumber + } + if wm.HasSymbol != hasSymbol { + hasChanged = true + changedEvent.HasSymbol = hasSymbol + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/iam_policy_password_lockout.go b/internal/v2/command/iam_policy_password_lockout.go new file mode 100644 index 0000000000..3ac9f03946 --- /dev/null +++ b/internal/v2/command/iam_policy_password_lockout.go @@ -0,0 +1,67 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/telemetry/tracing" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { + addedPolicy := NewIAMPasswordLockoutPolicyWriteModel(policy.AggregateID) + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists") + } + + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.PasswordLockoutPolicyWriteModel.WriteModel) + iamAgg.PushEvents(iam_repo.NewPasswordLockoutPolicyAddedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures)) + + err = r.eventstore.PushAggregate(ctx, addedPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToPasswordLockoutPolicy(addedPolicy), nil +} + +func (r *CommandSide) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { + existingPolicy, err := r.defaultPasswordLockoutPolicyWriteModelByID(ctx, policy.AggregateID) + if err != nil { + return nil, err + } + if !existingPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-0oPew", "Errors.IAM.PasswordLockoutPolicy.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-4M9vs", "Errors.IAM.PasswordLockoutPolicy.NotChanged") + } + + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.PasswordLockoutPolicyWriteModel.WriteModel) + iamAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, iamAgg) + if err != nil { + return nil, err + } + + return writeModelToPasswordLockoutPolicy(existingPolicy), nil +} + +func (r *CommandSide) defaultPasswordLockoutPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordLockoutPolicyWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewIAMPasswordLockoutPolicyWriteModel(iamID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/iam_policy_password_lockout_model.go b/internal/v2/command/iam_policy_password_lockout_model.go new file mode 100644 index 0000000000..be81f63e88 --- /dev/null +++ b/internal/v2/command/iam_policy_password_lockout_model.go @@ -0,0 +1,55 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMPasswordLockoutPolicyWriteModel struct { + PasswordLockoutPolicyWriteModel +} + +func NewIAMPasswordLockoutPolicyWriteModel(iamID string) *IAMPasswordLockoutPolicyWriteModel { + return &IAMPasswordLockoutPolicyWriteModel{ + PasswordLockoutPolicyWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *IAMPasswordLockoutPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.PasswordLockoutPolicyAddedEvent: + wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent) + case *iam.PasswordLockoutPolicyChangedEvent: + wm.PasswordLockoutPolicyWriteModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent) + } + } +} + +func (wm *IAMPasswordLockoutPolicyWriteModel) Reduce() error { + return wm.PasswordLockoutPolicyWriteModel.Reduce() +} + +func (wm *IAMPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID) +} + +func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) (*iam.PasswordLockoutPolicyChangedEvent, bool) { + hasChanged := false + changedEvent := iam.NewPasswordLockoutPolicyChangedEvent(ctx) + if wm.MaxAttempts != maxAttempts { + hasChanged = true + changedEvent.MaxAttempts = maxAttempts + } + if wm.ShowLockOutFailures != showLockoutFailure { + hasChanged = true + changedEvent.ShowLockOutFailures = showLockoutFailure + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/identity_provider_model.go b/internal/v2/command/identity_provider_model.go new file mode 100644 index 0000000000..9942b69267 --- /dev/null +++ b/internal/v2/command/identity_provider_model.go @@ -0,0 +1,29 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IdentityProviderWriteModel struct { + eventstore.WriteModel + + IDPConfigID string + IDPProviderType domain.IdentityProviderType + IsActive bool +} + +func (wm *IdentityProviderWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *policy.IdentityProviderAddedEvent: + wm.IDPConfigID = e.IDPConfigID + wm.IDPProviderType = e.IDPProviderType + wm.IsActive = true + case *policy.IdentityProviderRemovedEvent: + wm.IsActive = false + } + } + return wm.WriteModel.Reduce() +} diff --git a/internal/v2/command/idp_config_model.go b/internal/v2/command/idp_config_model.go new file mode 100644 index 0000000000..759e6013fc --- /dev/null +++ b/internal/v2/command/idp_config_model.go @@ -0,0 +1,75 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/idpconfig" +) + +type IDPConfigWriteModel struct { + eventstore.WriteModel + + State domain.IDPConfigState + + ConfigID string + Name string + StylingType domain.IDPConfigStylingType + + OIDCConfig *OIDCConfigWriteModel +} + +func (rm *IDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) { + rm.WriteModel.AppendEvents(events...) + for _, event := range events { + switch event.(type) { + case *idpconfig.OIDCConfigAddedEvent: + rm.OIDCConfig = new(OIDCConfigWriteModel) + rm.OIDCConfig.AppendEvents(event) + case *idpconfig.OIDCConfigChangedEvent: + rm.OIDCConfig.AppendEvents(event) + } + } +} + +func (rm *IDPConfigWriteModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *idpconfig.IDPConfigAddedEvent: + rm.reduceConfigAddedEvent(e) + case *idpconfig.IDPConfigChangedEvent: + rm.reduceConfigChangedEvent(e) + case *idpconfig.IDPConfigDeactivatedEvent: + rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateInactive) + case *idpconfig.IDPConfigReactivatedEvent: + rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateActive) + case *idpconfig.IDPConfigRemovedEvent: + rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateRemoved) + } + } + if rm.OIDCConfig != nil { + if err := rm.OIDCConfig.Reduce(); err != nil { + return err + } + } + return rm.WriteModel.Reduce() +} + +func (rm *IDPConfigWriteModel) reduceConfigAddedEvent(e *idpconfig.IDPConfigAddedEvent) { + rm.ConfigID = e.ConfigID + rm.Name = e.Name + rm.StylingType = e.StylingType + rm.State = domain.IDPConfigStateActive +} + +func (rm *IDPConfigWriteModel) reduceConfigChangedEvent(e *idpconfig.IDPConfigChangedEvent) { + if e.Name != "" { + rm.Name = e.Name + } + if e.StylingType.Valid() { + rm.StylingType = e.StylingType + } +} + +func (rm *IDPConfigWriteModel) reduceConfigStateChanged(configID string, state domain.IDPConfigState) { + rm.State = state +} diff --git a/internal/v2/command/member_model.go b/internal/v2/command/member_model.go new file mode 100644 index 0000000000..be94ee2ade --- /dev/null +++ b/internal/v2/command/member_model.go @@ -0,0 +1,37 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/member" +) + +type MemberWriteModel struct { + eventstore.WriteModel + + UserID string + Roles []string + IsActive bool +} + +func NewMemberWriteModel(userID string) *MemberWriteModel { + return &MemberWriteModel{ + UserID: userID, + } +} + +func (wm *MemberWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *member.MemberAddedEvent: + wm.UserID = e.UserID + wm.Roles = e.Roles + wm.IsActive = true + case *member.MemberChangedEvent: + wm.Roles = e.Roles + case *member.MemberRemovedEvent: + wm.Roles = nil + wm.IsActive = false + } + } + return wm.WriteModel.Reduce() +} diff --git a/internal/v2/repository/idp/oidc/config_write_model.go b/internal/v2/command/oidc_config_model.go similarity index 51% rename from internal/v2/repository/idp/oidc/config_write_model.go rename to internal/v2/command/oidc_config_model.go index 147772aadf..33f7cb7a23 100644 --- a/internal/v2/repository/idp/oidc/config_write_model.go +++ b/internal/v2/command/oidc_config_model.go @@ -1,11 +1,13 @@ -package oidc +package command import ( "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/idpconfig" ) -type ConfigWriteModel struct { +type OIDCConfigWriteModel struct { eventstore.WriteModel IDPConfigID string @@ -14,24 +16,31 @@ type ConfigWriteModel struct { Issuer string Scopes []string - IDPDisplayNameMapping MappingField - UserNameMapping MappingField + IDPDisplayNameMapping domain.OIDCMappingField + UserNameMapping domain.OIDCMappingField + State domain.IDPConfigState } -func (wm *ConfigWriteModel) Reduce() error { +func (wm *OIDCConfigWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *ConfigAddedEvent: + case *idpconfig.OIDCConfigAddedEvent: wm.reduceConfigAddedEvent(e) - case *ConfigChangedEvent: + case *idpconfig.OIDCConfigChangedEvent: wm.reduceConfigChangedEvent(e) + case *idpconfig.IDPConfigDeactivatedEvent: + wm.State = domain.IDPConfigStateInactive + case *idpconfig.IDPConfigReactivatedEvent: + wm.State = domain.IDPConfigStateActive + case *idpconfig.IDPConfigRemovedEvent: + wm.State = domain.IDPConfigStateRemoved } } return wm.WriteModel.Reduce() } -func (wm *ConfigWriteModel) reduceConfigAddedEvent(e *ConfigAddedEvent) { +func (wm *OIDCConfigWriteModel) reduceConfigAddedEvent(e *idpconfig.OIDCConfigAddedEvent) { wm.IDPConfigID = e.IDPConfigID wm.ClientID = e.ClientID wm.ClientSecret = e.ClientSecret @@ -39,9 +48,10 @@ func (wm *ConfigWriteModel) reduceConfigAddedEvent(e *ConfigAddedEvent) { wm.Scopes = e.Scopes wm.IDPDisplayNameMapping = e.IDPDisplayNameMapping wm.UserNameMapping = e.UserNameMapping + wm.State = domain.IDPConfigStateActive } -func (wm *ConfigWriteModel) reduceConfigChangedEvent(e *ConfigChangedEvent) { +func (wm *OIDCConfigWriteModel) reduceConfigChangedEvent(e *idpconfig.OIDCConfigChangedEvent) { if e.ClientID != "" { wm.ClientID = e.ClientID } diff --git a/internal/v2/command/org_converter.go b/internal/v2/command/org_converter.go new file mode 100644 index 0000000000..466d44dcf0 --- /dev/null +++ b/internal/v2/command/org_converter.go @@ -0,0 +1,23 @@ +package command + +import ( + "github.com/caos/zitadel/internal/iam/model" +) + +func orgWriteModelToOrgIAMPolicy(wm *ORGOrgIAMPolicyWriteModel) *model.OrgIAMPolicy { + return &model.OrgIAMPolicy{ + ObjectRoot: writeModelToObjectRoot(wm.PolicyOrgIAMWriteModel.WriteModel), + UserLoginMustBeDomain: wm.UserLoginMustBeDomain, + } +} + +func orgWriteModelToPasswordComplexityPolicy(wm *OrgPasswordComplexityPolicyWriteModel) *model.PasswordComplexityPolicy { + return &model.PasswordComplexityPolicy{ + ObjectRoot: writeModelToObjectRoot(wm.PasswordComplexityPolicyWriteModel.WriteModel), + MinLength: wm.MinLength, + HasLowercase: wm.HasLowercase, + HasUppercase: wm.HasUpperCase, + HasNumber: wm.HasNumber, + HasSymbol: wm.HasSymbol, + } +} diff --git a/internal/v2/command/org_member_model.go b/internal/v2/command/org_member_model.go new file mode 100644 index 0000000000..97b0e272f8 --- /dev/null +++ b/internal/v2/command/org_member_model.go @@ -0,0 +1,5 @@ +package command + +type OrgMemberWriteModel struct { + MemberWriteModel +} diff --git a/internal/v2/command/org_model.go b/internal/v2/command/org_model.go new file mode 100644 index 0000000000..88c29b1eb2 --- /dev/null +++ b/internal/v2/command/org_model.go @@ -0,0 +1,12 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" +) + +func ORGAggregateFromWriteModel(wm *eventstore.WriteModel) *org.Aggregate { + return &org.Aggregate{ + Aggregate: *eventstore.AggregateFromWriteModel(wm, org.AggregateType, org.AggregateVersion), + } +} diff --git a/internal/v2/command/org_policy_org_iam.go b/internal/v2/command/org_policy_org_iam.go new file mode 100644 index 0000000000..c71450705b --- /dev/null +++ b/internal/v2/command/org_policy_org_iam.go @@ -0,0 +1,78 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/telemetry/tracing" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) GetOrgIAMPolicy(ctx context.Context, orgID string) (*iam_model.OrgIAMPolicy, error) { + policy := NewORGOrgIAMPolicyWriteModel(orgID) + err := r.eventstore.FilterToQueryReducer(ctx, policy) + if err != nil { + return nil, err + } + if policy.IsActive { + return orgWriteModelToOrgIAMPolicy(policy), nil + } + return r.GetDefaultOrgIAMPolicy(ctx, r.iamID) +} + +func (r *CommandSide) AddOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { + addedPolicy := NewORGOrgIAMPolicyWriteModel(policy.AggregateID) + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return nil, err + } + if addedPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-5M0ds", "Errors.Org.OrgIAMPolicy.AlreadyExists") + } + orgAgg := ORGAggregateFromWriteModel(&addedPolicy.PolicyOrgIAMWriteModel.WriteModel) + orgAgg.PushEvents(iam_repo.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain)) + + err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg) + if err != nil { + return nil, err + } + + return orgWriteModelToOrgIAMPolicy(addedPolicy), nil +} + +func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { + existingPolicy, err := r.orgIAMPolicyWriteModelByID(ctx, policy.AggregateID) + if err != nil { + return nil, err + } + if !existingPolicy.IsActive { + return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-2N9sd", "Errors.Org.OrgIAMPolicy.NotFound") + } + + changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, policy.UserLoginMustBeDomain) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-3M9ds", "Errors.Org.LabelPolicy.NotChanged") + } + + orgAgg := ORGAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel) + orgAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg) + if err != nil { + return nil, err + } + + return orgWriteModelToOrgIAMPolicy(existingPolicy), nil +} + +func (r *CommandSide) orgIAMPolicyWriteModelByID(ctx context.Context, iamID string) (policy *ORGOrgIAMPolicyWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel := NewORGOrgIAMPolicyWriteModel(iamID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/org_policy_org_iam_model.go b/internal/v2/command/org_policy_org_iam_model.go new file mode 100644 index 0000000000..b2ad24880f --- /dev/null +++ b/internal/v2/command/org_policy_org_iam_model.go @@ -0,0 +1,51 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" +) + +type ORGOrgIAMPolicyWriteModel struct { + PolicyOrgIAMWriteModel +} + +func NewORGOrgIAMPolicyWriteModel(orgID string) *ORGOrgIAMPolicyWriteModel { + return &ORGOrgIAMPolicyWriteModel{ + PolicyOrgIAMWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: orgID, + }, + }, + } +} + +func (wm *ORGOrgIAMPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.OrgIAMPolicyAddedEvent: + wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyAddedEvent) + case *org.OrgIAMPolicyChangedEvent: + wm.PolicyOrgIAMWriteModel.AppendEvents(&e.OrgIAMPolicyChangedEvent) + } + } +} + +func (wm *ORGOrgIAMPolicyWriteModel) Reduce() error { + return wm.PolicyOrgIAMWriteModel.Reduce() +} + +func (wm *ORGOrgIAMPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). + AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID) +} + +func (wm *ORGOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLoginMustBeDomain bool) (*org.OrgIAMPolicyChangedEvent, bool) { + hasChanged := false + changedEvent := org.NewOrgIAMPolicyChangedEvent(ctx) + if wm.UserLoginMustBeDomain != userLoginMustBeDomain { + hasChanged = true + changedEvent.UserLoginMustBeDomain = userLoginMustBeDomain + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/org_policy_password_complexity.go b/internal/v2/command/org_policy_password_complexity.go new file mode 100644 index 0000000000..534897cfa5 --- /dev/null +++ b/internal/v2/command/org_policy_password_complexity.go @@ -0,0 +1,18 @@ +package command + +import ( + "context" + iam_model "github.com/caos/zitadel/internal/iam/model" +) + +func (r *CommandSide) GetOrgPasswordComplexityPolicy(ctx context.Context, orgID string) (*iam_model.PasswordComplexityPolicy, error) { + policy := NewOrgPasswordComplexityPolicyWriteModel(orgID) + err := r.eventstore.FilterToQueryReducer(ctx, policy) + if err != nil { + return nil, err + } + if policy.IsActive { + return orgWriteModelToPasswordComplexityPolicy(policy), nil + } + return r.GetDefaultPasswordComplexityPolicy(ctx, r.iamID) +} diff --git a/internal/v2/command/org_policy_password_complexity_model.go b/internal/v2/command/org_policy_password_complexity_model.go new file mode 100644 index 0000000000..123f685a16 --- /dev/null +++ b/internal/v2/command/org_policy_password_complexity_model.go @@ -0,0 +1,75 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" +) + +type OrgPasswordComplexityPolicyWriteModel struct { + PasswordComplexityPolicyWriteModel +} + +func NewOrgPasswordComplexityPolicyWriteModel(iamID string) *OrgPasswordComplexityPolicyWriteModel { + return &OrgPasswordComplexityPolicyWriteModel{ + PasswordComplexityPolicyWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: iamID, + }, + }, + } +} + +func (wm *OrgPasswordComplexityPolicyWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.PasswordComplexityPolicyAddedEvent: + wm.PasswordComplexityPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent) + case *org.PasswordComplexityPolicyChangedEvent: + wm.PasswordComplexityPolicyWriteModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent) + } + } +} + +func (wm *OrgPasswordComplexityPolicyWriteModel) Reduce() error { + return wm.PasswordComplexityPolicyWriteModel.Reduce() +} + +func (wm *OrgPasswordComplexityPolicyWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType). + AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID) +} + +func (wm *OrgPasswordComplexityPolicyWriteModel) NewChangedEvent( + ctx context.Context, + minLength uint64, + hasLowercase, + hasUppercase, + hasNumber, + hasSymbol bool, +) (*org.PasswordComplexityPolicyChangedEvent, bool) { + + hasChanged := false + changedEvent := org.NewPasswordComplexityPolicyChangedEvent(ctx) + if wm.MinLength != minLength { + hasChanged = true + changedEvent.MinLength = minLength + } + if wm.HasLowercase != hasLowercase { + hasChanged = true + changedEvent.HasLowercase = hasLowercase + } + if wm.HasUpperCase != hasUppercase { + hasChanged = true + changedEvent.HasUpperCase = hasUppercase + } + if wm.HasNumber != hasNumber { + hasChanged = true + changedEvent.HasNumber = hasNumber + } + if wm.HasSymbol != hasSymbol { + hasChanged = true + changedEvent.HasSymbol = hasSymbol + } + return changedEvent, hasChanged +} diff --git a/internal/v2/repository/policy/label/write_model.go b/internal/v2/command/policy_label_model.go similarity index 53% rename from internal/v2/repository/policy/label/write_model.go rename to internal/v2/command/policy_label_model.go index 1fa2cf7f0d..0c13c77012 100644 --- a/internal/v2/repository/policy/label/write_model.go +++ b/internal/v2/command/policy_label_model.go @@ -1,25 +1,30 @@ -package label +package command import ( "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" ) -type WriteModel struct { +type LabelPolicyWriteModel struct { eventstore.WriteModel PrimaryColor string SecondaryColor string + IsActive bool } -func (wm *WriteModel) Reduce() error { +func (wm *LabelPolicyWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.LabelPolicyAddedEvent: wm.PrimaryColor = e.PrimaryColor wm.SecondaryColor = e.SecondaryColor - case *ChangedEvent: + wm.IsActive = true + case *policy.LabelPolicyChangedEvent: wm.PrimaryColor = e.PrimaryColor wm.SecondaryColor = e.SecondaryColor + case *policy.LabelPolicyRemovedEvent: + wm.IsActive = false } } return wm.WriteModel.Reduce() diff --git a/internal/v2/repository/policy/login/factors/write_model.go b/internal/v2/command/policy_login_factors_model.go similarity index 50% rename from internal/v2/repository/policy/login/factors/write_model.go rename to internal/v2/command/policy_login_factors_model.go index 619c253c44..4404fb9224 100644 --- a/internal/v2/repository/policy/login/factors/write_model.go +++ b/internal/v2/command/policy_login_factors_model.go @@ -1,19 +1,26 @@ -package factors +package command -import "github.com/caos/zitadel/internal/eventstore/v2" +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" +) type SecondFactorWriteModel struct { eventstore.WriteModel - MFAType SecondFactorType + MFAType domain.SecondFactorType + IsActive bool } func (wm *SecondFactorWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *SecondFactorAddedEvent: + case *policy.SecondFactorAddedEvent: wm.MFAType = e.MFAType - case *SecondFactorRemovedEvent: + wm.IsActive = true + case *policy.SecondFactorRemovedEvent: wm.MFAType = e.MFAType + wm.IsActive = false } } return wm.WriteModel.Reduce() @@ -21,16 +28,19 @@ func (wm *SecondFactorWriteModel) Reduce() error { type MultiFactoryWriteModel struct { eventstore.WriteModel - MFAType MultiFactorType + MFAType domain.MultiFactorType + IsActive bool } func (wm *MultiFactoryWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *MultiFactorAddedEvent: + case *policy.MultiFactorAddedEvent: wm.MFAType = e.MFAType - case *MultiFactorRemovedEvent: + wm.IsActive = true + case *policy.MultiFactorRemovedEvent: wm.MFAType = e.MFAType + wm.IsActive = false } } return wm.WriteModel.Reduce() diff --git a/internal/v2/repository/policy/login/write_model.go b/internal/v2/command/policy_login_model.go similarity index 61% rename from internal/v2/repository/policy/login/write_model.go rename to internal/v2/command/policy_login_model.go index 8d52453cd4..31d1ae2297 100644 --- a/internal/v2/repository/policy/login/write_model.go +++ b/internal/v2/command/policy_login_model.go @@ -1,34 +1,40 @@ -package login +package command import ( "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" ) -type WriteModel struct { +type LoginPolicyWriteModel struct { eventstore.WriteModel AllowUserNamePassword bool AllowRegister bool AllowExternalIDP bool ForceMFA bool - PasswordlessType PasswordlessType + PasswordlessType domain.PasswordlessType + IsActive bool } -func (wm *WriteModel) Reduce() error { +func (wm *LoginPolicyWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.LoginPolicyAddedEvent: wm.AllowRegister = e.AllowRegister wm.AllowUserNamePassword = e.AllowUserNamePassword wm.AllowExternalIDP = e.AllowExternalIDP wm.ForceMFA = e.ForceMFA wm.PasswordlessType = e.PasswordlessType - case *ChangedEvent: + wm.IsActive = true + case *policy.LoginPolicyChangedEvent: wm.AllowRegister = e.AllowRegister wm.AllowUserNamePassword = e.AllowUserNamePassword wm.AllowExternalIDP = e.AllowExternalIDP wm.ForceMFA = e.ForceMFA wm.PasswordlessType = e.PasswordlessType + case *policy.LoginPolicyRemovedEvent: + wm.IsActive = false } } return wm.WriteModel.Reduce() diff --git a/internal/v2/command/policy_org_iam_model.go b/internal/v2/command/policy_org_iam_model.go new file mode 100644 index 0000000000..497ef2f094 --- /dev/null +++ b/internal/v2/command/policy_org_iam_model.go @@ -0,0 +1,26 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type PolicyOrgIAMWriteModel struct { + eventstore.WriteModel + + UserLoginMustBeDomain bool + IsActive bool +} + +func (wm *PolicyOrgIAMWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *policy.OrgIAMPolicyAddedEvent: + wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain + wm.IsActive = true + case *policy.OrgIAMPolicyChangedEvent: + wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain + } + } + return wm.WriteModel.Reduce() +} diff --git a/internal/v2/repository/policy/password_age/write_model.go b/internal/v2/command/policy_password_age_model.go similarity index 50% rename from internal/v2/repository/policy/password_age/write_model.go rename to internal/v2/command/policy_password_age_model.go index 13fb16885a..d77b4a70a4 100644 --- a/internal/v2/repository/policy/password_age/write_model.go +++ b/internal/v2/command/policy_password_age_model.go @@ -1,25 +1,30 @@ -package password_age +package command import ( "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" ) -type WriteModel struct { +type PasswordAgePolicyWriteModel struct { eventstore.WriteModel ExpireWarnDays uint64 MaxAgeDays uint64 + IsActive bool } -func (wm *WriteModel) Reduce() error { +func (wm *PasswordAgePolicyWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.PasswordAgePolicyAddedEvent: wm.ExpireWarnDays = e.ExpireWarnDays wm.MaxAgeDays = e.MaxAgeDays - case *ChangedEvent: + wm.IsActive = true + case *policy.PasswordAgePolicyChangedEvent: wm.ExpireWarnDays = e.ExpireWarnDays wm.MaxAgeDays = e.MaxAgeDays + case *policy.PasswordAgePolicyRemovedEvent: + wm.IsActive = false } } return wm.WriteModel.Reduce() diff --git a/internal/v2/repository/policy/password_complexity/write_model.go b/internal/v2/command/policy_password_complexity_model.go similarity index 60% rename from internal/v2/repository/policy/password_complexity/write_model.go rename to internal/v2/command/policy_password_complexity_model.go index f5d8eb4717..4ac9dc640c 100644 --- a/internal/v2/repository/policy/password_complexity/write_model.go +++ b/internal/v2/command/policy_password_complexity_model.go @@ -1,10 +1,11 @@ -package password_complexity +package command import ( "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" ) -type WriteModel struct { +type PasswordComplexityPolicyWriteModel struct { eventstore.WriteModel MinLength uint64 @@ -12,23 +13,27 @@ type WriteModel struct { HasUpperCase bool HasNumber bool HasSymbol bool + IsActive bool } -func (wm *WriteModel) Reduce() error { +func (wm *PasswordComplexityPolicyWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.PasswordComplexityPolicyAddedEvent: wm.MinLength = e.MinLength wm.HasLowercase = e.HasLowercase wm.HasUpperCase = e.HasUpperCase wm.HasNumber = e.HasNumber wm.HasSymbol = e.HasSymbol - case *ChangedEvent: + wm.IsActive = true + case *policy.PasswordComplexityPolicyChangedEvent: wm.MinLength = e.MinLength wm.HasLowercase = e.HasLowercase wm.HasUpperCase = e.HasUpperCase wm.HasNumber = e.HasNumber wm.HasSymbol = e.HasSymbol + case *policy.PasswordComplexityPolicyRemovedEvent: + wm.IsActive = false } } return wm.WriteModel.Reduce() diff --git a/internal/v2/repository/policy/password_lockout/write_model.go b/internal/v2/command/policy_password_lockout_model.go similarity index 51% rename from internal/v2/repository/policy/password_lockout/write_model.go rename to internal/v2/command/policy_password_lockout_model.go index 510e54f173..9c866f1a63 100644 --- a/internal/v2/repository/policy/password_lockout/write_model.go +++ b/internal/v2/command/policy_password_lockout_model.go @@ -1,25 +1,30 @@ -package password_lockout +package command import ( "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" ) -type WriteModel struct { +type PasswordLockoutPolicyWriteModel struct { eventstore.WriteModel MaxAttempts uint64 ShowLockOutFailures bool + IsActive bool } -func (wm *WriteModel) Reduce() error { +func (wm *PasswordLockoutPolicyWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.PasswordLockoutPolicyAddedEvent: wm.MaxAttempts = e.MaxAttempts wm.ShowLockOutFailures = e.ShowLockOutFailures - case *ChangedEvent: + wm.IsActive = true + case *policy.PasswordLockoutPolicyChangedEvent: wm.MaxAttempts = e.MaxAttempts wm.ShowLockOutFailures = e.ShowLockOutFailures + case *policy.PasswordLockoutPolicyRemovedEvent: + wm.IsActive = false } } return wm.WriteModel.Reduce() diff --git a/internal/v2/command/setup.go b/internal/v2/command/setup.go new file mode 100644 index 0000000000..bf00dea788 --- /dev/null +++ b/internal/v2/command/setup.go @@ -0,0 +1,65 @@ +package command + +import ( + "context" + + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *CommandSide) StartSetup(ctx context.Context, iamID string, step domain.Step) (*iam_model.IAM, error) { + iamWriteModel, err := r.iamByID(ctx, iamID) + if err != nil && !caos_errs.IsNotFound(err) { + return nil, err + } + if iamWriteModel.SetUpStarted >= step || iamWriteModel.SetUpStarted != iamWriteModel.SetUpDone { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error") + } + aggregate := IAMAggregateFromWriteModel(&iamWriteModel.WriteModel).PushEvents(iam_repo.NewSetupStepStartedEvent(ctx, step)) + err = r.eventstore.PushAggregate(ctx, iamWriteModel, aggregate) + if err != nil { + return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Grgh1", "Setup start failed") + } + return writeModelToIAM(iamWriteModel), nil +} + +//func (r *CommandSide) setupDone(ctx context.Context, iamAgg *iam_repo.Aggregate, event eventstore.EventPusher, aggregates ...eventstore.Aggregater) error { +// aggregate := iamAgg.PushEvents(event) +// +// aggregates = append(aggregates, aggregate) +// _, err := r.eventstore.PushAggregates(ctx, aggregates...) +// if err != nil { +// return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Dgd2", "Setup done failed") +// } +// return nil +//} + +// +////TODO: should not use readmodel +//func (r *CommandSide) setup(ctx context.Context, iamID string, step iam_repo.Step, event eventstore.EventPusher) (*iam_model.IAM, error) { +// iam, err := r.iamByID(ctx, iamID) +// if err != nil && !caos_errs.IsNotFound(err) { +// return nil, err +// } +// +// if iam != nil && (iam.SetUpStarted >= iam_repo.Step(step) || iam.SetUpStarted != iam.SetUpDone) { +// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error") +// } +// +// aggregate := query.AggregateFromReadModel(iam). +// PushEvents(event) +// +// events, err := r.eventstore.PushAggregates(ctx, aggregate) +// if err != nil { +// return nil, err +// } +// +// if err = iam.AppendAndReduce(events...); err != nil { +// return nil, err +// } +// return nil, nil +// //TODO: return write model +// //return readModelToIAM(iam), nil +//} diff --git a/internal/v2/command/setup_step1.go b/internal/v2/command/setup_step1.go new file mode 100644 index 0000000000..0782403e8f --- /dev/null +++ b/internal/v2/command/setup_step1.go @@ -0,0 +1,107 @@ +package command + +import ( + "context" + + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type Step1 struct { + GlobalOrg string + IAMProject string + DefaultLoginPolicy LoginPolicy //*iam_model.LoginPolicy + Orgs []Org + Owners []string + + //setup *Setup + //createdUsers map[string]*usr_model.User + //createdOrgs map[string]*org_model.Org + //createdProjects map[string]*proj_model.Project + //pwComplexityPolicy *iam_model.PasswordComplexityPolicyView +} + +type LoginPolicy struct { + AllowRegister bool + AllowUsernamePassword bool + AllowExternalIdp bool +} + +type User struct { + FirstName string + LastName string + UserName string + Email string + Password string +} + +type Org struct { + Name string + Domain string + OrgIamPolicy bool + Users []User + Owners []string + Projects []Project +} + +type Project struct { + Name string + Users []User + Members []string + OIDCApps []OIDCApp +} + +type OIDCApp struct { + Name string + RedirectUris []string + ResponseTypes []string + GrantTypes []string + ApplicationType string + AuthMethodType string + PostLogoutRedirectUris []string + DevMode bool +} + +func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 Step1) error { + iam, err := r.iamByID(ctx, iamID) + if err != nil && !caos_errs.IsNotFound(err) { + return err + } + //create default login policy + iamAgg, err := r.addDefaultLoginPolicy(ctx, + NewIAMLoginPolicyWriteModel(iam.AggregateID), + &iam_model.LoginPolicy{ + AllowUsernamePassword: step1.DefaultLoginPolicy.AllowUsernamePassword, + AllowRegister: step1.DefaultLoginPolicy.AllowRegister, + AllowExternalIdp: step1.DefaultLoginPolicy.AllowExternalIdp, + }) + if err != nil { + return err + } + //create orgs + //create projects + //create applications + //set iam owners + //set global org + //set iam project id + + /*aggregates: + iam: + default login policy + iam owner + org: + default + caos + zitadel + + */ + iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, domain.Step1)) + + _, err = r.eventstore.PushAggregates(ctx, iamAgg) + if err != nil { + return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Gr2hh", "Setup Step1 failed") + } + return nil +} diff --git a/internal/v2/command/setup_step2.go b/internal/v2/command/setup_step2.go new file mode 100644 index 0000000000..46d5ff24af --- /dev/null +++ b/internal/v2/command/setup_step2.go @@ -0,0 +1,38 @@ +package command + +import ( + "context" + + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/domain" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type Step2 struct { + DefaultPasswordComplexityPolicy iam_model.PasswordComplexityPolicy +} + +func (r *CommandSide) SetupStep2(ctx context.Context, iamID string, step Step2) error { + iam, err := r.iamByID(ctx, iamID) + if err != nil && !caos_errs.IsNotFound(err) { + return err + } + iamAgg, err := r.addDefaultPasswordComplexityPolicy(ctx, NewIAMPasswordComplexityPolicyWriteModel(iam.AggregateID), &iam_model.PasswordComplexityPolicy{ + MinLength: step.DefaultPasswordComplexityPolicy.MinLength, + HasLowercase: step.DefaultPasswordComplexityPolicy.HasLowercase, + HasUppercase: step.DefaultPasswordComplexityPolicy.HasUppercase, + HasNumber: step.DefaultPasswordComplexityPolicy.HasNumber, + HasSymbol: step.DefaultPasswordComplexityPolicy.HasSymbol, + }) + if err != nil { + return err + } + iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, domain.Step1)) + + _, err = r.eventstore.PushAggregates(ctx, iamAgg) + if err != nil { + return caos_errs.ThrowPreconditionFailed(nil, "EVENT-HR2na", "Setup Step2 failed") + } + return nil +} diff --git a/internal/v2/command/user.go b/internal/v2/command/user.go new file mode 100644 index 0000000000..9da407266c --- /dev/null +++ b/internal/v2/command/user.go @@ -0,0 +1,123 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/telemetry/tracing" + usr_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/user" +) + +func (r *CommandSide) AddUser(ctx context.Context, user *usr_model.User) (*usr_model.User, error) { + if !user.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2N9fs", "Errors.User.Invalid") + } + + if user.Human != nil { + human, err := r.AddHuman(ctx, user.ResourceOwner, user.UserName, user.Human) + if err != nil { + return nil, err + } + return &usr_model.User{UserName: user.UserName, Human: human}, nil + } else if user.Machine != nil { + + } + return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-8K0df", "Errors.User.TypeUndefined") +} + +func (r *CommandSide) DeactivateUser(ctx context.Context, userID string) (*usr_model.User, error) { + existingUser, err := r.userWriteModelByID(ctx, userID) + if err != nil { + return nil, err + } + if existingUser.UserState != domain.UserStateUnspecified || existingUser.UserState != domain.UserStateDeleted { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-3M9ds", "Errors.User.NotFound") + } + if existingUser.UserState == domain.UserStateInactive { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5M0sf", "Errors.User.AlreadyInactive") + } + userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) + userAgg.PushEvents(user.NewUserDeactivatedEvent(ctx)) + + err = r.eventstore.PushAggregate(ctx, existingUser, userAgg) + if err != nil { + return nil, err + } + return writeModelToUser(existingUser), nil +} + +func (r *CommandSide) ReactivateUser(ctx context.Context, userID string) (*usr_model.User, error) { + existingUser, err := r.userWriteModelByID(ctx, userID) + if err != nil { + return nil, err + } + if existingUser.UserState != domain.UserStateUnspecified || existingUser.UserState != domain.UserStateDeleted { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-4M0sd", "Errors.User.NotFound") + } + if existingUser.UserState != domain.UserStateInactive { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6M0sf", "Errors.User.NotInactive") + } + userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) + userAgg.PushEvents(user.NewUserReactivatedEvent(ctx)) + + err = r.eventstore.PushAggregate(ctx, existingUser, userAgg) + if err != nil { + return nil, err + } + return writeModelToUser(existingUser), nil +} + +func (r *CommandSide) LockUser(ctx context.Context, userID string) (*usr_model.User, error) { + existingUser, err := r.userWriteModelByID(ctx, userID) + if err != nil { + return nil, err + } + if existingUser.UserState != domain.UserStateUnspecified || existingUser.UserState != domain.UserStateDeleted { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-5M9fs", "Errors.User.NotFound") + } + if existingUser.UserState != domain.UserStateActive && existingUser.UserState != domain.UserStateInitial { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M9fs", "Errors.User.ShouldBeActiveOrInitial") + } + userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) + userAgg.PushEvents(user.NewUserLockedEvent(ctx)) + + err = r.eventstore.PushAggregate(ctx, existingUser, userAgg) + if err != nil { + return nil, err + } + return writeModelToUser(existingUser), nil +} + +func (r *CommandSide) UnlockUser(ctx context.Context, userID string) (*usr_model.User, error) { + existingUser, err := r.userWriteModelByID(ctx, userID) + if err != nil { + return nil, err + } + if existingUser.UserState != domain.UserStateUnspecified || existingUser.UserState != domain.UserStateDeleted { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-M0dos", "Errors.User.NotFound") + } + if existingUser.UserState != domain.UserStateLocked { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0ds", "Errors.User.NotLocked") + } + userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel) + userAgg.PushEvents(user.NewUserUnlockedEvent(ctx)) + + err = r.eventstore.PushAggregate(ctx, existingUser, userAgg) + if err != nil { + return nil, err + } + return writeModelToUser(existingUser), nil +} + +func (r *CommandSide) userWriteModelByID(ctx context.Context, userID string) (writeModel *UserWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel = NewUserWriteModel(userID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/user_converter.go b/internal/v2/command/user_converter.go new file mode 100644 index 0000000000..bf9a9d4f64 --- /dev/null +++ b/internal/v2/command/user_converter.go @@ -0,0 +1,62 @@ +package command + +import ( + "github.com/caos/zitadel/internal/user/model" +) + +func writeModelToUser(wm *UserWriteModel) *model.User { + return &model.User{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + UserName: wm.UserName, + State: model.UserState(wm.UserState), + } +} + +func writeModelToHuman(wm *HumanWriteModel) *model.Human { + return &model.Human{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + Profile: &model.Profile{ + FirstName: wm.FirstName, + LastName: wm.LastName, + NickName: wm.NickName, + DisplayName: wm.DisplayName, + PreferredLanguage: wm.PreferredLanguage, + Gender: model.Gender(wm.Gender), + }, + Email: &model.Email{ + EmailAddress: wm.Email, + IsEmailVerified: wm.IsEmailVerified, + }, + } +} + +func writeModelToProfile(wm *HumanProfileWriteModel) *model.Profile { + return &model.Profile{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + FirstName: wm.FirstName, + LastName: wm.LastName, + NickName: wm.NickName, + DisplayName: wm.DisplayName, + PreferredLanguage: wm.PreferredLanguage, + Gender: model.Gender(wm.Gender), + } +} + +func writeModelToEmail(wm *HumanEmailWriteModel) *model.Email { + return &model.Email{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + EmailAddress: wm.Email, + IsEmailVerified: wm.IsEmailVerified, + } +} + +func writeModelToAddress(wm *HumanAddressWriteModel) *model.Address { + return &model.Address{ + ObjectRoot: writeModelToObjectRoot(wm.WriteModel), + Country: wm.Country, + Locality: wm.Locality, + PostalCode: wm.PostalCode, + Region: wm.Region, + StreetAddress: wm.StreetAddress, + } +} diff --git a/internal/v2/command/user_human.go b/internal/v2/command/user_human.go new file mode 100644 index 0000000000..88736f43f2 --- /dev/null +++ b/internal/v2/command/user_human.go @@ -0,0 +1,71 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + usr_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/user" +) + +func (r *CommandSide) AddHuman(ctx context.Context, orgID, username string, human *usr_model.Human) (*usr_model.Human, error) { + if !human.IsValid() { + return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.User.Invalid") + } + userID, err := r.idGenerator.Next() + if err != nil { + return nil, err + } + human.AggregateID = userID + orgIAMPolicy, err := r.GetOrgIAMPolicy(ctx, orgID) + if err != nil { + return nil, err + } + //pwPolicy, err := r.GetOrgPasswordComplexityPolicy(ctx, orgID) + //if err != nil { + // return nil, err + //} + + addedHuman := NewHumanWriteModel(human.AggregateID) + //TODO: Check Unique Username + human.CheckOrgIAMPolicy(username, orgIAMPolicy) + human.SetNamesAsDisplayname() + //human.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg, true) + + userAgg := UserAggregateFromWriteModel(&addedHuman.WriteModel) + userAgg.PushEvents( + user.NewHumanAddedEvent( + ctx, + username, + human.FirstName, + human.LastName, + human.NickName, + human.DisplayName, + human.PreferredLanguage, + domain.Gender(human.Gender), + human.EmailAddress, + human.PhoneNumber, + human.Country, + human.Locality, + human.PostalCode, + human.Region, + human.StreetAddress, + ), + ) + //TODO: HashPassword If existing + //TODO: Generate Init Code if needed + //TODO: Generate Phone Code if needed + if human.Email != nil && human.EmailAddress != "" && human.IsEmailVerified { + userAgg.PushEvents(user.NewHumanEmailVerifiedEvent(ctx)) + } + if human.Phone != nil && human.PhoneNumber != "" && human.IsPhoneVerified { + userAgg.PushEvents(user.NewHumanPhoneVerifiedEvent(ctx)) + } + + err = r.eventstore.PushAggregate(ctx, addedHuman, userAgg) + if err != nil { + return nil, err + } + + return writeModelToHuman(addedHuman), nil +} diff --git a/internal/v2/command/user_human_address.go b/internal/v2/command/user_human_address.go new file mode 100644 index 0000000000..f5d80465ab --- /dev/null +++ b/internal/v2/command/user_human_address.go @@ -0,0 +1,44 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/telemetry/tracing" + usr_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/v2/domain" +) + +func (r *CommandSide) ChangeHumanAddress(ctx context.Context, address *usr_model.Address) (*usr_model.Address, error) { + existingAddress, err := r.addressWriteModel(ctx, address.AggregateID) + if err != nil { + return nil, err + } + if existingAddress.UserState == domain.UserStateUnspecified || existingAddress.UserState == domain.UserStateDeleted { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-0pLdo", "Errors.User.Address.NotFound") + } + changedEvent, hasChanged := existingAddress.NewChangedEvent(ctx, address.Country, address.Locality, address.PostalCode, address.Region, address.StreetAddress) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-3M0cs", "Errors.User.Address.NotChanged") + } + userAgg := UserAggregateFromWriteModel(&existingAddress.WriteModel) + userAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingAddress, userAgg) + if err != nil { + return nil, err + } + + return writeModelToAddress(existingAddress), nil +} + +func (r *CommandSide) addressWriteModel(ctx context.Context, userID string) (writeModel *HumanAddressWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel = NewHumanAddressWriteModel(userID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/user_human_address_model.go b/internal/v2/command/user_human_address_model.go new file mode 100644 index 0000000000..c9ce9b58aa --- /dev/null +++ b/internal/v2/command/user_human_address_model.go @@ -0,0 +1,109 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/user" +) + +type HumanAddressWriteModel struct { + eventstore.WriteModel + + Country string + Locality string + PostalCode string + Region string + StreetAddress string + + UserState domain.UserState +} + +func NewHumanAddressWriteModel(userID string) *HumanAddressWriteModel { + return &HumanAddressWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: userID, + }, + } +} + +func (wm *HumanAddressWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *user.HumanAddressChangedEvent: + wm.AppendEvents(e) + case *user.HumanAddedEvent, *user.HumanRegisteredEvent: + wm.AppendEvents(e) + case *user.UserRemovedEvent: + wm.AppendEvents(e) + } + } +} + +func (wm *HumanAddressWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *user.HumanAddedEvent: + wm.Country = e.Country + wm.Locality = e.Locality + wm.PostalCode = e.PostalCode + wm.Region = e.Region + wm.StreetAddress = e.StreetAddress + wm.UserState = domain.UserStateActive + case *user.HumanRegisteredEvent: + wm.Country = e.Country + wm.Locality = e.Locality + wm.PostalCode = e.PostalCode + wm.Region = e.Region + wm.StreetAddress = e.StreetAddress + wm.UserState = domain.UserStateActive + case *user.HumanAddressChangedEvent: + wm.Country = e.Country + wm.Locality = e.Locality + wm.PostalCode = e.PostalCode + wm.Region = e.Region + wm.StreetAddress = e.StreetAddress + case *user.UserRemovedEvent: + wm.UserState = domain.UserStateDeleted + } + } + return wm.WriteModel.Reduce() +} + +func (wm *HumanAddressWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). + AggregateIDs(wm.AggregateID) +} + +func (wm *HumanAddressWriteModel) NewChangedEvent( + ctx context.Context, + country, + locality, + postalCode, + region, + streetAddress string, +) (*user.HumanAddressChangedEvent, bool) { + hasChanged := false + changedEvent := user.NewHumanAddressChangedEvent(ctx) + if wm.Country != country { + hasChanged = true + changedEvent.Country = country + } + if wm.Locality != locality { + hasChanged = true + changedEvent.Locality = locality + } + if wm.PostalCode != postalCode { + hasChanged = true + changedEvent.PostalCode = postalCode + } + if wm.Region != region { + hasChanged = true + changedEvent.Region = region + } + if wm.StreetAddress != streetAddress { + hasChanged = true + changedEvent.StreetAddress = streetAddress + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/user_human_email.go b/internal/v2/command/user_human_email.go new file mode 100644 index 0000000000..e1843bc64f --- /dev/null +++ b/internal/v2/command/user_human_email.go @@ -0,0 +1,48 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/telemetry/tracing" + usr_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/v2/domain" +) + +func (r *CommandSide) ChangeHumanEmail(ctx context.Context, email *usr_model.Email) (*usr_model.Email, error) { + if !email.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M9sf", "Errors.Email.Invalid") + } + + existingEmail, err := r.emailWriteModel(ctx, email.AggregateID) + if err != nil { + return nil, err + } + if existingEmail.UserState == domain.UserStateUnspecified || existingEmail.UserState == domain.UserStateDeleted { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-0Pe4r", "Errors.User.Email.NotFound") + } + changedEvent, hasChanged := existingEmail.NewChangedEvent(ctx, email.EmailAddress) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-2M9fs", "Errors.User.Email.NotChanged") + } + userAgg := UserAggregateFromWriteModel(&existingEmail.WriteModel) + userAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingEmail, userAgg) + if err != nil { + return nil, err + } + + return writeModelToEmail(existingEmail), nil +} + +func (r *CommandSide) emailWriteModel(ctx context.Context, userID string) (writeModel *HumanEmailWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel = NewHumanEmailWriteModel(userID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/user_human_email_model.go b/internal/v2/command/user_human_email_model.go new file mode 100644 index 0000000000..69fb6d99d5 --- /dev/null +++ b/internal/v2/command/user_human_email_model.go @@ -0,0 +1,79 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/user" +) + +type HumanEmailWriteModel struct { + eventstore.WriteModel + + Email string + IsEmailVerified bool + + UserState domain.UserState +} + +func NewHumanEmailWriteModel(userID string) *HumanEmailWriteModel { + return &HumanEmailWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: userID, + }, + } +} + +func (wm *HumanEmailWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *user.HumanEmailChangedEvent: + wm.AppendEvents(e) + case *user.HumanEmailVerifiedEvent: + wm.AppendEvents(e) + case *user.HumanAddedEvent, *user.HumanRegisteredEvent: + wm.AppendEvents(e) + case *user.UserRemovedEvent: + wm.AppendEvents(e) + } + } +} + +func (wm *HumanEmailWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *user.HumanAddedEvent: + wm.Email = e.EmailAddress + wm.UserState = domain.UserStateActive + case *user.HumanRegisteredEvent: + wm.Email = e.EmailAddress + wm.UserState = domain.UserStateActive + case *user.HumanEmailChangedEvent: + wm.Email = e.EmailAddress + wm.IsEmailVerified = false + case *user.HumanEmailVerifiedEvent: + wm.IsEmailVerified = true + case *user.UserRemovedEvent: + wm.UserState = domain.UserStateDeleted + } + } + return wm.WriteModel.Reduce() +} + +func (wm *HumanEmailWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). + AggregateIDs(wm.AggregateID) +} + +func (wm *HumanEmailWriteModel) NewChangedEvent( + ctx context.Context, + email string, +) (*user.HumanEmailChangedEvent, bool) { + hasChanged := false + changedEvent := user.NewHumanEmailChangedEvent(ctx) + if wm.Email != email { + hasChanged = true + changedEvent.EmailAddress = email + } + return changedEvent, hasChanged +} diff --git a/internal/v2/command/user_human_model.go b/internal/v2/command/user_human_model.go new file mode 100644 index 0000000000..7fb5fb10db --- /dev/null +++ b/internal/v2/command/user_human_model.go @@ -0,0 +1,104 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/user" + "golang.org/x/text/language" +) + +type HumanWriteModel struct { + eventstore.WriteModel + + UserName string + + FirstName string + LastName string + NickName string + DisplayName string + PreferredLanguage language.Tag + Gender domain.Gender + + Email string + IsEmailVerified bool + + Phone string + IsPhoneVerified bool + + Country string + Locality string + PostalCode string + Region string + StreetAddress string + + UserState domain.UserState +} + +func NewHumanWriteModel(userID string) *HumanWriteModel { + return &HumanWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: userID, + }, + } +} + +func (wm *HumanWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *user.HumanEmailChangedEvent: + wm.AppendEvents(e) + case *user.HumanEmailVerifiedEvent: + wm.AppendEvents(e) + case *user.HumanAddedEvent, *user.HumanRegisteredEvent: + wm.AppendEvents(e) + case *user.UserDeactivatedEvent: + wm.AppendEvents(e) + case *user.UserReactivatedEvent: + wm.AppendEvents(e) + case *user.UserLockedEvent: + wm.AppendEvents(e) + case *user.UserUnlockedEvent: + wm.AppendEvents(e) + case *user.UserRemovedEvent: + wm.AppendEvents(e) + } + } +} + +//TODO: Compute State? initial/active +func (wm *HumanWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *user.HumanAddedEvent: + wm.UserName = e.UserName + wm.UserState = domain.UserStateInitial + case *user.HumanRegisteredEvent: + wm.UserName = e.UserName + wm.UserState = domain.UserStateInitial + case *user.UserLockedEvent: + if wm.UserState != domain.UserStateDeleted { + wm.UserState = domain.UserStateLocked + } + case *user.UserUnlockedEvent: + if wm.UserState != domain.UserStateDeleted { + wm.UserState = domain.UserStateActive + } + case *user.UserDeactivatedEvent: + if wm.UserState != domain.UserStateDeleted { + wm.UserState = domain.UserStateInactive + } + case *user.UserReactivatedEvent: + if wm.UserState != domain.UserStateDeleted { + wm.UserState = domain.UserStateActive + } + case *user.UserRemovedEvent: + wm.UserState = domain.UserStateDeleted + } + } + return wm.WriteModel.Reduce() +} + +func (wm *HumanWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). + AggregateIDs(wm.AggregateID) +} diff --git a/internal/v2/command/user_human_profile.go b/internal/v2/command/user_human_profile.go new file mode 100644 index 0000000000..f8394a3c24 --- /dev/null +++ b/internal/v2/command/user_human_profile.go @@ -0,0 +1,48 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/telemetry/tracing" + usr_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/v2/domain" +) + +func (r *CommandSide) ChangeHumanProfile(ctx context.Context, profile *usr_model.Profile) (*usr_model.Profile, error) { + if !profile.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-8io0d", "Errors.User.Profile.Invalid") + } + + existingProfile, err := r.profileWriteModelByID(ctx, profile.AggregateID) + if err != nil { + return nil, err + } + if existingProfile.UserState == domain.UserStateUnspecified || existingProfile.UserState == domain.UserStateDeleted { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-3M9sd", "Errors.User.Profile.NotFound") + } + changedEvent, hasChanged := existingProfile.NewChangedEvent(ctx, profile.FirstName, profile.LastName, profile.NickName, profile.DisplayName, profile.PreferredLanguage, domain.Gender(profile.Gender)) + if !hasChanged { + return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-2M0fs", "Errors.User.Profile.NotChanged") + } + userAgg := UserAggregateFromWriteModel(&existingProfile.WriteModel) + userAgg.PushEvents(changedEvent) + + err = r.eventstore.PushAggregate(ctx, existingProfile, userAgg) + if err != nil { + return nil, err + } + + return writeModelToProfile(existingProfile), nil +} + +func (r *CommandSide) profileWriteModelByID(ctx context.Context, userID string) (writeModel *HumanProfileWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel = NewHumanProfileWriteModel(userID) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/user_human_profile_model.go b/internal/v2/command/user_human_profile_model.go new file mode 100644 index 0000000000..0cfaa9fa0b --- /dev/null +++ b/internal/v2/command/user_human_profile_model.go @@ -0,0 +1,120 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/user" + "golang.org/x/text/language" +) + +type HumanProfileWriteModel struct { + eventstore.WriteModel + + FirstName string + LastName string + NickName string + DisplayName string + PreferredLanguage language.Tag + Gender domain.Gender + + UserState domain.UserState +} + +func NewHumanProfileWriteModel(userID string) *HumanProfileWriteModel { + return &HumanProfileWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: userID, + }, + } +} + +func (wm *HumanProfileWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *user.HumanProfileChangedEvent: + wm.AppendEvents(e) + case *user.HumanAddedEvent, *user.HumanRegisteredEvent: + wm.AppendEvents(e) + case *user.UserRemovedEvent: + wm.AppendEvents(e) + } + } +} + +func (wm *HumanProfileWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *user.HumanAddedEvent: + wm.FirstName = e.FirstName + wm.LastName = e.LastName + wm.NickName = e.NickName + wm.DisplayName = e.DisplayName + wm.PreferredLanguage = e.PreferredLanguage + wm.Gender = e.Gender + wm.UserState = domain.UserStateActive + case *user.HumanRegisteredEvent: + wm.FirstName = e.FirstName + wm.LastName = e.LastName + wm.NickName = e.NickName + wm.DisplayName = e.DisplayName + wm.PreferredLanguage = e.PreferredLanguage + wm.Gender = e.Gender + wm.UserState = domain.UserStateActive + case *user.HumanProfileChangedEvent: + wm.FirstName = e.FirstName + wm.LastName = e.LastName + wm.NickName = e.NickName + wm.DisplayName = e.DisplayName + wm.PreferredLanguage = e.PreferredLanguage + wm.Gender = e.Gender + case *user.UserRemovedEvent: + wm.UserState = domain.UserStateDeleted + } + } + return wm.WriteModel.Reduce() +} + +func (wm *HumanProfileWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). + AggregateIDs(wm.AggregateID) +} + +func (wm *HumanProfileWriteModel) NewChangedEvent( + ctx context.Context, + firstName, + lastName, + nickName, + displayName string, + preferredLanguage language.Tag, + gender domain.Gender, +) (*user.HumanProfileChangedEvent, bool) { + hasChanged := false + changedEvent := user.NewHumanProfileChangedEvent(ctx) + if wm.FirstName != firstName { + hasChanged = true + changedEvent.FirstName = firstName + } + if wm.LastName != lastName { + hasChanged = true + changedEvent.LastName = lastName + } + if wm.NickName != nickName { + hasChanged = true + changedEvent.NickName = nickName + } + if wm.DisplayName != displayName { + hasChanged = true + changedEvent.DisplayName = displayName + } + if wm.PreferredLanguage != preferredLanguage { + hasChanged = true + changedEvent.PreferredLanguage = preferredLanguage + } + if gender.Valid() && wm.Gender != gender { + hasChanged = true + changedEvent.Gender = gender + } + + return changedEvent, hasChanged +} diff --git a/internal/v2/command/user_model.go b/internal/v2/command/user_model.go new file mode 100644 index 0000000000..5a31d4aa56 --- /dev/null +++ b/internal/v2/command/user_model.go @@ -0,0 +1,95 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/user" +) + +type UserWriteModel struct { + eventstore.WriteModel + + UserName string + UserState domain.UserState +} + +func NewUserWriteModel(userID string) *UserWriteModel { + return &UserWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: userID, + }, + } +} + +func (wm *UserWriteModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *user.HumanEmailChangedEvent: + wm.AppendEvents(e) + case *user.HumanEmailVerifiedEvent: + wm.AppendEvents(e) + case *user.HumanAddedEvent, *user.HumanRegisteredEvent: + wm.AppendEvents(e) + case *user.MachineAddedEvent: + wm.AppendEvents(e) + case *user.UserDeactivatedEvent: + wm.AppendEvents(e) + case *user.UserReactivatedEvent: + wm.AppendEvents(e) + case *user.UserLockedEvent: + wm.AppendEvents(e) + case *user.UserUnlockedEvent: + wm.AppendEvents(e) + case *user.UserRemovedEvent: + wm.AppendEvents(e) + } + } +} + +//TODO: Compute State? initial/active +func (wm *UserWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *user.HumanAddedEvent: + wm.UserName = e.UserName + wm.UserState = domain.UserStateInitial + case *user.HumanRegisteredEvent: + wm.UserName = e.UserName + wm.UserState = domain.UserStateInitial + + case *user.MachineAddedEvent: + wm.UserName = e.UserName + wm.UserState = domain.UserStateActive + case *user.UserLockedEvent: + if wm.UserState != domain.UserStateDeleted { + wm.UserState = domain.UserStateLocked + } + case *user.UserUnlockedEvent: + if wm.UserState != domain.UserStateDeleted { + wm.UserState = domain.UserStateActive + } + case *user.UserDeactivatedEvent: + if wm.UserState != domain.UserStateDeleted { + wm.UserState = domain.UserStateInactive + } + case *user.UserReactivatedEvent: + if wm.UserState != domain.UserStateDeleted { + wm.UserState = domain.UserStateActive + } + case *user.UserRemovedEvent: + wm.UserState = domain.UserStateDeleted + } + } + return wm.WriteModel.Reduce() +} + +func (wm *UserWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). + AggregateIDs(wm.AggregateID) +} + +func UserAggregateFromWriteModel(wm *eventstore.WriteModel) *user.Aggregate { + return &user.Aggregate{ + Aggregate: *eventstore.AggregateFromWriteModel(wm, user.AggregateType, user.AggregateVersion), + } +} diff --git a/internal/v2/repository/policy/login/factors/factors.go b/internal/v2/domain/factors.go similarity index 94% rename from internal/v2/repository/policy/login/factors/factors.go rename to internal/v2/domain/factors.go index 5ef240edcf..862a59e46b 100644 --- a/internal/v2/repository/policy/login/factors/factors.go +++ b/internal/v2/domain/factors.go @@ -1,4 +1,4 @@ -package factors +package domain type SecondFactorType int32 diff --git a/internal/v2/repository/user/human/human.go b/internal/v2/domain/human.go similarity index 92% rename from internal/v2/repository/user/human/human.go rename to internal/v2/domain/human.go index 548d2a45e5..1644604962 100644 --- a/internal/v2/repository/user/human/human.go +++ b/internal/v2/domain/human.go @@ -1,4 +1,4 @@ -package human +package domain type Gender int32 diff --git a/internal/v2/domain/idp_config.go b/internal/v2/domain/idp_config.go new file mode 100644 index 0000000000..48f03b8057 --- /dev/null +++ b/internal/v2/domain/idp_config.go @@ -0,0 +1,42 @@ +package domain + +type IDPConfigType int32 + +const ( + IDPConfigTypeOIDC IDPConfigType = iota + IDPConfigTypeSAML + + //count is for validation + idpConfigTypeCount +) + +func (f IDPConfigType) Valid() bool { + return f >= 0 && f < idpConfigTypeCount +} + +type IDPConfigState int32 + +const ( + IDPConfigStateUnspecified IDPConfigState = iota + IDPConfigStateActive + IDPConfigStateInactive + IDPConfigStateRemoved + + idpConfigStateCount +) + +func (f IDPConfigState) Valid() bool { + return f >= 0 && f < idpConfigStateCount +} + +type IDPConfigStylingType int32 + +const ( + IDPConfigStylingTypeGoogle IDPConfigStylingType = iota + 1 + + idpConfigStylingTypeCount +) + +func (f IDPConfigStylingType) Valid() bool { + return f >= 0 && f < idpConfigStylingTypeCount +} diff --git a/internal/v2/repository/user/machine/keys/key.go b/internal/v2/domain/machine_key.go similarity index 91% rename from internal/v2/repository/user/machine/keys/key.go rename to internal/v2/domain/machine_key.go index 7c9b7ae438..239558e18d 100644 --- a/internal/v2/repository/user/machine/keys/key.go +++ b/internal/v2/domain/machine_key.go @@ -1,4 +1,4 @@ -package keys +package domain type MachineKeyType int32 diff --git a/internal/v2/domain/mfa.go b/internal/v2/domain/mfa.go new file mode 100644 index 0000000000..39156f7fff --- /dev/null +++ b/internal/v2/domain/mfa.go @@ -0,0 +1,15 @@ +package domain + +type MFAState int32 + +const ( + MFAStateUnspecified MFAState = iota + MFAStateNotReady + MFAStateReady + + stateCount +) + +func (f MFAState) Valid() bool { + return f >= 0 && f < stateCount +} diff --git a/internal/v2/domain/notification.go b/internal/v2/domain/notification.go new file mode 100644 index 0000000000..1a45c99461 --- /dev/null +++ b/internal/v2/domain/notification.go @@ -0,0 +1,14 @@ +package domain + +type NotificationType int32 + +const ( + NotificationTypeEmail NotificationType = iota + NotificationTypeSms + + notificationCount +) + +func (f NotificationType) Valid() bool { + return f >= 0 && f < notificationCount +} diff --git a/internal/v2/domain/oidc_mapping_field.go b/internal/v2/domain/oidc_mapping_field.go new file mode 100644 index 0000000000..61b2fb1968 --- /dev/null +++ b/internal/v2/domain/oidc_mapping_field.go @@ -0,0 +1,14 @@ +package domain + +type OIDCMappingField int32 + +const ( + OIDCMappingFieldPreferredLoginName OIDCMappingField = iota + 1 + OIDCMappingFieldEmail + // count is for validation purposes + oidcMappingFieldCount +) + +func (f OIDCMappingField) Valid() bool { + return f > 0 && f < oidcMappingFieldCount +} diff --git a/internal/v2/domain/policy_login.go b/internal/v2/domain/policy_login.go new file mode 100644 index 0000000000..b98f718460 --- /dev/null +++ b/internal/v2/domain/policy_login.go @@ -0,0 +1,14 @@ +package domain + +type PasswordlessType int32 + +const ( + PasswordlessTypeNotAllowed PasswordlessType = iota + PasswordlessTypeAllowed + + passwordlessCount +) + +func (f PasswordlessType) Valid() bool { + return f >= 0 && f < passwordlessCount +} diff --git a/internal/v2/domain/provider.go b/internal/v2/domain/provider.go new file mode 100644 index 0000000000..5cf6c64f07 --- /dev/null +++ b/internal/v2/domain/provider.go @@ -0,0 +1,14 @@ +package domain + +type IdentityProviderType int8 + +const ( + IdentityProviderTypeSystem IdentityProviderType = iota + IdentityProviderTypeOrg + + identityProviderCount +) + +func (f IdentityProviderType) Valid() bool { + return f >= 0 && f < identityProviderCount +} diff --git a/internal/v2/domain/step.go b/internal/v2/domain/step.go new file mode 100644 index 0000000000..72aba2e86c --- /dev/null +++ b/internal/v2/domain/step.go @@ -0,0 +1,16 @@ +package domain + +type Step int + +const ( + Step1 Step = iota + 1 + Step2 + Step3 + Step4 + Step5 + Step6 + Step7 + Step8 + //StepCount marks the the length of possible steps (StepCount-1 == last possible step) + StepCount +) diff --git a/internal/v2/domain/user.go b/internal/v2/domain/user.go new file mode 100644 index 0000000000..b836434f04 --- /dev/null +++ b/internal/v2/domain/user.go @@ -0,0 +1,19 @@ +package domain + +type UserState int32 + +const ( + UserStateUnspecified UserState = iota + UserStateActive + UserStateInactive + UserStateDeleted + UserStateLocked + UserStateSuspend + UserStateInitial + + userStateCount +) + +func (f UserState) Valid() bool { + return f >= 0 && f < userStateCount +} diff --git a/internal/v2/query/converter.go b/internal/v2/query/converter.go new file mode 100644 index 0000000000..24efe2f1a7 --- /dev/null +++ b/internal/v2/query/converter.go @@ -0,0 +1,168 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/iam/model" +) + +func readModelToIAM(readModel *ReadModel) *model.IAM { + return &model.IAM{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + GlobalOrgID: readModel.GlobalOrgID, + IAMProjectID: readModel.ProjectID, + SetUpDone: readModel.SetUpDone, + SetUpStarted: readModel.SetUpStarted, + Members: readModelToMembers(&readModel.Members), + DefaultLabelPolicy: readModelToLabelPolicy(&readModel.DefaultLabelPolicy), + DefaultLoginPolicy: readModelToLoginPolicy(&readModel.DefaultLoginPolicy), + DefaultOrgIAMPolicy: readModelToOrgIAMPolicy(&readModel.DefaultOrgIAMPolicy), + DefaultPasswordAgePolicy: readModelToPasswordAgePolicy(&readModel.DefaultPasswordAgePolicy), + DefaultPasswordComplexityPolicy: readModelToPasswordComplexityPolicy(&readModel.DefaultPasswordComplexityPolicy), + DefaultPasswordLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy), + IDPs: readModelToIDPConfigs(&readModel.IDPs), + } +} + +func readModelToIDPConfigView(rm *IAMIDPConfigReadModel) *model.IDPConfigView { + return &model.IDPConfigView{ + AggregateID: rm.AggregateID, + ChangeDate: rm.ChangeDate, + CreationDate: rm.CreationDate, + IDPConfigID: rm.ConfigID, + IDPProviderType: model.IDPProviderType(rm.ProviderType), + IsOIDC: rm.OIDCConfig != nil, + Name: rm.Name, + OIDCClientID: rm.OIDCConfig.ClientID, + OIDCClientSecret: rm.OIDCConfig.ClientSecret, + OIDCIDPDisplayNameMapping: model.OIDCMappingField(rm.OIDCConfig.IDPDisplayNameMapping), + OIDCIssuer: rm.OIDCConfig.Issuer, + OIDCScopes: rm.OIDCConfig.Scopes, + OIDCUsernameMapping: model.OIDCMappingField(rm.OIDCConfig.UserNameMapping), + Sequence: rm.ProcessedSequence, + State: model.IDPConfigState(rm.State), + StylingType: model.IDPStylingType(rm.StylingType), + } +} + +func readModelToMember(readModel *MemberReadModel) *model.IAMMember { + return &model.IAMMember{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + Roles: readModel.Roles, + UserID: readModel.UserID, + } +} + +func readModelToMembers(readModel *IAMMembersReadModel) []*model.IAMMember { + members := make([]*model.IAMMember, len(readModel.Members)) + + for i, member := range readModel.Members { + members[i] = &model.IAMMember{ + ObjectRoot: readModelToObjectRoot(member.ReadModel), + Roles: member.Roles, + UserID: member.UserID, + } + } + + return members +} + +func readModelToLabelPolicy(readModel *IAMLabelPolicyReadModel) *model.LabelPolicy { + return &model.LabelPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.LabelPolicyReadModel.ReadModel), + PrimaryColor: readModel.PrimaryColor, + SecondaryColor: readModel.SecondaryColor, + Default: true, + //TODO: State: int32, + } +} + +func readModelToLoginPolicy(readModel *IAMLoginPolicyReadModel) *model.LoginPolicy { + return &model.LoginPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.LoginPolicyReadModel.ReadModel), + AllowExternalIdp: readModel.AllowExternalIDP, + AllowRegister: readModel.AllowRegister, + AllowUsernamePassword: readModel.AllowUserNamePassword, + Default: true, + //TODO: IDPProviders: []*model.IDPProvider, + //TODO: State: int32, + } +} +func readModelToOrgIAMPolicy(readModel *IAMOrgIAMPolicyReadModel) *model.OrgIAMPolicy { + return &model.OrgIAMPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.OrgIAMPolicyReadModel.ReadModel), + UserLoginMustBeDomain: readModel.UserLoginMustBeDomain, + Default: true, + //TODO: State: int32, + } +} +func readModelToPasswordAgePolicy(readModel *IAMPasswordAgePolicyReadModel) *model.PasswordAgePolicy { + return &model.PasswordAgePolicy{ + ObjectRoot: readModelToObjectRoot(readModel.PasswordAgePolicyReadModel.ReadModel), + ExpireWarnDays: uint64(readModel.ExpireWarnDays), + MaxAgeDays: uint64(readModel.MaxAgeDays), + //TODO: State: int32, + } +} +func readModelToPasswordComplexityPolicy(readModel *IAMPasswordComplexityPolicyReadModel) *model.PasswordComplexityPolicy { + return &model.PasswordComplexityPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.PasswordComplexityPolicyReadModel.ReadModel), + HasLowercase: readModel.HasLowercase, + HasNumber: readModel.HasNumber, + HasSymbol: readModel.HasSymbol, + HasUppercase: readModel.HasUpperCase, + MinLength: uint64(readModel.MinLength), + //TODO: State: int32, + } +} +func readModelToPasswordLockoutPolicy(readModel *IAMPasswordLockoutPolicyReadModel) *model.PasswordLockoutPolicy { + return &model.PasswordLockoutPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.PasswordLockoutPolicyReadModel.ReadModel), + MaxAttempts: uint64(readModel.MaxAttempts), + ShowLockOutFailures: readModel.ShowLockOutFailures, + //TODO: State: int32, + } +} + +func readModelToIDPConfigs(rm *IAMIDPConfigsReadModel) []*model.IDPConfig { + configs := make([]*model.IDPConfig, len(rm.Configs)) + for i, config := range rm.Configs { + configs[i] = readModelToIDPConfig(&IAMIDPConfigReadModel{IDPConfigReadModel: *config}) + } + return configs +} + +func readModelToIDPConfig(rm *IAMIDPConfigReadModel) *model.IDPConfig { + return &model.IDPConfig{ + ObjectRoot: readModelToObjectRoot(rm.ReadModel), + OIDCConfig: readModelToIDPOIDCConfig(rm.OIDCConfig), + IDPConfigID: rm.ConfigID, + Name: rm.Name, + State: model.IDPConfigState(rm.State), + StylingType: model.IDPStylingType(rm.StylingType), + } +} + +func readModelToIDPOIDCConfig(rm *OIDCConfigReadModel) *model.OIDCIDPConfig { + return &model.OIDCIDPConfig{ + ObjectRoot: readModelToObjectRoot(rm.ReadModel), + ClientID: rm.ClientID, + ClientSecret: rm.ClientSecret, + ClientSecretString: string(rm.ClientSecret.Crypted), + IDPConfigID: rm.IDPConfigID, + IDPDisplayNameMapping: model.OIDCMappingField(rm.IDPDisplayNameMapping), + Issuer: rm.Issuer, + Scopes: rm.Scopes, + UsernameMapping: model.OIDCMappingField(rm.UserNameMapping), + } +} + +func readModelToObjectRoot(readModel eventstore.ReadModel) models.ObjectRoot { + return models.ObjectRoot{ + AggregateID: readModel.AggregateID, + ChangeDate: readModel.ChangeDate, + CreationDate: readModel.CreationDate, + ResourceOwner: readModel.ResourceOwner, + Sequence: readModel.ProcessedSequence, + } +} diff --git a/internal/v2/query/iam_idp_config_model.go b/internal/v2/query/iam_idp_config_model.go new file mode 100644 index 0000000000..fc8460c8b2 --- /dev/null +++ b/internal/v2/query/iam_idp_config_model.go @@ -0,0 +1,49 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMIDPConfigReadModel struct { + IDPConfigReadModel + + iamID string + configID string +} + +func NewIAMIDPConfigReadModel(iamID, configID string) *IAMIDPConfigReadModel { + return &IAMIDPConfigReadModel{ + iamID: iamID, + configID: configID, + } +} + +func (rm *IAMIDPConfigReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.IDPConfigAddedEvent: + rm.IDPConfigReadModel.AppendEvents(&e.IDPConfigAddedEvent) + case *iam.IDPConfigChangedEvent: + rm.IDPConfigReadModel.AppendEvents(&e.IDPConfigChangedEvent) + case *iam.IDPConfigDeactivatedEvent: + rm.IDPConfigReadModel.AppendEvents(&e.IDPConfigDeactivatedEvent) + case *iam.IDPConfigReactivatedEvent: + rm.IDPConfigReadModel.AppendEvents(&e.IDPConfigReactivatedEvent) + case *iam.IDPConfigRemovedEvent: + rm.IDPConfigReadModel.AppendEvents(&e.IDPConfigRemovedEvent) + case *iam.IDPOIDCConfigAddedEvent: + rm.IDPConfigReadModel.AppendEvents(&e.OIDCConfigAddedEvent) + case *iam.IDPOIDCConfigChangedEvent: + rm.IDPConfigReadModel.AppendEvents(&e.OIDCConfigChangedEvent) + } + } +} + +func (rm *IAMIDPConfigReadModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(rm.iamID). + EventData(map[string]interface{}{ + "idpConfigId": rm.configID, + }) +} diff --git a/internal/v2/query/iam_idp_configs_model.go b/internal/v2/query/iam_idp_configs_model.go new file mode 100644 index 0000000000..c6f99972ff --- /dev/null +++ b/internal/v2/query/iam_idp_configs_model.go @@ -0,0 +1,31 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMIDPConfigsReadModel struct { + IDPConfigsReadModel +} + +func (rm *IAMIDPConfigsReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.IDPConfigAddedEvent: + rm.IDPConfigsReadModel.AppendEvents(&e.IDPConfigAddedEvent) + case *iam.IDPConfigChangedEvent: + rm.IDPConfigsReadModel.AppendEvents(&e.IDPConfigChangedEvent) + case *iam.IDPConfigDeactivatedEvent: + rm.IDPConfigsReadModel.AppendEvents(&e.IDPConfigDeactivatedEvent) + case *iam.IDPConfigReactivatedEvent: + rm.IDPConfigsReadModel.AppendEvents(&e.IDPConfigReactivatedEvent) + case *iam.IDPConfigRemovedEvent: + rm.IDPConfigsReadModel.AppendEvents(&e.IDPConfigRemovedEvent) + case *iam.IDPOIDCConfigAddedEvent: + rm.IDPConfigsReadModel.AppendEvents(&e.OIDCConfigAddedEvent) + case *iam.IDPOIDCConfigChangedEvent: + rm.IDPConfigsReadModel.AppendEvents(&e.OIDCConfigChangedEvent) + } + } +} diff --git a/internal/v2/query/iam_member_model.go b/internal/v2/query/iam_member_model.go new file mode 100644 index 0000000000..898225733c --- /dev/null +++ b/internal/v2/query/iam_member_model.go @@ -0,0 +1,42 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/member" +) + +type IAMMemberReadModel struct { + MemberReadModel + + userID string + iamID string +} + +func NewIAMMemberReadModel(iamID, userID string) *IAMMemberReadModel { + return &IAMMemberReadModel{ + iamID: iamID, + userID: userID, + } +} + +func (rm *IAMMemberReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.MemberAddedEvent: + rm.MemberReadModel.AppendEvents(&e.MemberAddedEvent) + case *iam.MemberChangedEvent: + rm.MemberReadModel.AppendEvents(&e.MemberChangedEvent) + case *member.MemberAddedEvent, *member.MemberChangedEvent, *iam.MemberRemovedEvent: + rm.MemberReadModel.AppendEvents(e) + } + } +} + +func (rm *IAMMemberReadModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType). + AggregateIDs(rm.iamID). + EventData(map[string]interface{}{ + "userId": rm.userID, + }) +} diff --git a/internal/v2/query/iam_members_model.go b/internal/v2/query/iam_members_model.go new file mode 100644 index 0000000000..fd2325aa36 --- /dev/null +++ b/internal/v2/query/iam_members_model.go @@ -0,0 +1,23 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type IAMMembersReadModel struct { + MembersReadModel +} + +func (rm *IAMMembersReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.MemberAddedEvent: + rm.MembersReadModel.AppendEvents(&e.MemberAddedEvent) + case *iam.MemberChangedEvent: + rm.MembersReadModel.AppendEvents(&e.MemberChangedEvent) + case *iam.MemberRemovedEvent: + rm.MembersReadModel.AppendEvents(&e.MemberRemovedEvent) + } + } +} diff --git a/internal/v2/query/iam_model.go b/internal/v2/query/iam_model.go new file mode 100644 index 0000000000..a8c02f9048 --- /dev/null +++ b/internal/v2/query/iam_model.go @@ -0,0 +1,144 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/member" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type ReadModel struct { + eventstore.ReadModel + + SetUpStarted domain.Step + SetUpDone domain.Step + + Members IAMMembersReadModel + IDPs IAMIDPConfigsReadModel + + GlobalOrgID string + ProjectID string + + DefaultLoginPolicy IAMLoginPolicyReadModel + DefaultLabelPolicy IAMLabelPolicyReadModel + DefaultOrgIAMPolicy IAMOrgIAMPolicyReadModel + DefaultPasswordComplexityPolicy IAMPasswordComplexityPolicyReadModel + DefaultPasswordAgePolicy IAMPasswordAgePolicyReadModel + DefaultPasswordLockoutPolicy IAMPasswordLockoutPolicyReadModel +} + +func NewReadModel(id string) *ReadModel { + return &ReadModel{ + ReadModel: eventstore.ReadModel{ + AggregateID: id, + }, + } +} + +func (rm *ReadModel) IDPByID(idpID string) *IAMIDPConfigReadModel { + _, config := rm.IDPs.ConfigByID(idpID) + if config == nil { + return nil + } + return &IAMIDPConfigReadModel{IDPConfigReadModel: *config} +} + +func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { + rm.ReadModel.AppendEvents(events...) + for _, event := range events { + switch event.(type) { + case *member.MemberAddedEvent, + *member.MemberChangedEvent, + *member.MemberRemovedEvent: + + rm.Members.AppendEvents(event) + case *iam.IDPConfigAddedEvent, + *iam.IDPConfigChangedEvent, + *iam.IDPConfigDeactivatedEvent, + *iam.IDPConfigReactivatedEvent, + *iam.IDPConfigRemovedEvent, + *iam.IDPOIDCConfigAddedEvent, + *iam.IDPOIDCConfigChangedEvent: + + rm.IDPs.AppendEvents(event) + case *policy.LabelPolicyAddedEvent, + *policy.LabelPolicyChangedEvent: + + rm.DefaultLabelPolicy.AppendEvents(event) + case *policy.LoginPolicyAddedEvent, + *policy.LoginPolicyChangedEvent: + + rm.DefaultLoginPolicy.AppendEvents(event) + case *policy.OrgIAMPolicyAddedEvent: + rm.DefaultOrgIAMPolicy.AppendEvents(event) + case *policy.PasswordComplexityPolicyAddedEvent, + *policy.PasswordComplexityPolicyChangedEvent: + + rm.DefaultPasswordComplexityPolicy.AppendEvents(event) + case *policy.PasswordAgePolicyAddedEvent, + *policy.PasswordAgePolicyChangedEvent: + + rm.DefaultPasswordAgePolicy.AppendEvents(event) + case *policy.PasswordLockoutPolicyAddedEvent, + *policy.PasswordLockoutPolicyChangedEvent: + + rm.DefaultPasswordLockoutPolicy.AppendEvents(event) + } + } +} + +func (rm *ReadModel) Reduce() (err error) { + for _, event := range rm.Events { + switch e := event.(type) { + case *iam.ProjectSetEvent: + rm.ProjectID = e.ProjectID + case *iam.GlobalOrgSetEvent: + rm.GlobalOrgID = e.OrgID + case *iam.SetupStepEvent: + if e.Done { + rm.SetUpDone = e.Step + } else { + rm.SetUpStarted = e.Step + } + } + } + for _, reduce := range []func() error{ + rm.Members.Reduce, + rm.IDPs.Reduce, + rm.DefaultLoginPolicy.Reduce, + rm.DefaultLabelPolicy.Reduce, + rm.DefaultOrgIAMPolicy.Reduce, + rm.DefaultPasswordComplexityPolicy.Reduce, + rm.DefaultPasswordAgePolicy.Reduce, + rm.DefaultPasswordLockoutPolicy.Reduce, + rm.ReadModel.Reduce, + } { + if err = reduce(); err != nil { + return err + } + } + + return nil +} + +func (rm *ReadModel) AppendAndReduce(events ...eventstore.EventReader) error { + rm.AppendEvents(events...) + return rm.Reduce() +} + +func (rm *ReadModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).AggregateIDs(rm.AggregateID) +} + +func IAMAggregateFromReadModel(rm *ReadModel) *iam.Aggregate { + return &iam.Aggregate{ + Aggregate: *eventstore.NewAggregate( + rm.AggregateID, + iam.AggregateType, + rm.ResourceOwner, + iam.AggregateVersion, + rm.ProcessedSequence, + ), + } +} diff --git a/internal/v2/query/iam_policy_label_model.go b/internal/v2/query/iam_policy_label_model.go new file mode 100644 index 0000000000..fb91f3d9cc --- /dev/null +++ b/internal/v2/query/iam_policy_label_model.go @@ -0,0 +1,22 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IAMLabelPolicyReadModel struct{ LabelPolicyReadModel } + +func (rm *IAMLabelPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.LabelPolicyAddedEvent: + rm.LabelPolicyReadModel.AppendEvents(&e.LabelPolicyAddedEvent) + case *iam.LabelPolicyChangedEvent: + rm.LabelPolicyReadModel.AppendEvents(&e.LabelPolicyChangedEvent) + case *policy.LabelPolicyAddedEvent, *policy.LabelPolicyChangedEvent: + rm.LabelPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/iam_policy_login_model.go b/internal/v2/query/iam_policy_login_model.go new file mode 100644 index 0000000000..eabb539747 --- /dev/null +++ b/internal/v2/query/iam_policy_login_model.go @@ -0,0 +1,22 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IAMLoginPolicyReadModel struct{ LoginPolicyReadModel } + +func (rm *IAMLoginPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.LoginPolicyAddedEvent: + rm.LoginPolicyReadModel.AppendEvents(&e.LoginPolicyAddedEvent) + case *iam.LoginPolicyChangedEvent: + rm.LoginPolicyReadModel.AppendEvents(&e.LoginPolicyChangedEvent) + case *policy.LoginPolicyAddedEvent, *policy.LoginPolicyChangedEvent: + rm.LoginPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/iam_policy_org_iam_model.go b/internal/v2/query/iam_policy_org_iam_model.go new file mode 100644 index 0000000000..b8592baf31 --- /dev/null +++ b/internal/v2/query/iam_policy_org_iam_model.go @@ -0,0 +1,20 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IAMOrgIAMPolicyReadModel struct{ OrgIAMPolicyReadModel } + +func (rm *IAMOrgIAMPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.OrgIAMPolicyAddedEvent: + rm.OrgIAMPolicyReadModel.AppendEvents(&e.OrgIAMPolicyAddedEvent) + case *policy.OrgIAMPolicyAddedEvent: + rm.OrgIAMPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/iam_policy_password_age_model.go b/internal/v2/query/iam_policy_password_age_model.go new file mode 100644 index 0000000000..d557a1eb77 --- /dev/null +++ b/internal/v2/query/iam_policy_password_age_model.go @@ -0,0 +1,26 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IAMPasswordAgePolicyReadModel struct { + PasswordAgePolicyReadModel +} + +func (rm *IAMPasswordAgePolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.PasswordAgePolicyAddedEvent: + rm.PasswordAgePolicyReadModel.AppendEvents(&e.PasswordAgePolicyAddedEvent) + case *iam.PasswordAgePolicyChangedEvent: + rm.PasswordAgePolicyReadModel.AppendEvents(&e.PasswordAgePolicyChangedEvent) + case *policy.PasswordAgePolicyAddedEvent, + *policy.PasswordAgePolicyChangedEvent: + + rm.PasswordAgePolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/iam_policy_password_complexity_model.go b/internal/v2/query/iam_policy_password_complexity_model.go new file mode 100644 index 0000000000..48d9a3326c --- /dev/null +++ b/internal/v2/query/iam_policy_password_complexity_model.go @@ -0,0 +1,26 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IAMPasswordComplexityPolicyReadModel struct { + PasswordComplexityPolicyReadModel +} + +func (rm *IAMPasswordComplexityPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.PasswordComplexityPolicyAddedEvent: + rm.PasswordComplexityPolicyReadModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent) + case *iam.PasswordComplexityPolicyChangedEvent: + rm.PasswordComplexityPolicyReadModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent) + case *policy.PasswordComplexityPolicyAddedEvent, + *policy.PasswordComplexityPolicyChangedEvent: + + rm.PasswordComplexityPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/iam_policy_password_lockout_model.go b/internal/v2/query/iam_policy_password_lockout_model.go new file mode 100644 index 0000000000..b3f4349b56 --- /dev/null +++ b/internal/v2/query/iam_policy_password_lockout_model.go @@ -0,0 +1,24 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type IAMPasswordLockoutPolicyReadModel struct { + PasswordLockoutPolicyReadModel +} + +func (rm *IAMPasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *iam.PasswordLockoutPolicyAddedEvent: + rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent) + case *iam.PasswordLockoutPolicyChangedEvent: + rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent) + case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent: + rm.PasswordLockoutPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/idp_config.go b/internal/v2/query/idp_config.go new file mode 100644 index 0000000000..baff84ab32 --- /dev/null +++ b/internal/v2/query/idp_config.go @@ -0,0 +1,16 @@ +package query + +import ( + "context" + "github.com/caos/zitadel/internal/iam/model" +) + +func (r *QuerySide) DefaultIDPConfigByID(ctx context.Context, iamID, idpConfigID string) (*model.IDPConfigView, error) { + idpConfig := NewIAMIDPConfigReadModel(iamID, idpConfigID) + err := r.eventstore.FilterToQueryReducer(ctx, idpConfig) + if err != nil { + return nil, err + } + + return readModelToIDPConfigView(idpConfig), nil +} diff --git a/internal/v2/query/idp_config_model.go b/internal/v2/query/idp_config_model.go new file mode 100644 index 0000000000..f3b6cb25d4 --- /dev/null +++ b/internal/v2/query/idp_config_model.go @@ -0,0 +1,93 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/idpconfig" +) + +type IDPConfigReadModel struct { + eventstore.ReadModel + + State domain.IDPConfigState + ConfigID string + Name string + StylingType domain.IDPConfigStylingType + ProviderType domain.IdentityProviderType + + OIDCConfig *OIDCConfigReadModel +} + +func NewIDPConfigReadModel(configID string) *IDPConfigReadModel { + return &IDPConfigReadModel{ + ConfigID: configID, + } +} + +func (rm *IDPConfigReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *idpconfig.IDPConfigAddedEvent: + rm.ReadModel.AppendEvents(e) + case *idpconfig.IDPConfigChangedEvent: + rm.ReadModel.AppendEvents(e) + case *idpconfig.IDPConfigDeactivatedEvent: + rm.ReadModel.AppendEvents(e) + case *idpconfig.IDPConfigReactivatedEvent: + rm.ReadModel.AppendEvents(e) + case *idpconfig.IDPConfigRemovedEvent: + rm.ReadModel.AppendEvents(e) + case *idpconfig.OIDCConfigAddedEvent: + rm.OIDCConfig = &OIDCConfigReadModel{} + rm.ReadModel.AppendEvents(e) + rm.OIDCConfig.AppendEvents(event) + case *idpconfig.OIDCConfigChangedEvent: + rm.ReadModel.AppendEvents(e) + rm.OIDCConfig.AppendEvents(event) + } + } +} + +func (rm *IDPConfigReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *idpconfig.IDPConfigAddedEvent: + rm.reduceConfigAddedEvent(e) + case *idpconfig.IDPConfigChangedEvent: + rm.reduceConfigChangedEvent(e) + case *idpconfig.IDPConfigDeactivatedEvent: + rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateInactive) + case *idpconfig.IDPConfigReactivatedEvent: + rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateActive) + case *idpconfig.IDPConfigRemovedEvent: + rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateRemoved) + } + } + + if rm.OIDCConfig != nil { + if err := rm.OIDCConfig.Reduce(); err != nil { + return err + } + } + return rm.ReadModel.Reduce() +} + +func (rm *IDPConfigReadModel) reduceConfigAddedEvent(e *idpconfig.IDPConfigAddedEvent) { + rm.ConfigID = e.ConfigID + rm.Name = e.Name + rm.StylingType = e.StylingType + rm.State = domain.IDPConfigStateActive +} + +func (rm *IDPConfigReadModel) reduceConfigChangedEvent(e *idpconfig.IDPConfigChangedEvent) { + if e.Name != "" { + rm.Name = e.Name + } + if e.StylingType.Valid() { + rm.StylingType = e.StylingType + } +} + +func (rm *IDPConfigReadModel) reduceConfigStateChanged(configID string, state domain.IDPConfigState) { + rm.State = state +} diff --git a/internal/v2/repository/idp/configs_read_model.go b/internal/v2/query/idp_configs_model.go similarity index 59% rename from internal/v2/repository/idp/configs_read_model.go rename to internal/v2/query/idp_configs_model.go index b71027dab0..2b288a5614 100644 --- a/internal/v2/repository/idp/configs_read_model.go +++ b/internal/v2/query/idp_configs_model.go @@ -1,17 +1,17 @@ -package idp +package query import ( "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/idp/oidc" + "github.com/caos/zitadel/internal/v2/repository/idpconfig" ) -type ConfigsReadModel struct { +type IDPConfigsReadModel struct { eventstore.ReadModel - Configs []*ConfigReadModel + Configs []*IDPConfigReadModel } -func (rm *ConfigsReadModel) ConfigByID(id string) (idx int, config *ConfigReadModel) { +func (rm *IDPConfigsReadModel) ConfigByID(id string) (idx int, config *IDPConfigReadModel) { for idx, config = range rm.Configs { if config.ConfigID == id { return idx, config @@ -20,29 +20,29 @@ func (rm *ConfigsReadModel) ConfigByID(id string) (idx int, config *ConfigReadMo return -1, nil } -func (rm *ConfigsReadModel) AppendEvents(events ...eventstore.EventReader) { +func (rm *IDPConfigsReadModel) AppendEvents(events ...eventstore.EventReader) { for _, event := range events { switch e := event.(type) { - case *ConfigAddedEvent: - config := NewConfigReadModel(e.ConfigID) + case *idpconfig.IDPConfigAddedEvent: + config := NewIDPConfigReadModel(e.ConfigID) rm.Configs = append(rm.Configs, config) config.AppendEvents(event) - case *ConfigChangedEvent: + case *idpconfig.IDPConfigChangedEvent: _, config := rm.ConfigByID(e.ConfigID) config.AppendEvents(e) - case *ConfigDeactivatedEvent: + case *idpconfig.IDPConfigDeactivatedEvent: _, config := rm.ConfigByID(e.ConfigID) config.AppendEvents(e) - case *ConfigReactivatedEvent: + case *idpconfig.IDPConfigReactivatedEvent: _, config := rm.ConfigByID(e.ConfigID) config.AppendEvents(e) - case *oidc.ConfigAddedEvent: + case *idpconfig.OIDCConfigAddedEvent: _, config := rm.ConfigByID(e.IDPConfigID) config.AppendEvents(e) - case *oidc.ConfigChangedEvent: + case *idpconfig.OIDCConfigChangedEvent: _, config := rm.ConfigByID(e.IDPConfigID) config.AppendEvents(e) - case *ConfigRemovedEvent: + case *idpconfig.IDPConfigRemovedEvent: idx, _ := rm.ConfigByID(e.ConfigID) if idx < 0 { continue @@ -54,7 +54,7 @@ func (rm *ConfigsReadModel) AppendEvents(events ...eventstore.EventReader) { } } -func (rm *ConfigsReadModel) Reduce() error { +func (rm *IDPConfigsReadModel) Reduce() error { for _, config := range rm.Configs { if err := config.Reduce(); err != nil { return err diff --git a/internal/v2/query/member.go b/internal/v2/query/member.go new file mode 100644 index 0000000000..7098ccdec0 --- /dev/null +++ b/internal/v2/query/member.go @@ -0,0 +1,19 @@ +package query + +import ( + "context" + "github.com/caos/zitadel/internal/telemetry/tracing" +) + +func (r *QuerySide) IAMMemberByID(ctx context.Context, iamID, userID string) (member *IAMMemberReadModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + member = NewIAMMemberReadModel(iamID, userID) + err = r.eventstore.FilterToQueryReducer(ctx, member) + if err != nil { + return nil, err + } + + return member, nil +} diff --git a/internal/v2/query/member_model.go b/internal/v2/query/member_model.go new file mode 100644 index 0000000000..c9a2fb3b2a --- /dev/null +++ b/internal/v2/query/member_model.go @@ -0,0 +1,35 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/member" +) + +//MemberReadModel represenets the default member view. +// It's computed from events. +type MemberReadModel struct { + eventstore.ReadModel + + UserID string + Roles []string +} + +//NewMemberReadModel is the default constructor of MemberReadModel +func NewMemberReadModel(userID string) *MemberReadModel { + return &MemberReadModel{ + UserID: userID, + } +} + +//Reduce extends eventstore.MemberReadModel +func (rm *MemberReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *member.MemberAddedEvent: + rm.Roles = e.Roles + case *member.MemberChangedEvent: + rm.Roles = e.Roles + } + } + return rm.ReadModel.Reduce() +} diff --git a/internal/v2/repository/members/read_models.go b/internal/v2/query/members_model.go similarity index 64% rename from internal/v2/repository/members/read_models.go rename to internal/v2/query/members_model.go index 7d9273551b..e88368e522 100644 --- a/internal/v2/repository/members/read_models.go +++ b/internal/v2/query/members_model.go @@ -1,17 +1,17 @@ -package members +package query import ( "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/repository/member" ) -type ReadModel struct { +type MembersReadModel struct { eventstore.ReadModel - Members []*member.ReadModel + Members []*MemberReadModel } -func (rm *ReadModel) MemberByUserID(id string) (idx int, member *member.ReadModel) { +func (rm *MembersReadModel) MemberByUserID(id string) (idx int, member *MemberReadModel) { for idx, member = range rm.Members { if member.UserID == id { return idx, member @@ -20,17 +20,17 @@ func (rm *ReadModel) MemberByUserID(id string) (idx int, member *member.ReadMode return -1, nil } -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { +func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) { for _, event := range events { switch e := event.(type) { - case *member.AddedEvent: - m := member.NewReadModel(e.UserID) + case *member.MemberAddedEvent: + m := NewMemberReadModel(e.UserID) rm.Members = append(rm.Members, m) m.AppendEvents(e) - case *member.ChangedEvent: + case *member.MemberChangedEvent: _, m := rm.MemberByUserID(e.UserID) m.AppendEvents(e) - case *member.RemovedEvent: + case *member.MemberRemovedEvent: idx, _ := rm.MemberByUserID(e.UserID) if idx < 0 { continue @@ -42,7 +42,7 @@ func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { } } -func (rm *ReadModel) Reduce() (err error) { +func (rm *MembersReadModel) Reduce() (err error) { for _, m := range rm.Members { err = m.Reduce() if err != nil { diff --git a/internal/v2/repository/idp/oidc/config_read_model.go b/internal/v2/query/oidc_config_model.go similarity index 64% rename from internal/v2/repository/idp/oidc/config_read_model.go rename to internal/v2/query/oidc_config_model.go index 024cef0aa7..2038e1a93a 100644 --- a/internal/v2/repository/idp/oidc/config_read_model.go +++ b/internal/v2/query/oidc_config_model.go @@ -1,11 +1,13 @@ -package oidc +package query import ( "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/idpconfig" ) -type ConfigReadModel struct { +type OIDCConfigReadModel struct { eventstore.ReadModel IDPConfigID string @@ -13,16 +15,16 @@ type ConfigReadModel struct { ClientSecret *crypto.CryptoValue Issuer string Scopes []string - IDPDisplayNameMapping MappingField - UserNameMapping MappingField + IDPDisplayNameMapping domain.OIDCMappingField + UserNameMapping domain.OIDCMappingField } -func (rm *ConfigReadModel) Reduce() error { +func (rm *OIDCConfigReadModel) Reduce() error { for _, event := range rm.Events { switch e := event.(type) { - case *ConfigAddedEvent: + case *idpconfig.OIDCConfigAddedEvent: rm.reduceConfigAddedEvent(e) - case *ConfigChangedEvent: + case *idpconfig.OIDCConfigChangedEvent: rm.reduceConfigChangedEvent(e) } } @@ -30,7 +32,7 @@ func (rm *ConfigReadModel) Reduce() error { return rm.ReadModel.Reduce() } -func (rm *ConfigReadModel) reduceConfigAddedEvent(e *ConfigAddedEvent) { +func (rm *OIDCConfigReadModel) reduceConfigAddedEvent(e *idpconfig.OIDCConfigAddedEvent) { rm.IDPConfigID = e.IDPConfigID rm.ClientID = e.ClientID rm.ClientSecret = e.ClientSecret @@ -40,7 +42,7 @@ func (rm *ConfigReadModel) reduceConfigAddedEvent(e *ConfigAddedEvent) { rm.UserNameMapping = e.UserNameMapping } -func (rm *ConfigReadModel) reduceConfigChangedEvent(e *ConfigChangedEvent) { +func (rm *OIDCConfigReadModel) reduceConfigChangedEvent(e *idpconfig.OIDCConfigChangedEvent) { if e.ClientID != "" { rm.ClientID = e.ClientID } diff --git a/internal/v2/query/org_member_model.go b/internal/v2/query/org_member_model.go new file mode 100644 index 0000000000..ea28e81908 --- /dev/null +++ b/internal/v2/query/org_member_model.go @@ -0,0 +1,36 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" +) + +type OrgMembersReadModel struct { + MembersReadModel +} + +func (rm *OrgMembersReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.MemberAddedEvent: + rm.MembersReadModel.AppendEvents(&e.MemberAddedEvent) + case *org.MemberChangedEvent: + rm.MembersReadModel.AppendEvents(&e.MemberChangedEvent) + case *org.MemberRemovedEvent: + rm.MembersReadModel.AppendEvents(&e.MemberRemovedEvent) + } + } +} + +type OrgMemberReadModel MemberReadModel + +func (rm *OrgMemberReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.MemberAddedEvent: + rm.ReadModel.AppendEvents(&e.MemberAddedEvent) + case *org.MemberChangedEvent: + rm.ReadModel.AppendEvents(&e.MemberChangedEvent) + } + } +} diff --git a/internal/v2/query/org_policy_label_model.go b/internal/v2/query/org_policy_label_model.go new file mode 100644 index 0000000000..ae7d466e18 --- /dev/null +++ b/internal/v2/query/org_policy_label_model.go @@ -0,0 +1,22 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgLabelPolicyReadModel struct{ LabelPolicyReadModel } + +func (rm *OrgLabelPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.LabelPolicyAddedEvent: + rm.LabelPolicyReadModel.AppendEvents(&e.LabelPolicyAddedEvent) + case *org.LabelPolicyChangedEvent: + rm.LabelPolicyReadModel.AppendEvents(&e.LabelPolicyChangedEvent) + case *policy.LabelPolicyAddedEvent, *policy.LabelPolicyChangedEvent: + rm.LabelPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/org_policy_login_model.go b/internal/v2/query/org_policy_login_model.go new file mode 100644 index 0000000000..6f27dc995b --- /dev/null +++ b/internal/v2/query/org_policy_login_model.go @@ -0,0 +1,22 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgLoginPolicyReadModel struct{ LoginPolicyReadModel } + +func (rm *OrgLoginPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.LoginPolicyAddedEvent: + rm.LoginPolicyReadModel.AppendEvents(&e.LoginPolicyAddedEvent) + case *org.LoginPolicyChangedEvent: + rm.LoginPolicyReadModel.AppendEvents(&e.LoginPolicyChangedEvent) + case *policy.LoginPolicyAddedEvent, *policy.LoginPolicyChangedEvent: + rm.LoginPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/org_policy_org_iam_model.go b/internal/v2/query/org_policy_org_iam_model.go new file mode 100644 index 0000000000..a8bb3bffac --- /dev/null +++ b/internal/v2/query/org_policy_org_iam_model.go @@ -0,0 +1,20 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgOrgIAMPolicyReadModel struct{ OrgIAMPolicyReadModel } + +func (rm *OrgOrgIAMPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.OrgIAMPolicyAddedEvent: + rm.OrgIAMPolicyReadModel.AppendEvents(&e.OrgIAMPolicyAddedEvent) + case *policy.OrgIAMPolicyAddedEvent: + rm.OrgIAMPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/org_policy_password_age_model.go b/internal/v2/query/org_policy_password_age_model.go new file mode 100644 index 0000000000..1715cbbaa4 --- /dev/null +++ b/internal/v2/query/org_policy_password_age_model.go @@ -0,0 +1,24 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgPasswordAgePolicyReadModel struct { + PasswordAgePolicyReadModel +} + +func (rm *OrgPasswordAgePolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.PasswordAgePolicyAddedEvent: + rm.PasswordAgePolicyReadModel.AppendEvents(&e.PasswordAgePolicyAddedEvent) + case *org.PasswordAgePolicyChangedEvent: + rm.PasswordAgePolicyReadModel.AppendEvents(&e.PasswordAgePolicyChangedEvent) + case *policy.PasswordAgePolicyAddedEvent, *policy.PasswordAgePolicyChangedEvent: + rm.PasswordAgePolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/org_policy_password_complexity_model.go b/internal/v2/query/org_policy_password_complexity_model.go new file mode 100644 index 0000000000..60898931c7 --- /dev/null +++ b/internal/v2/query/org_policy_password_complexity_model.go @@ -0,0 +1,24 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgPasswordComplexityPolicyReadModel struct { + PasswordComplexityPolicyReadModel +} + +func (rm *OrgPasswordComplexityPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.PasswordComplexityPolicyAddedEvent: + rm.PasswordComplexityPolicyReadModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent) + case *org.PasswordComplexityPolicyChangedEvent: + rm.PasswordComplexityPolicyReadModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent) + case *policy.PasswordComplexityPolicyAddedEvent, *policy.PasswordComplexityPolicyChangedEvent: + rm.PasswordComplexityPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/org_policy_password_lockout_model.go b/internal/v2/query/org_policy_password_lockout_model.go new file mode 100644 index 0000000000..8e77aaa6d3 --- /dev/null +++ b/internal/v2/query/org_policy_password_lockout_model.go @@ -0,0 +1,24 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/org" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgPasswordLockoutPolicyReadModel struct { + PasswordLockoutPolicyReadModel +} + +func (rm *OrgPasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { + for _, event := range events { + switch e := event.(type) { + case *org.PasswordLockoutPolicyAddedEvent: + rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent) + case *org.PasswordLockoutPolicyChangedEvent: + rm.PasswordLockoutPolicyReadModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent) + case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent: + rm.PasswordLockoutPolicyReadModel.AppendEvents(e) + } + } +} diff --git a/internal/v2/query/policy_label_model.go b/internal/v2/query/policy_label_model.go new file mode 100644 index 0000000000..8dd2579fe9 --- /dev/null +++ b/internal/v2/query/policy_label_model.go @@ -0,0 +1,31 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type LabelPolicyReadModel struct { + eventstore.ReadModel + + PrimaryColor string + SecondaryColor string + IsActive bool +} + +func (rm *LabelPolicyReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *policy.LabelPolicyAddedEvent: + rm.PrimaryColor = e.PrimaryColor + rm.SecondaryColor = e.SecondaryColor + rm.IsActive = true + case *policy.LabelPolicyChangedEvent: + rm.PrimaryColor = e.PrimaryColor + rm.SecondaryColor = e.SecondaryColor + case *policy.LabelPolicyRemovedEvent: + rm.IsActive = false + } + } + return rm.ReadModel.Reduce() +} diff --git a/internal/v2/repository/policy/login/read_model.go b/internal/v2/query/policy_login_model.go similarity index 62% rename from internal/v2/repository/policy/login/read_model.go rename to internal/v2/query/policy_login_model.go index b4ba6d4014..89953c1a31 100644 --- a/internal/v2/repository/policy/login/read_model.go +++ b/internal/v2/query/policy_login_model.go @@ -1,34 +1,40 @@ -package login +package query import ( "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" ) -type ReadModel struct { +type LoginPolicyReadModel struct { eventstore.ReadModel AllowUserNamePassword bool AllowRegister bool AllowExternalIDP bool ForceMFA bool - PasswordlessType PasswordlessType + PasswordlessType domain.PasswordlessType + IsActive bool } -func (rm *ReadModel) Reduce() error { +func (rm *LoginPolicyReadModel) Reduce() error { for _, event := range rm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.LoginPolicyAddedEvent: rm.AllowUserNamePassword = e.AllowUserNamePassword rm.AllowExternalIDP = e.AllowExternalIDP rm.AllowRegister = e.AllowRegister rm.ForceMFA = e.ForceMFA rm.PasswordlessType = e.PasswordlessType - case *ChangedEvent: + rm.IsActive = true + case *policy.LoginPolicyChangedEvent: rm.AllowUserNamePassword = e.AllowUserNamePassword rm.AllowExternalIDP = e.AllowExternalIDP rm.AllowRegister = e.AllowRegister rm.ForceMFA = e.ForceMFA rm.PasswordlessType = e.PasswordlessType + case *policy.LoginPolicyRemovedEvent: + rm.IsActive = false } } return rm.ReadModel.Reduce() diff --git a/internal/v2/query/policy_org_iam_model.go b/internal/v2/query/policy_org_iam_model.go new file mode 100644 index 0000000000..c588dc809b --- /dev/null +++ b/internal/v2/query/policy_org_iam_model.go @@ -0,0 +1,24 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +type OrgIAMPolicyReadModel struct { + eventstore.ReadModel + + UserLoginMustBeDomain bool +} + +func (rm *OrgIAMPolicyReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *policy.OrgIAMPolicyAddedEvent: + rm.UserLoginMustBeDomain = e.UserLoginMustBeDomain + case *policy.OrgIAMPolicyChangedEvent: + rm.UserLoginMustBeDomain = e.UserLoginMustBeDomain + } + } + return rm.ReadModel.Reduce() +} diff --git a/internal/v2/repository/policy/password_age/read_model.go b/internal/v2/query/policy_password_age_model.go similarity index 50% rename from internal/v2/repository/policy/password_age/read_model.go rename to internal/v2/query/policy_password_age_model.go index 4f834fc636..f9820a5299 100644 --- a/internal/v2/repository/policy/password_age/read_model.go +++ b/internal/v2/query/policy_password_age_model.go @@ -1,21 +1,24 @@ -package password_age +package query -import "github.com/caos/zitadel/internal/eventstore/v2" +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) -type ReadModel struct { +type PasswordAgePolicyReadModel struct { eventstore.ReadModel ExpireWarnDays uint64 MaxAgeDays uint64 } -func (rm *ReadModel) Reduce() error { +func (rm *PasswordAgePolicyReadModel) Reduce() error { for _, event := range rm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.PasswordAgePolicyAddedEvent: rm.ExpireWarnDays = e.ExpireWarnDays rm.MaxAgeDays = e.MaxAgeDays - case *ChangedEvent: + case *policy.PasswordAgePolicyChangedEvent: rm.ExpireWarnDays = e.ExpireWarnDays rm.MaxAgeDays = e.MaxAgeDays } diff --git a/internal/v2/repository/policy/password_complexity/read_model.go b/internal/v2/query/policy_password_complexity_model.go similarity index 61% rename from internal/v2/repository/policy/password_complexity/read_model.go rename to internal/v2/query/policy_password_complexity_model.go index 51c3825e3f..748d450ab8 100644 --- a/internal/v2/repository/policy/password_complexity/read_model.go +++ b/internal/v2/query/policy_password_complexity_model.go @@ -1,8 +1,11 @@ -package password_complexity +package query -import "github.com/caos/zitadel/internal/eventstore/v2" +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) -type ReadModel struct { +type PasswordComplexityPolicyReadModel struct { eventstore.ReadModel MinLength uint64 @@ -12,16 +15,16 @@ type ReadModel struct { HasSymbol bool } -func (rm *ReadModel) Reduce() error { +func (rm *PasswordComplexityPolicyReadModel) Reduce() error { for _, event := range rm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.PasswordComplexityPolicyAddedEvent: rm.MinLength = e.MinLength rm.HasLowercase = e.HasLowercase rm.HasUpperCase = e.HasUpperCase rm.HasNumber = e.HasNumber rm.HasSymbol = e.HasSymbol - case *ChangedEvent: + case *policy.PasswordComplexityPolicyChangedEvent: rm.MinLength = e.MinLength rm.HasLowercase = e.HasLowercase rm.HasUpperCase = e.HasUpperCase diff --git a/internal/v2/repository/policy/password_lockout/read_model.go b/internal/v2/query/policy_password_lockout_model.go similarity index 51% rename from internal/v2/repository/policy/password_lockout/read_model.go rename to internal/v2/query/policy_password_lockout_model.go index 1b5149987b..30a0dc899f 100644 --- a/internal/v2/repository/policy/password_lockout/read_model.go +++ b/internal/v2/query/policy_password_lockout_model.go @@ -1,21 +1,24 @@ -package password_lockout +package query -import "github.com/caos/zitadel/internal/eventstore/v2" +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) -type ReadModel struct { +type PasswordLockoutPolicyReadModel struct { eventstore.ReadModel MaxAttempts uint64 ShowLockOutFailures bool } -func (rm *ReadModel) Reduce() error { +func (rm *PasswordLockoutPolicyReadModel) Reduce() error { for _, event := range rm.Events { switch e := event.(type) { - case *AddedEvent: + case *policy.PasswordLockoutPolicyAddedEvent: rm.MaxAttempts = e.MaxAttempts rm.ShowLockOutFailures = e.ShowLockOutFailures - case *ChangedEvent: + case *policy.PasswordLockoutPolicyChangedEvent: rm.MaxAttempts = e.MaxAttempts rm.ShowLockOutFailures = e.ShowLockOutFailures } diff --git a/internal/v2/business/iam/repository.go b/internal/v2/query/query.go similarity index 76% rename from internal/v2/business/iam/repository.go rename to internal/v2/query/query.go index b757e3cc8d..d650300761 100644 --- a/internal/v2/business/iam/repository.go +++ b/internal/v2/query/query.go @@ -1,4 +1,4 @@ -package iam +package query import ( "context" @@ -12,7 +12,7 @@ import ( iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) -type Repository struct { +type QuerySide struct { eventstore *eventstore.Eventstore idGenerator id.Generator secretCrypto crypto.Crypto @@ -23,8 +23,8 @@ type Config struct { SystemDefaults sd.SystemDefaults } -func StartRepository(config *Config) (repo *Repository, err error) { - repo = &Repository{ +func StartQuerySide(config *Config) (repo *QuerySide, err error) { + repo = &QuerySide{ eventstore: config.Eventstore, idGenerator: id.SonyFlakeGenerator, } @@ -37,7 +37,7 @@ func StartRepository(config *Config) (repo *Repository, err error) { return repo, nil } -func (r *Repository) IAMByID(ctx context.Context, id string) (_ *iam_model.IAM, err error) { +func (r *QuerySide) IAMByID(ctx context.Context, id string) (_ *iam_model.IAM, err error) { readModel, err := r.iamByID(ctx, id) if err != nil { return nil, err @@ -46,11 +46,11 @@ func (r *Repository) IAMByID(ctx context.Context, id string) (_ *iam_model.IAM, return readModelToIAM(readModel), nil } -func (r *Repository) iamByID(ctx context.Context, id string) (_ *iam_repo.ReadModel, err error) { +func (r *QuerySide) iamByID(ctx context.Context, id string) (_ *ReadModel, err error) { ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - readModel := iam_repo.NewReadModel(id) + readModel := NewReadModel(id) err = r.eventstore.FilterToQueryReducer(ctx, readModel) if err != nil { return nil, err diff --git a/internal/v2/query/user_model.go b/internal/v2/query/user_model.go new file mode 100644 index 0000000000..08aa4c551c --- /dev/null +++ b/internal/v2/query/user_model.go @@ -0,0 +1,65 @@ +package query + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/user" +) + +type UserReadModel struct { + eventstore.ReadModel +} + +func NewUserReadModel(id string) *UserReadModel { + return &UserReadModel{ + ReadModel: eventstore.ReadModel{ + AggregateID: id, + }, + } +} + +func (rm *UserReadModel) AppendEvents(events ...eventstore.EventReader) { + rm.ReadModel.AppendEvents(events...) + for _, event := range events { + switch event.(type) { + // TODO: implement append events + } + } +} + +func (rm *UserReadModel) Reduce() (err error) { + for _, event := range rm.Events { + switch event.(type) { + //TODO: implement reduce + } + } + for _, reduce := range []func() error{ + rm.ReadModel.Reduce, + } { + if err = reduce(); err != nil { + return err + } + } + + return nil +} + +func (rm *UserReadModel) AppendAndReduce(events ...eventstore.EventReader) error { + rm.AppendEvents(events...) + return rm.Reduce() +} + +func (rm *UserReadModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).AggregateIDs(rm.AggregateID) +} + +func UserAggregateFromReadModel(rm *UserReadModel) *user.Aggregate { + return &user.Aggregate{ + Aggregate: *eventstore.NewAggregate( + rm.AggregateID, + user.AggregateType, + rm.ResourceOwner, + user.AggregateVersion, + rm.ProcessedSequence, + ), + } +} diff --git a/internal/v2/repository/iam/aggregate.go b/internal/v2/repository/iam/aggregate.go index aaf1c2cc67..d0f963d74b 100644 --- a/internal/v2/repository/iam/aggregate.go +++ b/internal/v2/repository/iam/aggregate.go @@ -2,26 +2,12 @@ package iam import ( "context" - "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/label" - iam_login "github.com/caos/zitadel/internal/v2/repository/iam/policy/login" - factors2 "github.com/caos/zitadel/internal/v2/repository/iam/policy/login/factors" - iam_factors "github.com/caos/zitadel/internal/v2/repository/iam/policy/login/factors" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/login/idpprovider" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/org_iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_age" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_complexity" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_lockout" - "github.com/caos/zitadel/internal/v2/repository/idp" - "github.com/caos/zitadel/internal/v2/repository/idp/oidc" - "github.com/caos/zitadel/internal/v2/repository/policy/login" - "github.com/caos/zitadel/internal/v2/repository/policy/login/factors" - idpprovider2 "github.com/caos/zitadel/internal/v2/repository/policy/login/idpprovider" + "github.com/caos/zitadel/internal/v2/domain" ) const ( - IamEventTypePrefix = eventstore.EventType("iam.") + iamEventTypePrefix = eventstore.EventType("iam.") ) const ( @@ -50,252 +36,12 @@ func NewAggregate( } } -func AggregateFromWriteModel(wm *eventstore.WriteModel) *Aggregate { - return &Aggregate{ - Aggregate: *eventstore.AggregateFromWriteModel(wm, AggregateType, AggregateVersion), - } -} - -func AggregateFromReadModel(rm *ReadModel) *Aggregate { - return &Aggregate{ - Aggregate: *eventstore.NewAggregate( - rm.AggregateID, - AggregateType, - rm.ResourceOwner, - AggregateVersion, - rm.ProcessedSequence, - ), - } -} - -func (a *Aggregate) PushMemberAdded(ctx context.Context, userID string, roles ...string) *Aggregate { - a.Aggregate = *a.PushEvents(NewMemberAddedEvent(ctx, userID, roles...)) - return a -} - -func (a *Aggregate) PushMemberChangedFromExisting(ctx context.Context, current *MemberWriteModel, roles ...string) *Aggregate { - e, err := MemberChangedEventFromExisting(ctx, current, roles...) - if err != nil { - return a - } - a.Aggregate = *a.PushEvents(e) - return a -} - -func (a *Aggregate) PushMemberRemoved(ctx context.Context, userID string) *Aggregate { - a.Aggregate = *a.PushEvents(NewMemberRemovedEvent(ctx, userID)) - return a -} - -func (a *Aggregate) PushStepStarted(ctx context.Context, step Step) *Aggregate { +func (a *Aggregate) PushStepStarted(ctx context.Context, step domain.Step) *Aggregate { a.Aggregate = *a.PushEvents(NewSetupStepStartedEvent(ctx, step)) return a } -func (a *Aggregate) PushStepDone(ctx context.Context, step Step) *Aggregate { +func (a *Aggregate) PushStepDone(ctx context.Context, step domain.Step) *Aggregate { a.Aggregate = *a.PushEvents(NewSetupStepDoneEvent(ctx, step)) return a } - -func (a *Aggregate) PushOrgIAMPolicyAddedEvent(ctx context.Context, userLoginMustBeDomain bool) *Aggregate { - a.Aggregate = *a.PushEvents(org_iam.NewAddedEvent(ctx, userLoginMustBeDomain)) - return a -} - -func (a *Aggregate) PushOrgIAMPolicyChangedFromExisting(ctx context.Context, current *org_iam.WriteModel, userLoginMustBeDomain bool) *Aggregate { - e, err := org_iam.ChangedEventFromExisting(ctx, current, userLoginMustBeDomain) - if err != nil { - return a - } - a.Aggregate = *a.PushEvents(e) - return a -} - -func (a *Aggregate) PushPasswordAgePolicyAddedEvent(ctx context.Context, expireWarnDays, maxAgeDays uint64) *Aggregate { - a.Aggregate = *a.PushEvents(password_age.NewAddedEvent(ctx, expireWarnDays, maxAgeDays)) - return a -} - -func (a *Aggregate) PushPasswordAgePolicyChangedFromExisting(ctx context.Context, current *password_age.WriteModel, expireWarnDays, maxAgeDays uint64) *Aggregate { - e, err := password_age.ChangedEventFromExisting(ctx, current, expireWarnDays, maxAgeDays) - if err != nil { - return a - } - a.Aggregate = *a.PushEvents(e) - return a -} - -func (a *Aggregate) PushPasswordComplexityPolicyAddedEvent(ctx context.Context, minLength uint64, hasLowercase, hasUppercase, hasNumber, hasSymbol bool) *Aggregate { - a.Aggregate = *a.PushEvents(password_complexity.NewAddedEvent(ctx, minLength, hasLowercase, hasUppercase, hasNumber, hasSymbol)) - return a -} - -func (a *Aggregate) PushPasswordComplexityPolicyChangedFromExisting(ctx context.Context, current *password_complexity.WriteModel, minLength uint64, hasLowercase, hasUppercase, hasNumber, hasSymbol bool) *Aggregate { - e, err := password_complexity.ChangedEventFromExisting(ctx, current, minLength, hasLowercase, hasUppercase, hasNumber, hasSymbol) - if err != nil { - return a - } - a.Aggregate = *a.PushEvents(e) - return a -} - -func (a *Aggregate) PushPasswordLockoutPolicyAddedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) *Aggregate { - a.Aggregate = *a.PushEvents(password_lockout.NewAddedEvent(ctx, maxAttempts, showLockoutFailure)) - return a -} - -func (a *Aggregate) PushPasswordLockoutPolicyChangedFromExisting(ctx context.Context, current *password_lockout.WriteModel, maxAttempts uint64, showLockoutFailure bool) *Aggregate { - e, err := password_lockout.ChangedEventFromExisting(ctx, current, maxAttempts, showLockoutFailure) - if err != nil { - return a - } - a.Aggregate = *a.PushEvents(e) - return a -} - -func (a *Aggregate) PushLabelPolicyAddedEvent(ctx context.Context, primaryColor, secondaryColor string) *Aggregate { - a.Aggregate = *a.PushEvents(label.NewAddedEvent(ctx, primaryColor, secondaryColor)) - return a -} - -func (a *Aggregate) PushLabelPolicyChangedFromExisting(ctx context.Context, current *label.WriteModel, primaryColor, secondaryColor string) *Aggregate { - e, err := label.ChangedEventFromExisting(ctx, current, primaryColor, secondaryColor) - if err != nil { - return a - } - a.Aggregate = *a.PushEvents(e) - return a -} - -func (a *Aggregate) PushLoginPolicyAddedEvent(ctx context.Context, allowUsernamePassword, allowRegister, allowExternalIDP, forceMFA bool, passwordlessType login.PasswordlessType) *Aggregate { - a.Aggregate = *a.PushEvents(iam_login.NewAddedEvent(ctx, allowUsernamePassword, allowRegister, allowExternalIDP, forceMFA, passwordlessType)) - return a -} - -func (a *Aggregate) PushLoginPolicyChangedFromExisting(ctx context.Context, current *iam_login.WriteModel, allowUsernamePassword, allowRegister, allowExternalIDP, forceMFA bool, passwordlessType login.PasswordlessType) *Aggregate { - e, err := iam_login.ChangedEventFromExisting(ctx, current, allowUsernamePassword, allowRegister, allowExternalIDP, forceMFA, passwordlessType) - if err != nil { - return a - } - a.Aggregate = *a.PushEvents(e) - return a -} - -func (a *Aggregate) PushLoginPolicySecondFactorAdded(ctx context.Context, mfaType factors.SecondFactorType) *Aggregate { - a.Aggregate = *a.PushEvents(iam_factors.NewLoginPolicySecondFactorAddedEvent(ctx, mfaType)) - return a -} - -func (a *Aggregate) PushLoginPolicySecondFactorRemoved(ctx context.Context, mfaType factors.SecondFactorType) *Aggregate { - a.Aggregate = *a.PushEvents(iam_factors.NewLoginPolicySecondFactorRemovedEvent(ctx, mfaType)) - return a -} - -func (a *Aggregate) PushLoginPolicyMultiFactorAdded(ctx context.Context, mfaType factors.MultiFactorType) *Aggregate { - a.Aggregate = *a.PushEvents(factors2.NewLoginPolicyMultiFactorAddedEvent(ctx, mfaType)) - return a -} - -func (a *Aggregate) PushLoginPolicyMultiFactorRemoved(ctx context.Context, mfaType factors.MultiFactorType) *Aggregate { - a.Aggregate = *a.PushEvents(factors2.NewLoginPolicyMultiFactorRemovedEvent(ctx, mfaType)) - return a -} - -func (a *Aggregate) PushIDPConfigAdded( - ctx context.Context, - configID, - name string, - configType idp.ConfigType, - stylingType idp.StylingType, -) *Aggregate { - - a.Aggregate = *a.PushEvents(NewIDPConfigAddedEvent(ctx, configID, name, configType, stylingType)) - return a -} - -func (a *Aggregate) PushIDPConfigChanged( - ctx context.Context, - current *IDPConfigWriteModel, - configID, - name string, - configType idp.ConfigType, - stylingType idp.StylingType, -) *Aggregate { - - event, err := NewIDPConfigChangedEvent(ctx, current, configID, name, configType, stylingType) - if err != nil { - return a - } - a.Aggregate = *a.PushEvents(event) - return a -} - -func (a *Aggregate) PushIDPConfigDeactivated(ctx context.Context, configID string) *Aggregate { - a.Aggregate = *a.PushEvents(NewIDPConfigDeactivatedEvent(ctx, configID)) - return a -} - -func (a *Aggregate) PushIDPConfigReactivated(ctx context.Context, configID string) *Aggregate { - a.Aggregate = *a.PushEvents(NewIDPConfigReactivatedEvent(ctx, configID)) - return a -} - -func (a *Aggregate) PushIDPConfigRemoved(ctx context.Context, configID string) *Aggregate { - a.Aggregate = *a.PushEvents(NewIDPConfigRemovedEvent(ctx, configID)) - return a -} - -func (a *Aggregate) PushIDPOIDCConfigAdded( - ctx context.Context, - clientID, - idpConfigID, - issuer string, - clientSecret *crypto.CryptoValue, - idpDisplayNameMapping, - userNameMapping oidc.MappingField, - scopes ...string, -) *Aggregate { - - a.Aggregate = *a.PushEvents(NewIDPOIDCConfigAddedEvent(ctx, clientID, idpConfigID, issuer, clientSecret, idpDisplayNameMapping, userNameMapping, scopes...)) - return a -} - -func (a *Aggregate) PushIDPOIDCConfigChanged( - ctx context.Context, - current *IDPOIDCConfigWriteModel, - clientID, - issuer string, - clientSecret *crypto.CryptoValue, - idpDisplayNameMapping, - userNameMapping oidc.MappingField, - scopes ...string, -) *Aggregate { - - event, err := NewIDPOIDCConfigChangedEvent(ctx, current, clientID, issuer, clientSecret, idpDisplayNameMapping, userNameMapping, scopes...) - if err != nil { - return a - } - - a.Aggregate = *a.PushEvents(event) - return a -} - -func (a *Aggregate) PushLoginPolicyIDPProviderAddedEvent( - ctx context.Context, - idpConfigID string, - providerType idpprovider2.Type, -) *Aggregate { - - a.Aggregate = *a.PushEvents(idpprovider.NewAddedEvent(ctx, idpConfigID, providerType)) - return a -} - -func (a *Aggregate) PushLoginPolicyIDPProviderRemovedEvent( - ctx context.Context, - idpConfigID string, - providerType idpprovider2.Type, -) *Aggregate { - - a.Aggregate = *a.PushEvents(idpprovider.NewRemovedEvent(ctx, idpConfigID)) - return a -} diff --git a/internal/v2/repository/iam/events_step.go b/internal/v2/repository/iam/events_step.go index f44951bc4e..3e13fb043e 100644 --- a/internal/v2/repository/iam/events_step.go +++ b/internal/v2/repository/iam/events_step.go @@ -7,6 +7,7 @@ import ( "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" ) const ( @@ -14,13 +15,11 @@ const ( SetupStartedEventType eventstore.EventType = "iam.setup.started" ) -type Step int8 - type SetupStepEvent struct { eventstore.BaseEvent `json:"-"` - Step Step `json:"Step"` - Done bool `json:"-"` + Step domain.Step `json:"Step"` + Done bool `json:"-"` } func (e *SetupStepEvent) Data() interface{} { @@ -42,7 +41,7 @@ func SetupStepMapper(event *repository.Event) (eventstore.EventReader, error) { func NewSetupStepDoneEvent( ctx context.Context, - step Step, + step domain.Step, ) *SetupStepEvent { return &SetupStepEvent{ @@ -56,7 +55,7 @@ func NewSetupStepDoneEvent( func NewSetupStepStartedEvent( ctx context.Context, - step Step, + step domain.Step, ) *SetupStepEvent { return &SetupStepEvent{ diff --git a/internal/v2/repository/iam/eventstore.go b/internal/v2/repository/iam/eventstore.go index b8816a4ca9..1994adb22d 100644 --- a/internal/v2/repository/iam/eventstore.go +++ b/internal/v2/repository/iam/eventstore.go @@ -2,12 +2,6 @@ package iam import ( "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/label" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/login" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/org_iam" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_age" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_complexity" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_lockout" ) func RegisterEventMappers(es *eventstore.Eventstore) { @@ -15,17 +9,17 @@ func RegisterEventMappers(es *eventstore.Eventstore) { RegisterFilterEventMapper(SetupDoneEventType, SetupStepMapper). RegisterFilterEventMapper(GlobalOrgSetEventType, GlobalOrgSetMapper). RegisterFilterEventMapper(ProjectSetEventType, ProjectSetMapper). - RegisterFilterEventMapper(label.LabelPolicyAddedEventType, label.AddedEventMapper). - RegisterFilterEventMapper(label.LabelPolicyChangedEventType, label.ChangedEventMapper). - RegisterFilterEventMapper(login.LoginPolicyAddedEventType, login.AddedEventMapper). - RegisterFilterEventMapper(login.LoginPolicyChangedEventType, login.ChangedEventMapper). - RegisterFilterEventMapper(org_iam.OrgIAMPolicyAddedEventType, org_iam.AddedEventMapper). - RegisterFilterEventMapper(password_age.PasswordAgePolicyAddedEventType, password_age.AddedEventMapper). - RegisterFilterEventMapper(password_age.PasswordAgePolicyChangedEventType, password_age.ChangedEventMapper). - RegisterFilterEventMapper(password_complexity.PasswordComplexityPolicyAddedEventType, password_complexity.AddedEventMapper). - RegisterFilterEventMapper(password_complexity.PasswordComplexityPolicyChangedEventType, password_complexity.ChangedEventMapper). - RegisterFilterEventMapper(password_lockout.PasswordLockoutPolicyAddedEventType, password_lockout.AddedEventMapper). - RegisterFilterEventMapper(password_lockout.PasswordLockoutPolicyChangedEventType, password_lockout.ChangedEventMapper). + RegisterFilterEventMapper(LabelPolicyAddedEventType, LabelPolicyAddedEventMapper). + RegisterFilterEventMapper(LabelPolicyChangedEventType, LabelPolicyChangedEventMapper). + RegisterFilterEventMapper(LoginPolicyAddedEventType, LoginPolicyAddedEventMapper). + RegisterFilterEventMapper(LoginPolicyChangedEventType, LoginPolicyChangedEventMapper). + RegisterFilterEventMapper(OrgIAMPolicyAddedEventType, OrgIAMPolicyAddedEventMapper). + RegisterFilterEventMapper(PasswordAgePolicyAddedEventType, PasswordAgePolicyAddedEventMapper). + RegisterFilterEventMapper(PasswordAgePolicyChangedEventType, PasswordAgePolicyChangedEventMapper). + RegisterFilterEventMapper(PasswordComplexityPolicyAddedEventType, PasswordComplexityPolicyAddedEventMapper). + RegisterFilterEventMapper(PasswordComplexityPolicyChangedEventType, PasswordComplexityPolicyChangedEventMapper). + RegisterFilterEventMapper(PasswordLockoutPolicyAddedEventType, PasswordLockoutPolicyAddedEventMapper). + RegisterFilterEventMapper(PasswordLockoutPolicyChangedEventType, PasswordLockoutPolicyChangedEventMapper). RegisterFilterEventMapper(MemberAddedEventType, MemberAddedEventMapper). RegisterFilterEventMapper(MemberChangedEventType, MemberChangedEventMapper). RegisterFilterEventMapper(MemberRemovedEventType, MemberRemovedEventMapper). diff --git a/internal/v2/repository/iam/idp_config.go b/internal/v2/repository/iam/idp_config.go index 6c0521598c..05207b27b5 100644 --- a/internal/v2/repository/iam/idp_config.go +++ b/internal/v2/repository/iam/idp_config.go @@ -2,10 +2,10 @@ package iam import ( "context" - "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/idp" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/idpconfig" ) const ( @@ -16,138 +16,20 @@ const ( IDPConfigReactivatedEventType eventstore.EventType = "iam.idp.config.reactivated" ) -type IDPConfigReadModel struct { - idp.ConfigReadModel - - iamID string - configID string -} - -func NewIDPConfigReadModel(iamID, configID string) *IDPConfigReadModel { - return &IDPConfigReadModel{ - iamID: iamID, - configID: configID, - } -} - -func (rm *IDPConfigReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *IDPConfigAddedEvent: - rm.ConfigReadModel.AppendEvents(&e.ConfigAddedEvent) - case *IDPConfigChangedEvent: - rm.ConfigReadModel.AppendEvents(&e.ConfigChangedEvent) - case *IDPConfigDeactivatedEvent: - rm.ConfigReadModel.AppendEvents(&e.ConfigDeactivatedEvent) - case *IDPConfigReactivatedEvent: - rm.ConfigReadModel.AppendEvents(&e.ConfigReactivatedEvent) - case *IDPConfigRemovedEvent: - rm.ConfigReadModel.AppendEvents(&e.ConfigRemovedEvent) - case *IDPOIDCConfigAddedEvent: - rm.ConfigReadModel.AppendEvents(&e.ConfigAddedEvent) - case *IDPOIDCConfigChangedEvent: - rm.ConfigReadModel.AppendEvents(&e.ConfigChangedEvent) - } - } -} - -func (rm *IDPConfigReadModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(rm.iamID). - EventData(map[string]interface{}{ - "idpConfigId": rm.configID, - }) -} - -type IDPConfigWriteModel struct { - eventstore.WriteModel - idp.ConfigWriteModel - - iamID string - configID string -} - -func NewIDPConfigWriteModel(iamID, configID string) *IDPConfigWriteModel { - return &IDPConfigWriteModel{ - iamID: iamID, - configID: configID, - } -} - -func (wm *IDPConfigWriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.iamID) -} - -func (wm *IDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) - for _, event := range events { - switch e := event.(type) { - case *IDPConfigAddedEvent: - if wm.configID != e.ConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigAddedEvent) - case *IDPConfigChangedEvent: - if wm.configID != e.ConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigChangedEvent) - case *IDPConfigDeactivatedEvent: - if wm.configID != e.ConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigDeactivatedEvent) - case *IDPConfigReactivatedEvent: - if wm.configID != e.ConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigReactivatedEvent) - case *IDPConfigRemovedEvent: - if wm.configID != e.ConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigRemovedEvent) - case *IDPOIDCConfigAddedEvent: - if wm.configID != e.IDPConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigAddedEvent) - case *IDPOIDCConfigChangedEvent: - if wm.configID != e.IDPConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigChangedEvent) - } - } -} - -func (wm *IDPConfigWriteModel) Reduce() error { - if err := wm.ConfigWriteModel.Reduce(); err != nil { - return err - } - return wm.WriteModel.Reduce() -} - -func (wm *IDPConfigWriteModel) AppendAndReduce(events ...eventstore.EventReader) error { - wm.AppendEvents(events...) - return wm.Reduce() -} - type IDPConfigAddedEvent struct { - idp.ConfigAddedEvent + idpconfig.IDPConfigAddedEvent } func NewIDPConfigAddedEvent( ctx context.Context, configID string, name string, - configType idp.ConfigType, - stylingType idp.StylingType, + configType domain.IDPConfigType, + stylingType domain.IDPConfigStylingType, ) *IDPConfigAddedEvent { return &IDPConfigAddedEvent{ - ConfigAddedEvent: *idp.NewConfigAddedEvent( + IDPConfigAddedEvent: *idpconfig.NewIDPConfigAddedEvent( eventstore.NewBaseEventForPush( ctx, IDPConfigAddedEventType, @@ -161,57 +43,39 @@ func NewIDPConfigAddedEvent( } func IDPConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := idp.ConfigAddedEventMapper(event) + e, err := idpconfig.IDPConfigAddedEventMapper(event) if err != nil { return nil, err } - return &IDPConfigAddedEvent{ConfigAddedEvent: *e.(*idp.ConfigAddedEvent)}, nil + return &IDPConfigAddedEvent{IDPConfigAddedEvent: *e.(*idpconfig.IDPConfigAddedEvent)}, nil } type IDPConfigChangedEvent struct { - idp.ConfigChangedEvent + idpconfig.IDPConfigChangedEvent } func NewIDPConfigChangedEvent( ctx context.Context, - current *IDPConfigWriteModel, - configID string, - name string, - configType idp.ConfigType, - stylingType idp.StylingType, -) (*IDPConfigChangedEvent, error) { - - event, err := idp.NewConfigChangedEvent( - eventstore.NewBaseEventForPush( - ctx, - IDPConfigChangedEventType, - ), - ¤t.ConfigWriteModel, - name, - stylingType, - ) - - if err != nil { - return nil, err - } - +) *IDPConfigChangedEvent { return &IDPConfigChangedEvent{ - ConfigChangedEvent: *event, - }, nil + IDPConfigChangedEvent: *idpconfig.NewIDPConfigChangedEvent( + eventstore.NewBaseEventForPush(ctx, IDPConfigChangedEventType), + ), + } } func IDPConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := idp.ConfigChangedEventMapper(event) + e, err := idpconfig.IDPConfigChangedEventMapper(event) if err != nil { return nil, err } - return &IDPConfigChangedEvent{ConfigChangedEvent: *e.(*idp.ConfigChangedEvent)}, nil + return &IDPConfigChangedEvent{IDPConfigChangedEvent: *e.(*idpconfig.IDPConfigChangedEvent)}, nil } type IDPConfigRemovedEvent struct { - idp.ConfigRemovedEvent + idpconfig.IDPConfigRemovedEvent } func NewIDPConfigRemovedEvent( @@ -220,7 +84,7 @@ func NewIDPConfigRemovedEvent( ) *IDPConfigRemovedEvent { return &IDPConfigRemovedEvent{ - ConfigRemovedEvent: *idp.NewConfigRemovedEvent( + IDPConfigRemovedEvent: *idpconfig.NewIDPConfigRemovedEvent( eventstore.NewBaseEventForPush( ctx, IDPConfigRemovedEventType, @@ -231,16 +95,16 @@ func NewIDPConfigRemovedEvent( } func IDPConfigRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := idp.ConfigRemovedEventMapper(event) + e, err := idpconfig.IDPConfigRemovedEventMapper(event) if err != nil { return nil, err } - return &IDPConfigRemovedEvent{ConfigRemovedEvent: *e.(*idp.ConfigRemovedEvent)}, nil + return &IDPConfigRemovedEvent{IDPConfigRemovedEvent: *e.(*idpconfig.IDPConfigRemovedEvent)}, nil } type IDPConfigDeactivatedEvent struct { - idp.ConfigDeactivatedEvent + idpconfig.IDPConfigDeactivatedEvent } func NewIDPConfigDeactivatedEvent( @@ -249,7 +113,7 @@ func NewIDPConfigDeactivatedEvent( ) *IDPConfigDeactivatedEvent { return &IDPConfigDeactivatedEvent{ - ConfigDeactivatedEvent: *idp.NewConfigDeactivatedEvent( + IDPConfigDeactivatedEvent: *idpconfig.NewIDPConfigDeactivatedEvent( eventstore.NewBaseEventForPush( ctx, IDPConfigDeactivatedEventType, @@ -260,16 +124,16 @@ func NewIDPConfigDeactivatedEvent( } func IDPConfigDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := idp.ConfigDeactivatedEventMapper(event) + e, err := idpconfig.IDPConfigDeactivatedEventMapper(event) if err != nil { return nil, err } - return &IDPConfigDeactivatedEvent{ConfigDeactivatedEvent: *e.(*idp.ConfigDeactivatedEvent)}, nil + return &IDPConfigDeactivatedEvent{IDPConfigDeactivatedEvent: *e.(*idpconfig.IDPConfigDeactivatedEvent)}, nil } type IDPConfigReactivatedEvent struct { - idp.ConfigReactivatedEvent + idpconfig.IDPConfigReactivatedEvent } func NewIDPConfigReactivatedEvent( @@ -278,7 +142,7 @@ func NewIDPConfigReactivatedEvent( ) *IDPConfigReactivatedEvent { return &IDPConfigReactivatedEvent{ - ConfigReactivatedEvent: *idp.NewConfigReactivatedEvent( + IDPConfigReactivatedEvent: *idpconfig.NewIDPConfigReactivatedEvent( eventstore.NewBaseEventForPush( ctx, IDPConfigReactivatedEventType, @@ -289,10 +153,10 @@ func NewIDPConfigReactivatedEvent( } func IDPConfigReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := idp.ConfigReactivatedEventMapper(event) + e, err := idpconfig.IDPConfigReactivatedEventMapper(event) if err != nil { return nil, err } - return &IDPConfigReactivatedEvent{ConfigReactivatedEvent: *e.(*idp.ConfigReactivatedEvent)}, nil + return &IDPConfigReactivatedEvent{IDPConfigReactivatedEvent: *e.(*idpconfig.IDPConfigReactivatedEvent)}, nil } diff --git a/internal/v2/repository/iam/idp_configs.go b/internal/v2/repository/iam/idp_configs.go deleted file mode 100644 index 8aa0756023..0000000000 --- a/internal/v2/repository/iam/idp_configs.go +++ /dev/null @@ -1,31 +0,0 @@ -package iam - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/idp" -) - -type IDPConfigsReadModel struct { - idp.ConfigsReadModel -} - -func (rm *IDPConfigsReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *IDPConfigAddedEvent: - rm.ConfigsReadModel.AppendEvents(&e.ConfigAddedEvent) - case *IDPConfigChangedEvent: - rm.ConfigsReadModel.AppendEvents(&e.ConfigChangedEvent) - case *IDPConfigDeactivatedEvent: - rm.ConfigsReadModel.AppendEvents(&e.ConfigDeactivatedEvent) - case *IDPConfigReactivatedEvent: - rm.ConfigsReadModel.AppendEvents(&e.ConfigReactivatedEvent) - case *IDPConfigRemovedEvent: - rm.ConfigsReadModel.AppendEvents(&e.ConfigRemovedEvent) - case *IDPOIDCConfigAddedEvent: - rm.ConfigsReadModel.AppendEvents(&e.ConfigAddedEvent) - case *IDPOIDCConfigChangedEvent: - rm.ConfigsReadModel.AppendEvents(&e.ConfigChangedEvent) - } - } -} diff --git a/internal/v2/repository/iam/idp_oidc_config.go b/internal/v2/repository/iam/idp_oidc_config.go index a23a1402b7..737f7d9351 100644 --- a/internal/v2/repository/iam/idp_oidc_config.go +++ b/internal/v2/repository/iam/idp_oidc_config.go @@ -2,67 +2,20 @@ package iam import ( "context" - "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/idp/oidc" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/idpconfig" ) const ( - IDPOIDCConfigAddedEventType eventstore.EventType = "iam.idp." + oidc.ConfigAddedEventType - IDPOIDCConfigChangedEventType eventstore.EventType = "iam.idp." + oidc.ConfigChangedEventType + IDPOIDCConfigAddedEventType eventstore.EventType = "iam.idp." + idpconfig.OIDCConfigAddedEventType + IDPOIDCConfigChangedEventType eventstore.EventType = "iam.idp." + idpconfig.ConfigChangedEventType ) -type IDPOIDCConfigWriteModel struct { - eventstore.WriteModel - oidc.ConfigWriteModel - - iamID string - idpConfigID string -} - -func NewIDPOIDCConfigWriteModel(iamID, idpConfigID string) *IDPOIDCConfigWriteModel { - return &IDPOIDCConfigWriteModel{ - iamID: iamID, - idpConfigID: idpConfigID, - } -} - -func (wm *IDPOIDCConfigWriteModel) AppendEvents(events ...eventstore.EventReader) { - wm.WriteModel.AppendEvents(events...) - for _, event := range events { - switch e := event.(type) { - case *IDPOIDCConfigAddedEvent: - if wm.idpConfigID != e.IDPConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigAddedEvent) - case *IDPOIDCConfigChangedEvent: - if wm.idpConfigID != e.IDPConfigID { - continue - } - wm.ConfigWriteModel.AppendEvents(&e.ConfigChangedEvent) - default: - wm.ConfigWriteModel.AppendEvents(e) - } - } -} - -func (wm *IDPOIDCConfigWriteModel) Reduce() error { - if err := wm.ConfigWriteModel.Reduce(); err != nil { - return err - } - return wm.WriteModel.Reduce() -} - -func (wm *IDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.iamID) -} - type IDPOIDCConfigAddedEvent struct { - oidc.ConfigAddedEvent + idpconfig.OIDCConfigAddedEvent } func NewIDPOIDCConfigAddedEvent( @@ -72,12 +25,12 @@ func NewIDPOIDCConfigAddedEvent( issuer string, clientSecret *crypto.CryptoValue, idpDisplayNameMapping, - userNameMapping oidc.MappingField, + userNameMapping domain.OIDCMappingField, scopes ...string, ) *IDPOIDCConfigAddedEvent { return &IDPOIDCConfigAddedEvent{ - ConfigAddedEvent: *oidc.NewConfigAddedEvent( + OIDCConfigAddedEvent: *idpconfig.NewOIDCConfigAddedEvent( eventstore.NewBaseEventForPush( ctx, IDPOIDCConfigAddedEventType, @@ -94,57 +47,33 @@ func NewIDPOIDCConfigAddedEvent( } func IDPOIDCConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := oidc.ConfigAddedEventMapper(event) + e, err := idpconfig.OIDCConfigAddedEventMapper(event) if err != nil { return nil, err } - return &IDPOIDCConfigAddedEvent{ConfigAddedEvent: *e.(*oidc.ConfigAddedEvent)}, nil + return &IDPOIDCConfigAddedEvent{OIDCConfigAddedEvent: *e.(*idpconfig.OIDCConfigAddedEvent)}, nil } type IDPOIDCConfigChangedEvent struct { - oidc.ConfigChangedEvent + idpconfig.OIDCConfigChangedEvent } func NewIDPOIDCConfigChangedEvent( ctx context.Context, - current *IDPOIDCConfigWriteModel, - clientID, - issuer string, - clientSecret *crypto.CryptoValue, - idpDisplayNameMapping, - userNameMapping oidc.MappingField, - scopes ...string, -) (*IDPOIDCConfigChangedEvent, error) { - - event, err := oidc.NewConfigChangedEvent( - eventstore.NewBaseEventForPush( - ctx, - IDPOIDCConfigChangedEventType, - ), - ¤t.ConfigWriteModel, - clientID, - issuer, - clientSecret, - idpDisplayNameMapping, - userNameMapping, - scopes..., - ) - - if err != nil { - return nil, err - } - +) *IDPOIDCConfigChangedEvent { return &IDPOIDCConfigChangedEvent{ - ConfigChangedEvent: *event, - }, nil + OIDCConfigChangedEvent: *idpconfig.NewOIDCConfigChangedEvent( + eventstore.NewBaseEventForPush(ctx, IDPOIDCConfigChangedEventType), + ), + } } func IDPOIDCConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := oidc.ConfigChangedEventMapper(event) + e, err := idpconfig.OIDCConfigChangedEventMapper(event) if err != nil { return nil, err } - return &IDPOIDCConfigChangedEvent{ConfigChangedEvent: *e.(*oidc.ConfigChangedEvent)}, nil + return &IDPOIDCConfigChangedEvent{OIDCConfigChangedEvent: *e.(*idpconfig.OIDCConfigChangedEvent)}, nil } diff --git a/internal/v2/repository/iam/member.go b/internal/v2/repository/iam/member.go index c92cf5cabf..59961bc790 100644 --- a/internal/v2/repository/iam/member.go +++ b/internal/v2/repository/iam/member.go @@ -2,101 +2,19 @@ package iam import ( "context" - "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/v2/repository/member" ) var ( - MemberAddedEventType = IamEventTypePrefix + member.AddedEventType - MemberChangedEventType = IamEventTypePrefix + member.ChangedEventType - MemberRemovedEventType = IamEventTypePrefix + member.RemovedEventType + MemberAddedEventType = iamEventTypePrefix + member.AddedEventType + MemberChangedEventType = iamEventTypePrefix + member.ChangedEventType + MemberRemovedEventType = iamEventTypePrefix + member.RemovedEventType ) -type MemberReadModel struct { - member.ReadModel - - userID string - iamID string -} - -func NewMemberReadModel(iamID, userID string) *MemberReadModel { - return &MemberReadModel{ - iamID: iamID, - userID: userID, - } -} - -func (rm *MemberReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *MemberAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *MemberChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *member.AddedEvent, *member.ChangedEvent, *MemberRemovedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} - -func (rm *MemberReadModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(rm.iamID). - EventData(map[string]interface{}{ - "userId": rm.userID, - }) -} - -type MemberWriteModel struct { - member.WriteModel -} - -func NewMemberWriteModel(iamID, userID string) *MemberWriteModel { - return &MemberWriteModel{ - member.WriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - UserID: userID, - }, - } -} - -func (wm *MemberWriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *MemberAddedEvent: - if e.UserID != wm.WriteModel.UserID { - continue - } - wm.WriteModel.AppendEvents(&e.AddedEvent) - case *MemberChangedEvent: - if e.UserID != wm.WriteModel.UserID { - continue - } - wm.WriteModel.AppendEvents(&e.ChangedEvent) - case *MemberRemovedEvent: - if e.UserID != wm.WriteModel.UserID { - continue - } - wm.WriteModel.AppendEvents(&e.RemovedEvent) - } - } -} - -func (wm *MemberWriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *MemberWriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} - type MemberAddedEvent struct { - member.AddedEvent + member.MemberAddedEvent } func NewMemberAddedEvent( @@ -106,7 +24,7 @@ func NewMemberAddedEvent( ) *MemberAddedEvent { return &MemberAddedEvent{ - AddedEvent: *member.NewAddedEvent( + MemberAddedEvent: *member.NewMemberAddedEvent( eventstore.NewBaseEventForPush( ctx, MemberAddedEventType, @@ -118,39 +36,33 @@ func NewMemberAddedEvent( } func MemberAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := member.AddedEventMapper(event) + e, err := member.MemberAddedEventMapper(event) if err != nil { return nil, err } - return &MemberAddedEvent{AddedEvent: *e.(*member.AddedEvent)}, nil + return &MemberAddedEvent{MemberAddedEvent: *e.(*member.MemberAddedEvent)}, nil } type MemberChangedEvent struct { - member.ChangedEvent + member.MemberChangedEvent } -func MemberChangedEventFromExisting( +func NewMemberChangedEvent( ctx context.Context, - current *MemberWriteModel, + userID string, roles ...string, -) (*MemberChangedEvent, error) { - - event, err := member.ChangeEventFromExisting( - eventstore.NewBaseEventForPush( - ctx, - MemberChangedEventType, - ), - ¤t.WriteModel, - roles..., - ) - if err != nil { - return nil, err - } - +) *MemberChangedEvent { return &MemberChangedEvent{ - ChangedEvent: *event, - }, nil + MemberChangedEvent: *member.NewMemberChangedEvent( + eventstore.NewBaseEventForPush( + ctx, + MemberChangedEventType, + ), + userID, + roles..., + ), + } } func MemberChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { @@ -159,11 +71,11 @@ func MemberChangedEventMapper(event *repository.Event) (eventstore.EventReader, return nil, err } - return &MemberChangedEvent{ChangedEvent: *e.(*member.ChangedEvent)}, nil + return &MemberChangedEvent{MemberChangedEvent: *e.(*member.MemberChangedEvent)}, nil } type MemberRemovedEvent struct { - member.RemovedEvent + member.MemberRemovedEvent } func NewMemberRemovedEvent( @@ -172,7 +84,7 @@ func NewMemberRemovedEvent( ) *MemberRemovedEvent { return &MemberRemovedEvent{ - RemovedEvent: *member.NewRemovedEvent( + MemberRemovedEvent: *member.NewRemovedEvent( eventstore.NewBaseEventForPush( ctx, MemberRemovedEventType, @@ -188,5 +100,5 @@ func MemberRemovedEventMapper(event *repository.Event) (eventstore.EventReader, return nil, err } - return &MemberRemovedEvent{RemovedEvent: *e.(*member.RemovedEvent)}, nil + return &MemberRemovedEvent{MemberRemovedEvent: *e.(*member.MemberRemovedEvent)}, nil } diff --git a/internal/v2/repository/iam/members.go b/internal/v2/repository/iam/members.go deleted file mode 100644 index 814eb63212..0000000000 --- a/internal/v2/repository/iam/members.go +++ /dev/null @@ -1,23 +0,0 @@ -package iam - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/members" -) - -type MembersReadModel struct { - members.ReadModel -} - -func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *MemberAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *MemberChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *MemberRemovedEvent: - rm.ReadModel.AppendEvents(&e.RemovedEvent) - } - } -} diff --git a/internal/v2/repository/iam/policy/label/events.go b/internal/v2/repository/iam/policy/label/events.go deleted file mode 100644 index c29b5d4827..0000000000 --- a/internal/v2/repository/iam/policy/label/events.go +++ /dev/null @@ -1,73 +0,0 @@ -package label - -import ( - "context" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/policy/label" -) - -var ( - iamEventPrefix = eventstore.EventType("iam.") - LabelPolicyAddedEventType = iamEventPrefix + label.LabelPolicyAddedEventType - LabelPolicyChangedEventType = iamEventPrefix + label.LabelPolicyChangedEventType -) - -type AddedEvent struct { - label.AddedEvent -} - -func NewAddedEvent( - ctx context.Context, - primaryColor, - secondaryColor string, -) *AddedEvent { - return &AddedEvent{ - AddedEvent: *label.NewAddedEvent( - eventstore.NewBaseEventForPush(ctx, LabelPolicyAddedEventType), - primaryColor, - secondaryColor), - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := label.AddedEventMapper(event) - if err != nil { - return nil, err - } - - return &AddedEvent{AddedEvent: *e.(*label.AddedEvent)}, nil -} - -type ChangedEvent struct { - label.ChangedEvent -} - -func ChangedEventFromExisting( - ctx context.Context, - current *WriteModel, - primaryColor, - secondaryColor string, -) (*ChangedEvent, error) { - event := label.NewChangedEvent( - eventstore.NewBaseEventForPush( - ctx, - LabelPolicyChangedEventType, - ), - ¤t.WriteModel, - primaryColor, - secondaryColor, - ) - return &ChangedEvent{ - *event, - }, nil -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := label.ChangedEventMapper(event) - if err != nil { - return nil, err - } - - return &ChangedEvent{ChangedEvent: *e.(*label.ChangedEvent)}, nil -} diff --git a/internal/v2/repository/iam/policy/label/read_model.go b/internal/v2/repository/iam/policy/label/read_model.go deleted file mode 100644 index 4dcd0876bf..0000000000 --- a/internal/v2/repository/iam/policy/label/read_model.go +++ /dev/null @@ -1,21 +0,0 @@ -package label - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/label" -) - -type ReadModel struct{ label.ReadModel } - -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *label.AddedEvent, *label.ChangedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} diff --git a/internal/v2/repository/iam/policy/label/write_model.go b/internal/v2/repository/iam/policy/label/write_model.go deleted file mode 100644 index b7a3db691b..0000000000 --- a/internal/v2/repository/iam/policy/label/write_model.go +++ /dev/null @@ -1,44 +0,0 @@ -package label - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/label" -) - -const ( - AggregateType = "iam" -) - -type WriteModel struct { - label.WriteModel -} - -func NewWriteModel(iamID string) *WriteModel { - return &WriteModel{ - label.WriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - }, - } -} - -func (wm *WriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - wm.WriteModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - wm.WriteModel.AppendEvents(&e.ChangedEvent) - } - } -} - -func (wm *WriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *WriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} diff --git a/internal/v2/repository/iam/policy/login/events.go b/internal/v2/repository/iam/policy/login/events.go deleted file mode 100644 index 951fc016ac..0000000000 --- a/internal/v2/repository/iam/policy/login/events.go +++ /dev/null @@ -1,89 +0,0 @@ -package login - -import ( - "context" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/policy/login" -) - -var ( - iamEventPrefix = eventstore.EventType("iam.") - LoginPolicyAddedEventType = iamEventPrefix + login.LoginPolicyAddedEventType - LoginPolicyChangedEventType = iamEventPrefix + login.LoginPolicyChangedEventType - - LoginPolicyIDPProviderAddedEventType = iamEventPrefix + login.LoginPolicyIDPProviderAddedEventType - LoginPolicyIDPProviderRemovedEventType = iamEventPrefix + login.LoginPolicyIDPProviderRemovedEventType -) - -type AddedEvent struct { - login.AddedEvent -} - -func NewAddedEvent( - ctx context.Context, - allowUsernamePassword, - allowRegister, - allowExternalIDP, - forceMFA bool, - passwordlessType login.PasswordlessType, -) *AddedEvent { - return &AddedEvent{ - AddedEvent: *login.NewAddedEvent( - eventstore.NewBaseEventForPush(ctx, login.LoginPolicyAddedEventType), - allowUsernamePassword, - allowRegister, - allowExternalIDP, - forceMFA, - passwordlessType), - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := login.AddedEventMapper(event) - if err != nil { - return nil, err - } - - return &AddedEvent{AddedEvent: *e.(*login.AddedEvent)}, nil -} - -type ChangedEvent struct { - login.ChangedEvent -} - -func ChangedEventFromExisting( - ctx context.Context, - current *WriteModel, - allowUsernamePassword, - allowRegister, - allowExternalIDP, - forceMFA bool, - passwordlessType login.PasswordlessType, -) (*ChangedEvent, error) { - - event := login.NewChangedEvent( - eventstore.NewBaseEventForPush( - ctx, - LoginPolicyChangedEventType, - ), - ¤t.WriteModel, - allowUsernamePassword, - allowRegister, - allowExternalIDP, - forceMFA, - passwordlessType, - ) - return &ChangedEvent{ - *event, - }, nil -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := login.ChangedEventMapper(event) - if err != nil { - return nil, err - } - - return &ChangedEvent{ChangedEvent: *e.(*login.ChangedEvent)}, nil -} diff --git a/internal/v2/repository/iam/policy/login/factors/write_model.go b/internal/v2/repository/iam/policy/login/factors/write_model.go deleted file mode 100644 index dc3fdad369..0000000000 --- a/internal/v2/repository/iam/policy/login/factors/write_model.go +++ /dev/null @@ -1,74 +0,0 @@ -package factors - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/login/factors" -) - -const ( - AggregateType = "iam" -) - -type SecondFactorWriteModel struct { - factors.SecondFactorWriteModel -} - -func NewSecondFactorWriteModel(iamID string) *SecondFactorWriteModel { - return &SecondFactorWriteModel{ - factors.SecondFactorWriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - }, - } -} - -func (wm *SecondFactorWriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *LoginPolicySecondFactorAddedEvent: - wm.WriteModel.AppendEvents(&e.SecondFactorAddedEvent) - } - } -} - -func (wm *SecondFactorWriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *SecondFactorWriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} - -type MultiFactorWriteModel struct { - factors.MultiFactoryWriteModel -} - -func NewMultiFactorWriteModel(iamID string) *MultiFactorWriteModel { - return &MultiFactorWriteModel{ - factors.MultiFactoryWriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - }, - } -} - -func (wm *MultiFactorWriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *LoginPolicyMultiFactorAddedEvent: - wm.WriteModel.AppendEvents(&e.MultiFactorAddedEvent) - } - } -} - -func (wm *MultiFactorWriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *MultiFactorWriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} diff --git a/internal/v2/repository/iam/policy/login/idpprovider/events.go b/internal/v2/repository/iam/policy/login/idpprovider/events.go deleted file mode 100644 index c86df181a1..0000000000 --- a/internal/v2/repository/iam/policy/login/idpprovider/events.go +++ /dev/null @@ -1,65 +0,0 @@ -package idpprovider - -import ( - "context" - "github.com/caos/zitadel/internal/v2/repository/iam/policy/login" - "github.com/caos/zitadel/internal/v2/repository/policy/login/idpprovider" - - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -type AddedEvent struct { - idpprovider.AddedEvent -} - -func NewAddedEvent( - ctx context.Context, - idpConfigID string, - idpProviderType idpprovider.Type, -) *AddedEvent { - - return &AddedEvent{ - AddedEvent: *idpprovider.NewAddedEvent( - eventstore.NewBaseEventForPush(ctx, login.LoginPolicyIDPProviderAddedEventType), - idpConfigID, - idpProviderType), - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := idpprovider.AddedEventMapper(event) - if err != nil { - return nil, err - } - - return &AddedEvent{ - AddedEvent: *e.(*idpprovider.AddedEvent), - }, nil -} - -type RemovedEvent struct { - idpprovider.RemovedEvent -} - -func NewRemovedEvent( - ctx context.Context, - idpConfigID string, -) *RemovedEvent { - return &RemovedEvent{ - RemovedEvent: *idpprovider.NewRemovedEvent( - eventstore.NewBaseEventForPush(ctx, login.LoginPolicyIDPProviderRemovedEventType), - idpConfigID), - } -} - -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := idpprovider.RemovedEventMapper(event) - if err != nil { - return nil, err - } - - return &RemovedEvent{ - RemovedEvent: *e.(*idpprovider.RemovedEvent), - }, nil -} diff --git a/internal/v2/repository/iam/policy/login/idpprovider/write_model.go b/internal/v2/repository/iam/policy/login/idpprovider/write_model.go deleted file mode 100644 index b75911c0f0..0000000000 --- a/internal/v2/repository/iam/policy/login/idpprovider/write_model.go +++ /dev/null @@ -1,48 +0,0 @@ -package idpprovider - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/login/idpprovider" -) - -const ( - AggregateType = "iam" -) - -type WriteModel struct { - idpprovider.WriteModel - IsRemoved bool -} - -func NewWriteModel(iamID, idpConfigID string) *WriteModel { - return &WriteModel{ - WriteModel: idpprovider.WriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - IDPConfigID: idpConfigID, - }, - IsRemoved: false, - } -} - -func (wm *WriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - if e.IDPConfigID != wm.IDPConfigID { - continue - } - wm.WriteModel.AppendEvents(&e.AddedEvent) - } - } -} - -func (wm *WriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *WriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.AggregateID) -} diff --git a/internal/v2/repository/iam/policy/login/read_model.go b/internal/v2/repository/iam/policy/login/read_model.go deleted file mode 100644 index 5d348915eb..0000000000 --- a/internal/v2/repository/iam/policy/login/read_model.go +++ /dev/null @@ -1,21 +0,0 @@ -package login - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/login" -) - -type ReadModel struct{ login.ReadModel } - -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *login.AddedEvent, *login.ChangedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} diff --git a/internal/v2/repository/iam/policy/login/write_model.go b/internal/v2/repository/iam/policy/login/write_model.go deleted file mode 100644 index d609511892..0000000000 --- a/internal/v2/repository/iam/policy/login/write_model.go +++ /dev/null @@ -1,44 +0,0 @@ -package login - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/login" -) - -const ( - AggregateType = "iam" -) - -type WriteModel struct { - login.WriteModel -} - -func NewWriteModel(iamID string) *WriteModel { - return &WriteModel{ - login.WriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - }, - } -} - -func (wm *WriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - wm.WriteModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - wm.WriteModel.AppendEvents(&e.ChangedEvent) - } - } -} - -func (wm *WriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *WriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} diff --git a/internal/v2/repository/iam/policy/org_iam/events.go b/internal/v2/repository/iam/policy/org_iam/events.go deleted file mode 100644 index 6619ef518b..0000000000 --- a/internal/v2/repository/iam/policy/org_iam/events.go +++ /dev/null @@ -1,70 +0,0 @@ -package org_iam - -import ( - "context" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/policy/org_iam" -) - -var ( - iamEventPrefix = eventstore.EventType("iam.") - OrgIAMPolicyAddedEventType = iamEventPrefix + org_iam.OrgIAMPolicyAddedEventType - OrgIAMPolicyChangedEventType = iamEventPrefix + org_iam.OrgIAMPolicyChangedEventType -) - -type AddedEvent struct { - org_iam.AddedEvent -} - -func NewAddedEvent( - ctx context.Context, - userLoginMustBeDomain bool, -) *AddedEvent { - return &AddedEvent{ - AddedEvent: *org_iam.NewAddedEvent( - eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyAddedEventType), - userLoginMustBeDomain, - ), - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := org_iam.AddedEventMapper(event) - if err != nil { - return nil, err - } - - return &AddedEvent{AddedEvent: *e.(*org_iam.AddedEvent)}, nil -} - -type ChangedEvent struct { - org_iam.ChangedEvent -} - -func ChangedEventFromExisting( - ctx context.Context, - current *WriteModel, - userLoginMustBeDomain bool, -) (*ChangedEvent, error) { - event := org_iam.NewChangedEvent( - eventstore.NewBaseEventForPush( - ctx, - OrgIAMPolicyChangedEventType, - ), - ¤t.WriteModel, - userLoginMustBeDomain, - ) - return &ChangedEvent{ - *event, - }, nil -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := org_iam.ChangedEventMapper(event) - if err != nil { - return nil, err - } - - return &ChangedEvent{ChangedEvent: *e.(*org_iam.ChangedEvent)}, nil -} diff --git a/internal/v2/repository/iam/policy/org_iam/read_model.go b/internal/v2/repository/iam/policy/org_iam/read_model.go deleted file mode 100644 index c271f9e73f..0000000000 --- a/internal/v2/repository/iam/policy/org_iam/read_model.go +++ /dev/null @@ -1,19 +0,0 @@ -package org_iam - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/org_iam" -) - -type ReadModel struct{ org_iam.ReadModel } - -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *org_iam.AddedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} diff --git a/internal/v2/repository/iam/policy/org_iam/write_model.go b/internal/v2/repository/iam/policy/org_iam/write_model.go deleted file mode 100644 index d29351898a..0000000000 --- a/internal/v2/repository/iam/policy/org_iam/write_model.go +++ /dev/null @@ -1,44 +0,0 @@ -package org_iam - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/org_iam" -) - -const ( - AggregateType = "iam" -) - -type WriteModel struct { - org_iam.WriteModel -} - -func NewWriteModel(iamID string) *WriteModel { - return &WriteModel{ - org_iam.WriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - }, - } -} - -func (wm *WriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - wm.WriteModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - wm.WriteModel.AppendEvents(&e.ChangedEvent) - } - } -} - -func (wm *WriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *WriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} diff --git a/internal/v2/repository/iam/policy/password_age/events.go b/internal/v2/repository/iam/policy/password_age/events.go deleted file mode 100644 index 166ecde756..0000000000 --- a/internal/v2/repository/iam/policy/password_age/events.go +++ /dev/null @@ -1,73 +0,0 @@ -package password_age - -import ( - "context" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/policy/password_age" -) - -var ( - iamEventPrefix = eventstore.EventType("iam.") - PasswordAgePolicyAddedEventType = iamEventPrefix + password_age.PasswordAgePolicyAddedEventType - PasswordAgePolicyChangedEventType = iamEventPrefix + password_age.PasswordAgePolicyChangedEventType -) - -type AddedEvent struct { - password_age.AddedEvent -} - -func NewAddedEvent( - ctx context.Context, - expireWarnDays, - maxAgeDays uint64, -) *AddedEvent { - return &AddedEvent{ - AddedEvent: *password_age.NewAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordAgePolicyAddedEventType), - expireWarnDays, - maxAgeDays), - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := password_age.AddedEventMapper(event) - if err != nil { - return nil, err - } - - return &AddedEvent{AddedEvent: *e.(*password_age.AddedEvent)}, nil -} - -type ChangedEvent struct { - password_age.ChangedEvent -} - -func ChangedEventFromExisting( - ctx context.Context, - current *WriteModel, - expireWarnDays, - maxAgeDays uint64, -) (*ChangedEvent, error) { - event := password_age.NewChangedEvent( - eventstore.NewBaseEventForPush( - ctx, - PasswordAgePolicyChangedEventType, - ), - ¤t.WriteModel, - expireWarnDays, - maxAgeDays, - ) - return &ChangedEvent{ - *event, - }, nil -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := password_age.ChangedEventMapper(event) - if err != nil { - return nil, err - } - - return &ChangedEvent{ChangedEvent: *e.(*password_age.ChangedEvent)}, nil -} diff --git a/internal/v2/repository/iam/policy/password_age/read_model.go b/internal/v2/repository/iam/policy/password_age/read_model.go deleted file mode 100644 index cd15f5badb..0000000000 --- a/internal/v2/repository/iam/policy/password_age/read_model.go +++ /dev/null @@ -1,25 +0,0 @@ -package password_age - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_age" -) - -type ReadModel struct { - password_age.ReadModel -} - -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *password_age.AddedEvent, - *password_age.ChangedEvent: - - rm.ReadModel.AppendEvents(e) - } - } -} diff --git a/internal/v2/repository/iam/policy/password_age/write_model.go b/internal/v2/repository/iam/policy/password_age/write_model.go deleted file mode 100644 index 30cc666593..0000000000 --- a/internal/v2/repository/iam/policy/password_age/write_model.go +++ /dev/null @@ -1,44 +0,0 @@ -package password_age - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_age" -) - -const ( - AggregateType = "iam" -) - -type WriteModel struct { - password_age.WriteModel -} - -func NewWriteModel(iamID string) *WriteModel { - return &WriteModel{ - password_age.WriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - }, - } -} - -func (wm *WriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - wm.WriteModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - wm.WriteModel.AppendEvents(&e.ChangedEvent) - } - } -} - -func (wm *WriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *WriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} diff --git a/internal/v2/repository/iam/policy/password_complexity/events.go b/internal/v2/repository/iam/policy/password_complexity/events.go deleted file mode 100644 index a8c8f1a894..0000000000 --- a/internal/v2/repository/iam/policy/password_complexity/events.go +++ /dev/null @@ -1,85 +0,0 @@ -package password_complexity - -import ( - "context" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/policy/password_complexity" -) - -const ( - iamEventPrefix = eventstore.EventType("iam.") - PasswordComplexityPolicyAddedEventType = iamEventPrefix + password_complexity.PasswordComplexityPolicyAddedEventType - PasswordComplexityPolicyChangedEventType = iamEventPrefix + password_complexity.PasswordComplexityPolicyChangedEventType -) - -type AddedEvent struct { - password_complexity.AddedEvent -} - -func NewAddedEvent( - ctx context.Context, - minLength uint64, - hasLowercase, - hasUppercase, - hasNumber, - hasSymbol bool, -) *AddedEvent { - return &AddedEvent{ - AddedEvent: *password_complexity.NewAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyAddedEventType), - minLength, - hasLowercase, - hasUppercase, - hasNumber, - hasSymbol), - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := password_complexity.AddedEventMapper(event) - if err != nil { - return nil, err - } - - return &AddedEvent{AddedEvent: *e.(*password_complexity.AddedEvent)}, nil -} - -type ChangedEvent struct { - password_complexity.ChangedEvent -} - -func ChangedEventFromExisting( - ctx context.Context, - current *WriteModel, - minLength uint64, - hasLowerCase, - hasUpperCase, - hasNumber, - hasSymbol bool, -) (*ChangedEvent, error) { - event := password_complexity.NewChangedEvent( - eventstore.NewBaseEventForPush( - ctx, - PasswordComplexityPolicyChangedEventType, - ), - ¤t.WriteModel, - minLength, - hasLowerCase, - hasUpperCase, - hasNumber, - hasSymbol, - ) - return &ChangedEvent{ - *event, - }, nil -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := password_complexity.ChangedEventMapper(event) - if err != nil { - return nil, err - } - - return &ChangedEvent{ChangedEvent: *e.(*password_complexity.ChangedEvent)}, nil -} diff --git a/internal/v2/repository/iam/policy/password_complexity/read_model.go b/internal/v2/repository/iam/policy/password_complexity/read_model.go deleted file mode 100644 index 54d1fb05ac..0000000000 --- a/internal/v2/repository/iam/policy/password_complexity/read_model.go +++ /dev/null @@ -1,25 +0,0 @@ -package password_complexity - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_complexity" -) - -type ReadModel struct { - password_complexity.ReadModel -} - -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *password_complexity.AddedEvent, - *password_complexity.ChangedEvent: - - rm.ReadModel.AppendEvents(e) - } - } -} diff --git a/internal/v2/repository/iam/policy/password_complexity/write_model.go b/internal/v2/repository/iam/policy/password_complexity/write_model.go deleted file mode 100644 index 0fd79ce499..0000000000 --- a/internal/v2/repository/iam/policy/password_complexity/write_model.go +++ /dev/null @@ -1,44 +0,0 @@ -package password_complexity - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_complexity" -) - -const ( - AggregateType = "iam" -) - -type WriteModel struct { - password_complexity.WriteModel -} - -func NewWriteModel(iamID string) *WriteModel { - return &WriteModel{ - password_complexity.WriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - }, - } -} - -func (wm *WriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - wm.WriteModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - wm.WriteModel.AppendEvents(&e.ChangedEvent) - } - } -} - -func (wm *WriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *WriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} diff --git a/internal/v2/repository/iam/policy/password_lockout/events.go b/internal/v2/repository/iam/policy/password_lockout/events.go deleted file mode 100644 index 68ebf15c39..0000000000 --- a/internal/v2/repository/iam/policy/password_lockout/events.go +++ /dev/null @@ -1,73 +0,0 @@ -package password_lockout - -import ( - "context" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/policy/password_lockout" -) - -var ( - iamEventPrefix = eventstore.EventType("iam.") - PasswordLockoutPolicyAddedEventType = iamEventPrefix + password_lockout.PasswordLockoutPolicyAddedEventType - PasswordLockoutPolicyChangedEventType = iamEventPrefix + password_lockout.PasswordLockoutPolicyChangedEventType -) - -type AddedEvent struct { - password_lockout.AddedEvent -} - -func NewAddedEvent( - ctx context.Context, - maxAttempts uint64, - showLockoutFailure bool, -) *AddedEvent { - return &AddedEvent{ - AddedEvent: *password_lockout.NewAddedEvent( - eventstore.NewBaseEventForPush(ctx, PasswordLockoutPolicyAddedEventType), - maxAttempts, - showLockoutFailure), - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := password_lockout.AddedEventMapper(event) - if err != nil { - return nil, err - } - - return &AddedEvent{AddedEvent: *e.(*password_lockout.AddedEvent)}, nil -} - -type ChangedEvent struct { - password_lockout.ChangedEvent -} - -func ChangedEventFromExisting( - ctx context.Context, - current *WriteModel, - maxAttempts uint64, - showLockoutFailure bool, -) (*ChangedEvent, error) { - event := password_lockout.NewChangedEvent( - eventstore.NewBaseEventForPush( - ctx, - PasswordLockoutPolicyChangedEventType, - ), - ¤t.WriteModel, - maxAttempts, - showLockoutFailure, - ) - return &ChangedEvent{ - *event, - }, nil -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := password_lockout.ChangedEventMapper(event) - if err != nil { - return nil, err - } - - return &ChangedEvent{ChangedEvent: *e.(*password_lockout.ChangedEvent)}, nil -} diff --git a/internal/v2/repository/iam/policy/password_lockout/read_model.go b/internal/v2/repository/iam/policy/password_lockout/read_model.go deleted file mode 100644 index 45cb29b635..0000000000 --- a/internal/v2/repository/iam/policy/password_lockout/read_model.go +++ /dev/null @@ -1,23 +0,0 @@ -package password_lockout - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_lockout" -) - -type ReadModel struct { - password_lockout.ReadModel -} - -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *password_lockout.AddedEvent, *password_lockout.ChangedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} diff --git a/internal/v2/repository/iam/policy/password_lockout/write_model.go b/internal/v2/repository/iam/policy/password_lockout/write_model.go deleted file mode 100644 index 3c9c7032b7..0000000000 --- a/internal/v2/repository/iam/policy/password_lockout/write_model.go +++ /dev/null @@ -1,44 +0,0 @@ -package password_lockout - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_lockout" -) - -const ( - AggregateType = "iam" -) - -type WriteModel struct { - password_lockout.WriteModel -} - -func NewWriteModel(iamID string) *WriteModel { - return &WriteModel{ - password_lockout.WriteModel{ - WriteModel: eventstore.WriteModel{ - AggregateID: iamID, - }, - }, - } -} - -func (wm *WriteModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *AddedEvent: - wm.WriteModel.AppendEvents(&e.AddedEvent) - case *ChangedEvent: - wm.WriteModel.AppendEvents(&e.ChangedEvent) - } - } -} - -func (wm *WriteModel) Reduce() error { - return wm.WriteModel.Reduce() -} - -func (wm *WriteModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType). - AggregateIDs(wm.WriteModel.AggregateID) -} diff --git a/internal/v2/repository/iam/policy_label.go b/internal/v2/repository/iam/policy_label.go new file mode 100644 index 0000000000..247e84fa98 --- /dev/null +++ b/internal/v2/repository/iam/policy_label.go @@ -0,0 +1,62 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + LabelPolicyAddedEventType = iamEventTypePrefix + policy.LabelPolicyAddedEventType + LabelPolicyChangedEventType = iamEventTypePrefix + policy.LabelPolicyChangedEventType +) + +type LabelPolicyAddedEvent struct { + policy.LabelPolicyAddedEvent +} + +func NewLabelPolicyAddedEvent( + ctx context.Context, + primaryColor, + secondaryColor string, +) *LabelPolicyAddedEvent { + return &LabelPolicyAddedEvent{ + LabelPolicyAddedEvent: *policy.NewLabelPolicyAddedEvent( + eventstore.NewBaseEventForPush(ctx, LabelPolicyAddedEventType), + primaryColor, + secondaryColor), + } +} + +func LabelPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.LabelPolicyAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &LabelPolicyAddedEvent{LabelPolicyAddedEvent: *e.(*policy.LabelPolicyAddedEvent)}, nil +} + +type LabelPolicyChangedEvent struct { + policy.LabelPolicyChangedEvent +} + +func NewLabelPolicyChangedEvent( + ctx context.Context, +) *LabelPolicyChangedEvent { + return &LabelPolicyChangedEvent{ + LabelPolicyChangedEvent: *policy.NewLabelPolicyChangedEvent( + eventstore.NewBaseEventForPush(ctx, LabelPolicyChangedEventType), + ), + } +} + +func LabelPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.LabelPolicyChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &LabelPolicyChangedEvent{LabelPolicyChangedEvent: *e.(*policy.LabelPolicyChangedEvent)}, nil +} diff --git a/internal/v2/repository/iam/policy_login.go b/internal/v2/repository/iam/policy_login.go new file mode 100644 index 0000000000..549becf254 --- /dev/null +++ b/internal/v2/repository/iam/policy_login.go @@ -0,0 +1,69 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + LoginPolicyAddedEventType = iamEventTypePrefix + policy.LoginPolicyAddedEventType + LoginPolicyChangedEventType = iamEventTypePrefix + policy.LoginPolicyChangedEventType +) + +type LoginPolicyAddedEvent struct { + policy.LoginPolicyAddedEvent +} + +func NewLoginPolicyAddedEvent( + ctx context.Context, + allowUsernamePassword, + allowRegister, + allowExternalIDP, + forceMFA bool, + passwordlessType domain.PasswordlessType, +) *LoginPolicyAddedEvent { + return &LoginPolicyAddedEvent{ + LoginPolicyAddedEvent: *policy.NewLoginPolicyAddedEvent( + eventstore.NewBaseEventForPush(ctx, LoginPolicyAddedEventType), + allowUsernamePassword, + allowRegister, + allowExternalIDP, + forceMFA, + passwordlessType), + } +} + +func LoginPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.LoginPolicyAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &LoginPolicyAddedEvent{LoginPolicyAddedEvent: *e.(*policy.LoginPolicyAddedEvent)}, nil +} + +type LoginPolicyChangedEvent struct { + policy.LoginPolicyChangedEvent +} + +func NewLoginPolicyChangedEvent( + ctx context.Context, +) *LoginPolicyChangedEvent { + return &LoginPolicyChangedEvent{ + LoginPolicyChangedEvent: *policy.NewLoginPolicyChangedEvent( + eventstore.NewBaseEventForPush(ctx, LoginPolicyChangedEventType), + ), + } +} + +func LoginPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.LoginPolicyChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &LoginPolicyChangedEvent{LoginPolicyChangedEvent: *e.(*policy.LoginPolicyChangedEvent)}, nil +} diff --git a/internal/v2/repository/iam/policy/login/factors/events.go b/internal/v2/repository/iam/policy_login_factors.go similarity index 57% rename from internal/v2/repository/iam/policy/login/factors/events.go rename to internal/v2/repository/iam/policy_login_factors.go index 9aa0431f19..93f1336673 100644 --- a/internal/v2/repository/iam/policy/login/factors/events.go +++ b/internal/v2/repository/iam/policy_login_factors.go @@ -1,123 +1,123 @@ -package factors +package iam import ( "context" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/policy/login/factors" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" ) var ( - iamEventPrefix = eventstore.EventType("iam.") - LoginPolicySecondFactorAddedEventType = iamEventPrefix + factors.LoginPolicySecondFactorAddedEventType - LoginPolicySecondFactorRemovedEventType = iamEventPrefix + factors.LoginPolicySecondFactorRemovedEventType + LoginPolicySecondFactorAddedEventType = iamEventTypePrefix + policy.LoginPolicySecondFactorAddedEventType + LoginPolicySecondFactorRemovedEventType = iamEventTypePrefix + policy.LoginPolicySecondFactorRemovedEventType - LoginPolicyMultiFactorAddedEventType = iamEventPrefix + factors.LoginPolicyMultiFactorAddedEventType - LoginPolicyMultiFactorRemovedEventType = iamEventPrefix + factors.LoginPolicyMultiFactorRemovedEventType + LoginPolicyMultiFactorAddedEventType = iamEventTypePrefix + policy.LoginPolicyMultiFactorAddedEventType + LoginPolicyMultiFactorRemovedEventType = iamEventTypePrefix + policy.LoginPolicyMultiFactorRemovedEventType ) type LoginPolicySecondFactorAddedEvent struct { - factors.SecondFactorAddedEvent + policy.SecondFactorAddedEvent } func NewLoginPolicySecondFactorAddedEvent( ctx context.Context, - mfaType factors.SecondFactorType, + mfaType domain.SecondFactorType, ) *LoginPolicySecondFactorAddedEvent { return &LoginPolicySecondFactorAddedEvent{ - SecondFactorAddedEvent: *factors.NewSecondFactorAddedEvent( + SecondFactorAddedEvent: *policy.NewSecondFactorAddedEvent( eventstore.NewBaseEventForPush(ctx, LoginPolicySecondFactorAddedEventType), mfaType), } } func SecondFactorAddedEventEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := factors.SecondFactorAddedEventMapper(event) + e, err := policy.SecondFactorAddedEventMapper(event) if err != nil { return nil, err } return &LoginPolicySecondFactorAddedEvent{ - SecondFactorAddedEvent: *e.(*factors.SecondFactorAddedEvent), + SecondFactorAddedEvent: *e.(*policy.SecondFactorAddedEvent), }, nil } type LoginPolicySecondFactorRemovedEvent struct { - factors.SecondFactorRemovedEvent + policy.SecondFactorRemovedEvent } func NewLoginPolicySecondFactorRemovedEvent( ctx context.Context, - mfaType factors.SecondFactorType, + mfaType domain.SecondFactorType, ) *LoginPolicySecondFactorRemovedEvent { return &LoginPolicySecondFactorRemovedEvent{ - SecondFactorRemovedEvent: *factors.NewSecondFactorRemovedEvent( + SecondFactorRemovedEvent: *policy.NewSecondFactorRemovedEvent( eventstore.NewBaseEventForPush(ctx, LoginPolicySecondFactorRemovedEventType), mfaType), } } func SecondFactorRemovedEventEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := factors.SecondFactorRemovedEventMapper(event) + e, err := policy.SecondFactorRemovedEventMapper(event) if err != nil { return nil, err } return &LoginPolicySecondFactorRemovedEvent{ - SecondFactorRemovedEvent: *e.(*factors.SecondFactorRemovedEvent), + SecondFactorRemovedEvent: *e.(*policy.SecondFactorRemovedEvent), }, nil } type LoginPolicyMultiFactorAddedEvent struct { - factors.MultiFactorAddedEvent + policy.MultiFactorAddedEvent } func NewLoginPolicyMultiFactorAddedEvent( ctx context.Context, - mfaType factors.MultiFactorType, + mfaType domain.MultiFactorType, ) *LoginPolicyMultiFactorAddedEvent { return &LoginPolicyMultiFactorAddedEvent{ - MultiFactorAddedEvent: *factors.NewMultiFactorAddedEvent( + MultiFactorAddedEvent: *policy.NewMultiFactorAddedEvent( eventstore.NewBaseEventForPush(ctx, LoginPolicyMultiFactorAddedEventType), mfaType), } } func MultiFactorAddedEventEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := factors.MultiFactorAddedEventMapper(event) + e, err := policy.MultiFactorAddedEventMapper(event) if err != nil { return nil, err } return &LoginPolicyMultiFactorAddedEvent{ - MultiFactorAddedEvent: *e.(*factors.MultiFactorAddedEvent), + MultiFactorAddedEvent: *e.(*policy.MultiFactorAddedEvent), }, nil } type LoginPolicyMultiFactorRemovedEvent struct { - factors.MultiFactorRemovedEvent + policy.MultiFactorRemovedEvent } func NewLoginPolicyMultiFactorRemovedEvent( ctx context.Context, - mfaType factors.MultiFactorType, + mfaType domain.MultiFactorType, ) *LoginPolicyMultiFactorRemovedEvent { return &LoginPolicyMultiFactorRemovedEvent{ - MultiFactorRemovedEvent: *factors.NewMultiFactorRemovedEvent( + MultiFactorRemovedEvent: *policy.NewMultiFactorRemovedEvent( eventstore.NewBaseEventForPush(ctx, LoginPolicyMultiFactorRemovedEventType), mfaType), } } func MultiFactorRemovedEventEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e, err := factors.MultiFactorRemovedEventMapper(event) + e, err := policy.MultiFactorRemovedEventMapper(event) if err != nil { return nil, err } return &LoginPolicyMultiFactorRemovedEvent{ - MultiFactorRemovedEvent: *e.(*factors.MultiFactorRemovedEvent), + MultiFactorRemovedEvent: *e.(*policy.MultiFactorRemovedEvent), }, nil } diff --git a/internal/v2/repository/iam/policy_login_identity_provider.go b/internal/v2/repository/iam/policy_login_identity_provider.go new file mode 100644 index 0000000000..68004e539f --- /dev/null +++ b/internal/v2/repository/iam/policy_login_identity_provider.go @@ -0,0 +1,69 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + LoginPolicyIDPProviderAddedEventType = iamEventTypePrefix + policy.LoginPolicyIDPProviderAddedType + LoginPolicyIDPProviderRemovedEventType = iamEventTypePrefix + policy.LoginPolicyIDPProviderRemovedType +) + +type IdentityProviderAddedEvent struct { + policy.IdentityProviderAddedEvent +} + +func NewIdentityProviderAddedEvent( + ctx context.Context, + idpConfigID string, + idpProviderType domain.IdentityProviderType, +) *IdentityProviderAddedEvent { + + return &IdentityProviderAddedEvent{ + IdentityProviderAddedEvent: *policy.NewIdentityProviderAddedEvent( + eventstore.NewBaseEventForPush(ctx, LoginPolicyIDPProviderAddedEventType), + idpConfigID, + idpProviderType), + } +} + +func IdentityProviderAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.IdentityProviderAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &IdentityProviderAddedEvent{ + IdentityProviderAddedEvent: *e.(*policy.IdentityProviderAddedEvent), + }, nil +} + +type IdentityProviderRemovedEvent struct { + policy.IdentityProviderRemovedEvent +} + +func NewIdentityProviderRemovedEvent( + ctx context.Context, + idpConfigID string, +) *IdentityProviderRemovedEvent { + return &IdentityProviderRemovedEvent{ + IdentityProviderRemovedEvent: *policy.NewIdentityProviderRemovedEvent( + eventstore.NewBaseEventForPush(ctx, LoginPolicyIDPProviderRemovedEventType), + idpConfigID), + } +} + +func IdentityProviderRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.IdentityProviderRemovedEventMapper(event) + if err != nil { + return nil, err + } + + return &IdentityProviderRemovedEvent{ + IdentityProviderRemovedEvent: *e.(*policy.IdentityProviderRemovedEvent), + }, nil +} diff --git a/internal/v2/repository/iam/policy_org_iam.go b/internal/v2/repository/iam/policy_org_iam.go new file mode 100644 index 0000000000..d7a3e8f1fc --- /dev/null +++ b/internal/v2/repository/iam/policy_org_iam.go @@ -0,0 +1,61 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + OrgIAMPolicyAddedEventType = iamEventTypePrefix + policy.OrgIAMPolicyAddedEventType + OrgIAMPolicyChangedEventType = iamEventTypePrefix + policy.OrgIAMPolicyChangedEventType +) + +type OrgIAMPolicyAddedEvent struct { + policy.OrgIAMPolicyAddedEvent +} + +func NewOrgIAMPolicyAddedEvent( + ctx context.Context, + userLoginMustBeDomain bool, +) *OrgIAMPolicyAddedEvent { + return &OrgIAMPolicyAddedEvent{ + OrgIAMPolicyAddedEvent: *policy.NewOrgIAMPolicyAddedEvent( + eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyAddedEventType), + userLoginMustBeDomain, + ), + } +} + +func OrgIAMPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.OrgIAMPolicyAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &OrgIAMPolicyAddedEvent{OrgIAMPolicyAddedEvent: *e.(*policy.OrgIAMPolicyAddedEvent)}, nil +} + +type OrgIAMPolicyChangedEvent struct { + policy.OrgIAMPolicyChangedEvent +} + +func NewOrgIAMPolicyChangedEvent( + ctx context.Context, +) *OrgIAMPolicyChangedEvent { + return &OrgIAMPolicyChangedEvent{ + OrgIAMPolicyChangedEvent: *policy.NewOrgIAMPolicyChangedEvent( + eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyChangedEventType), + ), + } +} + +func OrgIAMPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.OrgIAMPolicyChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &OrgIAMPolicyChangedEvent{OrgIAMPolicyChangedEvent: *e.(*policy.OrgIAMPolicyChangedEvent)}, nil +} diff --git a/internal/v2/repository/iam/policy_password_age.go b/internal/v2/repository/iam/policy_password_age.go new file mode 100644 index 0000000000..a0fd537d2a --- /dev/null +++ b/internal/v2/repository/iam/policy_password_age.go @@ -0,0 +1,62 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + PasswordAgePolicyAddedEventType = iamEventTypePrefix + policy.PasswordAgePolicyAddedEventType + PasswordAgePolicyChangedEventType = iamEventTypePrefix + policy.PasswordAgePolicyChangedEventType +) + +type PasswordAgePolicyAddedEvent struct { + policy.PasswordAgePolicyAddedEvent +} + +func NewPasswordAgePolicyAddedEvent( + ctx context.Context, + expireWarnDays, + maxAgeDays uint64, +) *PasswordAgePolicyAddedEvent { + return &PasswordAgePolicyAddedEvent{ + PasswordAgePolicyAddedEvent: *policy.NewPasswordAgePolicyAddedEvent( + eventstore.NewBaseEventForPush(ctx, PasswordAgePolicyAddedEventType), + expireWarnDays, + maxAgeDays), + } +} + +func PasswordAgePolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.PasswordAgePolicyAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &PasswordAgePolicyAddedEvent{PasswordAgePolicyAddedEvent: *e.(*policy.PasswordAgePolicyAddedEvent)}, nil +} + +type PasswordAgePolicyChangedEvent struct { + policy.PasswordAgePolicyChangedEvent +} + +func NewPasswordAgePolicyChangedEvent( + ctx context.Context, +) *PasswordAgePolicyChangedEvent { + return &PasswordAgePolicyChangedEvent{ + PasswordAgePolicyChangedEvent: *policy.NewPasswordAgePolicyChangedEvent( + eventstore.NewBaseEventForPush(ctx, PasswordAgePolicyChangedEventType), + ), + } +} + +func PasswordAgePolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.PasswordAgePolicyChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &PasswordAgePolicyChangedEvent{PasswordAgePolicyChangedEvent: *e.(*policy.PasswordAgePolicyChangedEvent)}, nil +} diff --git a/internal/v2/repository/iam/policy_password_complexity.go b/internal/v2/repository/iam/policy_password_complexity.go new file mode 100644 index 0000000000..571c88af3f --- /dev/null +++ b/internal/v2/repository/iam/policy_password_complexity.go @@ -0,0 +1,68 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +const ( + PasswordComplexityPolicyAddedEventType = iamEventTypePrefix + policy.PasswordComplexityPolicyAddedEventType + PasswordComplexityPolicyChangedEventType = iamEventTypePrefix + policy.PasswordComplexityPolicyChangedEventType +) + +type PasswordComplexityPolicyAddedEvent struct { + policy.PasswordComplexityPolicyAddedEvent +} + +func NewPasswordComplexityPolicyAddedEvent( + ctx context.Context, + minLength uint64, + hasLowercase, + hasUppercase, + hasNumber, + hasSymbol bool, +) *PasswordComplexityPolicyAddedEvent { + return &PasswordComplexityPolicyAddedEvent{ + PasswordComplexityPolicyAddedEvent: *policy.NewPasswordComplexityPolicyAddedEvent( + eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyAddedEventType), + minLength, + hasLowercase, + hasUppercase, + hasNumber, + hasSymbol), + } +} + +func PasswordComplexityPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.PasswordComplexityPolicyAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &PasswordComplexityPolicyAddedEvent{PasswordComplexityPolicyAddedEvent: *e.(*policy.PasswordComplexityPolicyAddedEvent)}, nil +} + +type PasswordComplexityPolicyChangedEvent struct { + policy.PasswordComplexityPolicyChangedEvent +} + +func NewPasswordComplexityPolicyChangedEvent( + ctx context.Context, +) *PasswordComplexityPolicyChangedEvent { + return &PasswordComplexityPolicyChangedEvent{ + PasswordComplexityPolicyChangedEvent: *policy.NewPasswordComplexityPolicyChangedEvent( + eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyAddedEventType), + ), + } +} + +func PasswordComplexityPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.PasswordComplexityPolicyChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &PasswordComplexityPolicyChangedEvent{PasswordComplexityPolicyChangedEvent: *e.(*policy.PasswordComplexityPolicyChangedEvent)}, nil +} diff --git a/internal/v2/repository/iam/policy_password_lockout.go b/internal/v2/repository/iam/policy_password_lockout.go new file mode 100644 index 0000000000..3caf3d449e --- /dev/null +++ b/internal/v2/repository/iam/policy_password_lockout.go @@ -0,0 +1,62 @@ +package iam + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + PasswordLockoutPolicyAddedEventType = iamEventTypePrefix + policy.PasswordLockoutPolicyAddedEventType + PasswordLockoutPolicyChangedEventType = iamEventTypePrefix + policy.PasswordLockoutPolicyChangedEventType +) + +type PasswordLockoutPolicyAddedEvent struct { + policy.PasswordLockoutPolicyAddedEvent +} + +func NewPasswordLockoutPolicyAddedEvent( + ctx context.Context, + maxAttempts uint64, + showLockoutFailure bool, +) *PasswordLockoutPolicyAddedEvent { + return &PasswordLockoutPolicyAddedEvent{ + PasswordLockoutPolicyAddedEvent: *policy.NewPasswordLockoutPolicyAddedEvent( + eventstore.NewBaseEventForPush(ctx, PasswordLockoutPolicyAddedEventType), + maxAttempts, + showLockoutFailure), + } +} + +func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.PasswordLockoutPolicyAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &PasswordLockoutPolicyAddedEvent{PasswordLockoutPolicyAddedEvent: *e.(*policy.PasswordLockoutPolicyAddedEvent)}, nil +} + +type PasswordLockoutPolicyChangedEvent struct { + policy.PasswordLockoutPolicyChangedEvent +} + +func NewPasswordLockoutPolicyChangedEvent( + ctx context.Context, +) *PasswordLockoutPolicyChangedEvent { + return &PasswordLockoutPolicyChangedEvent{ + PasswordLockoutPolicyChangedEvent: *policy.NewPasswordLockoutPolicyChangedEvent( + eventstore.NewBaseEventForPush(ctx, PasswordLockoutPolicyChangedEventType), + ), + } +} + +func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.PasswordLockoutPolicyChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &PasswordLockoutPolicyChangedEvent{PasswordLockoutPolicyChangedEvent: *e.(*policy.PasswordLockoutPolicyChangedEvent)}, nil +} diff --git a/internal/v2/repository/iam/read_model.go b/internal/v2/repository/iam/read_model.go deleted file mode 100644 index 62d55a8495..0000000000 --- a/internal/v2/repository/iam/read_model.go +++ /dev/null @@ -1,141 +0,0 @@ -package iam - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - iam_label "github.com/caos/zitadel/internal/v2/repository/iam/policy/label" - iam_login "github.com/caos/zitadel/internal/v2/repository/iam/policy/login" - iam_org_iam "github.com/caos/zitadel/internal/v2/repository/iam/policy/org_iam" - iam_password_age "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_age" - iam_password_complexity "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_complexity" - iam_password_lockout "github.com/caos/zitadel/internal/v2/repository/iam/policy/password_lockout" - "github.com/caos/zitadel/internal/v2/repository/member" - "github.com/caos/zitadel/internal/v2/repository/policy/label" - "github.com/caos/zitadel/internal/v2/repository/policy/login" - "github.com/caos/zitadel/internal/v2/repository/policy/org_iam" - "github.com/caos/zitadel/internal/v2/repository/policy/password_age" - "github.com/caos/zitadel/internal/v2/repository/policy/password_complexity" - "github.com/caos/zitadel/internal/v2/repository/policy/password_lockout" -) - -type ReadModel struct { - eventstore.ReadModel - - SetUpStarted Step - SetUpDone Step - - Members MembersReadModel - IDPs IDPConfigsReadModel - - GlobalOrgID string - ProjectID string - - DefaultLoginPolicy iam_login.ReadModel - DefaultLabelPolicy iam_label.ReadModel - DefaultOrgIAMPolicy iam_org_iam.ReadModel - DefaultPasswordComplexityPolicy iam_password_complexity.ReadModel - DefaultPasswordAgePolicy iam_password_age.ReadModel - DefaultPasswordLockoutPolicy iam_password_lockout.ReadModel -} - -func NewReadModel(id string) *ReadModel { - return &ReadModel{ - ReadModel: eventstore.ReadModel{ - AggregateID: id, - }, - } -} - -func (rm *ReadModel) IDPByID(idpID string) *IDPConfigReadModel { - _, config := rm.IDPs.ConfigByID(idpID) - if config == nil { - return nil - } - return &IDPConfigReadModel{ConfigReadModel: *config} -} - -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { - rm.ReadModel.AppendEvents(events...) - for _, event := range events { - switch event.(type) { - case *member.AddedEvent, - *member.ChangedEvent, - *member.RemovedEvent: - - rm.Members.AppendEvents(event) - case *IDPConfigAddedEvent, - *IDPConfigChangedEvent, - *IDPConfigDeactivatedEvent, - *IDPConfigReactivatedEvent, - *IDPConfigRemovedEvent, - *IDPOIDCConfigAddedEvent, - *IDPOIDCConfigChangedEvent: - - rm.IDPs.AppendEvents(event) - case *label.AddedEvent, - *label.ChangedEvent: - - rm.DefaultLabelPolicy.AppendEvents(event) - case *login.AddedEvent, - *login.ChangedEvent: - - rm.DefaultLoginPolicy.AppendEvents(event) - case *org_iam.AddedEvent: - rm.DefaultOrgIAMPolicy.AppendEvents(event) - case *password_complexity.AddedEvent, - *password_complexity.ChangedEvent: - - rm.DefaultPasswordComplexityPolicy.AppendEvents(event) - case *password_age.AddedEvent, - *password_age.ChangedEvent: - - rm.DefaultPasswordAgePolicy.AppendEvents(event) - case *password_lockout.AddedEvent, - *password_lockout.ChangedEvent: - - rm.DefaultPasswordLockoutPolicy.AppendEvents(event) - } - } -} - -func (rm *ReadModel) Reduce() (err error) { - for _, event := range rm.Events { - switch e := event.(type) { - case *ProjectSetEvent: - rm.ProjectID = e.ProjectID - case *GlobalOrgSetEvent: - rm.GlobalOrgID = e.OrgID - case *SetupStepEvent: - if e.Done { - rm.SetUpDone = e.Step - } else { - rm.SetUpStarted = e.Step - } - } - } - for _, reduce := range []func() error{ - rm.Members.Reduce, - rm.IDPs.Reduce, - rm.DefaultLoginPolicy.Reduce, - rm.DefaultLabelPolicy.Reduce, - rm.DefaultOrgIAMPolicy.Reduce, - rm.DefaultPasswordComplexityPolicy.Reduce, - rm.DefaultPasswordAgePolicy.Reduce, - rm.DefaultPasswordLockoutPolicy.Reduce, - rm.ReadModel.Reduce, - } { - if err = reduce(); err != nil { - return err - } - } - - return nil -} - -func (rm *ReadModel) AppendAndReduce(events ...eventstore.EventReader) error { - rm.AppendEvents(events...) - return rm.Reduce() -} - -func (rm *ReadModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType).AggregateIDs(rm.AggregateID) -} diff --git a/internal/v2/repository/idp/config.go b/internal/v2/repository/idp/config.go deleted file mode 100644 index 53814f2c77..0000000000 --- a/internal/v2/repository/idp/config.go +++ /dev/null @@ -1,49 +0,0 @@ -package idp - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" -) - -type ConfigAggregate struct { - eventstore.Aggregate -} - -type ConfigType int32 - -const ( - ConfigTypeOIDC ConfigType = iota - ConfigTypeSAML - - //count is for validation - configTypeCount -) - -func (f ConfigType) Valid() bool { - return f >= 0 && f < configTypeCount -} - -type ConfigState int32 - -const ( - ConfigStateActive ConfigState = iota - ConfigStateInactive - ConfigStateRemoved - - configStateCount -) - -func (f ConfigState) Valid() bool { - return f >= 0 && f < configStateCount -} - -type StylingType int32 - -const ( - StylingTypeGoogle StylingType = iota + 1 - - stylingTypeCount -) - -func (f StylingType) Valid() bool { - return f >= 0 && f < stylingTypeCount -} diff --git a/internal/v2/repository/idp/config_read_model.go b/internal/v2/repository/idp/config_read_model.go deleted file mode 100644 index f1ddd19a96..0000000000 --- a/internal/v2/repository/idp/config_read_model.go +++ /dev/null @@ -1,93 +0,0 @@ -package idp - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/idp/oidc" - "github.com/caos/zitadel/internal/v2/repository/policy/login/idpprovider" -) - -type ConfigReadModel struct { - eventstore.ReadModel - - State ConfigState - ConfigID string - Name string - StylingType StylingType - ProviderType idpprovider.Type - - OIDCConfig *oidc.ConfigReadModel -} - -func NewConfigReadModel(configID string) *ConfigReadModel { - return &ConfigReadModel{ - ConfigID: configID, - } -} - -func (rm *ConfigReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *ConfigAddedEvent: - rm.ReadModel.AppendEvents(e) - case *ConfigChangedEvent: - rm.ReadModel.AppendEvents(e) - case *ConfigDeactivatedEvent: - rm.ReadModel.AppendEvents(e) - case *ConfigReactivatedEvent: - rm.ReadModel.AppendEvents(e) - case *ConfigRemovedEvent: - rm.ReadModel.AppendEvents(e) - case *oidc.ConfigAddedEvent: - rm.OIDCConfig = &oidc.ConfigReadModel{} - rm.ReadModel.AppendEvents(e) - rm.OIDCConfig.AppendEvents(event) - case *oidc.ConfigChangedEvent: - rm.ReadModel.AppendEvents(e) - rm.OIDCConfig.AppendEvents(event) - } - } -} - -func (rm *ConfigReadModel) Reduce() error { - for _, event := range rm.Events { - switch e := event.(type) { - case *ConfigAddedEvent: - rm.reduceConfigAddedEvent(e) - case *ConfigChangedEvent: - rm.reduceConfigChangedEvent(e) - case *ConfigDeactivatedEvent: - rm.reduceConfigStateChanged(e.ConfigID, ConfigStateInactive) - case *ConfigReactivatedEvent: - rm.reduceConfigStateChanged(e.ConfigID, ConfigStateActive) - case *ConfigRemovedEvent: - rm.reduceConfigStateChanged(e.ConfigID, ConfigStateRemoved) - } - } - - if rm.OIDCConfig != nil { - if err := rm.OIDCConfig.Reduce(); err != nil { - return err - } - } - return rm.ReadModel.Reduce() -} - -func (rm *ConfigReadModel) reduceConfigAddedEvent(e *ConfigAddedEvent) { - rm.ConfigID = e.ConfigID - rm.Name = e.Name - rm.StylingType = e.StylingType - rm.State = ConfigStateActive -} - -func (rm *ConfigReadModel) reduceConfigChangedEvent(e *ConfigChangedEvent) { - if e.Name != "" { - rm.Name = e.Name - } - if e.StylingType.Valid() { - rm.StylingType = e.StylingType - } -} - -func (rm *ConfigReadModel) reduceConfigStateChanged(configID string, state ConfigState) { - rm.State = state -} diff --git a/internal/v2/repository/idp/config_write_model.go b/internal/v2/repository/idp/config_write_model.go deleted file mode 100644 index d04f68550b..0000000000 --- a/internal/v2/repository/idp/config_write_model.go +++ /dev/null @@ -1,74 +0,0 @@ -package idp - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/idp/oidc" -) - -type ConfigWriteModel struct { - eventstore.WriteModel - - State ConfigState - - ConfigID string - Name string - StylingType StylingType - - OIDCConfig *oidc.ConfigWriteModel -} - -func (rm *ConfigWriteModel) AppendEvents(events ...eventstore.EventReader) { - rm.WriteModel.AppendEvents(events...) - for _, event := range events { - switch event.(type) { - case *oidc.ConfigAddedEvent: - rm.OIDCConfig = new(oidc.ConfigWriteModel) - rm.OIDCConfig.AppendEvents(event) - case *oidc.ConfigChangedEvent: - rm.OIDCConfig.AppendEvents(event) - } - } -} - -func (rm *ConfigWriteModel) Reduce() error { - for _, event := range rm.Events { - switch e := event.(type) { - case *ConfigAddedEvent: - rm.reduceConfigAddedEvent(e) - case *ConfigChangedEvent: - rm.reduceConfigChangedEvent(e) - case *ConfigDeactivatedEvent: - rm.reduceConfigStateChanged(e.ConfigID, ConfigStateInactive) - case *ConfigReactivatedEvent: - rm.reduceConfigStateChanged(e.ConfigID, ConfigStateActive) - case *ConfigRemovedEvent: - rm.reduceConfigStateChanged(e.ConfigID, ConfigStateRemoved) - } - } - if rm.OIDCConfig != nil { - if err := rm.OIDCConfig.Reduce(); err != nil { - return err - } - } - return rm.WriteModel.Reduce() -} - -func (rm *ConfigWriteModel) reduceConfigAddedEvent(e *ConfigAddedEvent) { - rm.ConfigID = e.ConfigID - rm.Name = e.Name - rm.StylingType = e.StylingType - rm.State = ConfigStateActive -} - -func (rm *ConfigWriteModel) reduceConfigChangedEvent(e *ConfigChangedEvent) { - if e.Name != "" { - rm.Name = e.Name - } - if e.StylingType.Valid() { - rm.StylingType = e.StylingType - } -} - -func (rm *ConfigWriteModel) reduceConfigStateChanged(configID string, state ConfigState) { - rm.State = state -} diff --git a/internal/v2/repository/idp/event_config_added.go b/internal/v2/repository/idp/event_config_added.go deleted file mode 100644 index 039150367d..0000000000 --- a/internal/v2/repository/idp/event_config_added.go +++ /dev/null @@ -1,52 +0,0 @@ -package idp - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -type ConfigAddedEvent struct { - eventstore.BaseEvent `json:"-"` - - ConfigID string `json:"idpConfigId"` - Name string `json:"name,omitempty"` - Typ ConfigType `json:"idpType,omitempty"` - StylingType StylingType `json:"stylingType,omitempty"` -} - -func NewConfigAddedEvent( - base *eventstore.BaseEvent, - configID string, - name string, - configType ConfigType, - stylingType StylingType, -) *ConfigAddedEvent { - - return &ConfigAddedEvent{ - BaseEvent: *base, - ConfigID: configID, - Name: name, - StylingType: stylingType, - Typ: configType, - } -} - -func (e *ConfigAddedEvent) Data() interface{} { - return e -} - -func ConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ConfigAddedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") - } - - return e, nil -} diff --git a/internal/v2/repository/idp/event_config_changed.go b/internal/v2/repository/idp/event_config_changed.go deleted file mode 100644 index 5f70922f95..0000000000 --- a/internal/v2/repository/idp/event_config_changed.go +++ /dev/null @@ -1,63 +0,0 @@ -package idp - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -type ConfigChangedEvent struct { - eventstore.BaseEvent `json:"-"` - - ConfigID string `json:"idpConfigId"` - Name string `json:"name,omitempty"` - StylingType StylingType `json:"stylingType,omitempty"` -} - -func NewConfigChangedEvent( - base *eventstore.BaseEvent, - current *ConfigWriteModel, - name string, - stylingType StylingType, -) (*ConfigChangedEvent, error) { - - change := &ConfigChangedEvent{ - BaseEvent: *base, - ConfigID: current.ConfigID, - } - hasChanged := false - - if current.Name != name { - change.Name = name - hasChanged = true - } - if stylingType != current.StylingType { - change.StylingType = stylingType - hasChanged = true - } - - if !hasChanged { - return nil, errors.ThrowPreconditionFailed(nil, "IDP-UBJbB", "Errors.NoChanges") - } - - return change, nil -} - -func (e *ConfigChangedEvent) Data() interface{} { - return e -} - -func ConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ConfigChangedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") - } - - return e, nil -} diff --git a/internal/v2/repository/idp/event_config_deactivated.go b/internal/v2/repository/idp/event_config_deactivated.go deleted file mode 100644 index 5649b5adc1..0000000000 --- a/internal/v2/repository/idp/event_config_deactivated.go +++ /dev/null @@ -1,43 +0,0 @@ -package idp - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -type ConfigDeactivatedEvent struct { - eventstore.BaseEvent `json:"-"` - - ConfigID string `idpConfigId` -} - -func NewConfigDeactivatedEvent( - base *eventstore.BaseEvent, - configID string, -) *ConfigDeactivatedEvent { - - return &ConfigDeactivatedEvent{ - BaseEvent: *base, - ConfigID: configID, - } -} - -func (e *ConfigDeactivatedEvent) Data() interface{} { - return e -} - -func ConfigDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ConfigDeactivatedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") - } - - return e, nil -} diff --git a/internal/v2/repository/idp/event_config_reactivated.go b/internal/v2/repository/idp/event_config_reactivated.go deleted file mode 100644 index b309efde6e..0000000000 --- a/internal/v2/repository/idp/event_config_reactivated.go +++ /dev/null @@ -1,43 +0,0 @@ -package idp - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -type ConfigReactivatedEvent struct { - eventstore.BaseEvent `json:"-"` - - ConfigID string `idpConfigId` -} - -func NewConfigReactivatedEvent( - base *eventstore.BaseEvent, - configID string, -) *ConfigReactivatedEvent { - - return &ConfigReactivatedEvent{ - BaseEvent: *base, - ConfigID: configID, - } -} - -func (e *ConfigReactivatedEvent) Data() interface{} { - return e -} - -func ConfigReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ConfigReactivatedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") - } - - return e, nil -} diff --git a/internal/v2/repository/idp/event_config_removed.go b/internal/v2/repository/idp/event_config_removed.go deleted file mode 100644 index 76936e247e..0000000000 --- a/internal/v2/repository/idp/event_config_removed.go +++ /dev/null @@ -1,43 +0,0 @@ -package idp - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -type ConfigRemovedEvent struct { - eventstore.BaseEvent `json:"-"` - - ConfigID string `idpConfigId` -} - -func NewConfigRemovedEvent( - base *eventstore.BaseEvent, - configID string, -) *ConfigRemovedEvent { - - return &ConfigRemovedEvent{ - BaseEvent: *base, - ConfigID: configID, - } -} - -func (e *ConfigRemovedEvent) Data() interface{} { - return e -} - -func ConfigRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ConfigRemovedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") - } - - return e, nil -} diff --git a/internal/v2/repository/idp/oidc/event_added.go b/internal/v2/repository/idp/oidc/event_added.go deleted file mode 100644 index 99ef28736e..0000000000 --- a/internal/v2/repository/idp/oidc/event_added.go +++ /dev/null @@ -1,67 +0,0 @@ -package oidc - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -const ( - ConfigAddedEventType eventstore.EventType = "oidc.config.added" -) - -type ConfigAddedEvent struct { - eventstore.BaseEvent - - IDPConfigID string `json:"idpConfigId"` - ClientID string `json:"clientId,omitempty"` - ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"` - Issuer string `json:"issuer,omitempty"` - Scopes []string `json:"scpoes,omitempty"` - - IDPDisplayNameMapping MappingField `json:"idpDisplayNameMapping,omitempty"` - UserNameMapping MappingField `json:"usernameMapping,omitempty"` -} - -func (e *ConfigAddedEvent) Data() interface{} { - return e -} - -func NewConfigAddedEvent( - base *eventstore.BaseEvent, - clientID, - idpConfigID, - issuer string, - clientSecret *crypto.CryptoValue, - idpDisplayNameMapping, - userNameMapping MappingField, - scopes ...string, -) *ConfigAddedEvent { - - return &ConfigAddedEvent{ - BaseEvent: *base, - IDPConfigID: idpConfigID, - ClientID: clientID, - ClientSecret: clientSecret, - Issuer: issuer, - Scopes: scopes, - IDPDisplayNameMapping: idpDisplayNameMapping, - UserNameMapping: userNameMapping, - } -} - -func ConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ConfigAddedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") - } - - return e, nil -} diff --git a/internal/v2/repository/idp/oidc/event_changed.go b/internal/v2/repository/idp/oidc/event_changed.go deleted file mode 100644 index ec445b75f3..0000000000 --- a/internal/v2/repository/idp/oidc/event_changed.go +++ /dev/null @@ -1,105 +0,0 @@ -package oidc - -import ( - "encoding/json" - "reflect" - "sort" - - "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -const ( - ConfigChangedEventType eventstore.EventType = "oidc.config.changed" -) - -type ConfigChangedEvent struct { - eventstore.BaseEvent `json:"-"` - - IDPConfigID string `json:"idpConfigId"` - - ClientID string `json:"clientId,omitempty"` - ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"` - Issuer string `json:"issuer,omitempty"` - Scopes []string `json:"scpoes,omitempty"` - - IDPDisplayNameMapping MappingField `json:"idpDisplayNameMapping,omitempty"` - UserNameMapping MappingField `json:"usernameMapping,omitempty"` -} - -func (e *ConfigChangedEvent) Data() interface{} { - return e -} - -func NewConfigChangedEvent( - base *eventstore.BaseEvent, - current *ConfigWriteModel, - clientID, - issuer string, - clientSecret *crypto.CryptoValue, - idpDisplayNameMapping, - userNameMapping MappingField, - scopes ...string, -) (*ConfigChangedEvent, error) { - - event := &ConfigChangedEvent{ - BaseEvent: *base, - IDPConfigID: current.IDPConfigID, - } - hasChanged := false - - if clientID != "" && clientID != current.ClientID { - event.ClientID = clientID - hasChanged = true - } - - if issuer != "" && issuer != current.Issuer { - event.Issuer = issuer - hasChanged = true - } - - if clientSecret != nil { - event.ClientSecret = clientSecret - hasChanged = true - } - - if idpDisplayNameMapping.Valid() && idpDisplayNameMapping != current.IDPDisplayNameMapping { - event.IDPDisplayNameMapping = idpDisplayNameMapping - hasChanged = true - } - - if userNameMapping.Valid() && userNameMapping != current.UserNameMapping { - event.UserNameMapping = userNameMapping - hasChanged = true - } - - if len(scopes) > 0 { - sort.Strings(scopes) - sort.Strings(current.Scopes) - if !reflect.DeepEqual(scopes, current.Scopes) { - event.Scopes = scopes - hasChanged = true - } - } - - if !hasChanged { - return nil, errors.ThrowPreconditionFailed(nil, "OIDC-zPDOL", "Errors.NoChanges") - } - - return event, nil -} - -func ConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ConfigChangedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") - } - - return e, nil -} diff --git a/internal/v2/repository/idp/oidc/mapping_field.go b/internal/v2/repository/idp/oidc/mapping_field.go deleted file mode 100644 index d3c932f8ed..0000000000 --- a/internal/v2/repository/idp/oidc/mapping_field.go +++ /dev/null @@ -1,14 +0,0 @@ -package oidc - -type MappingField int32 - -const ( - MappingFieldPreferredLoginName MappingField = iota + 1 - MappingFieldEmail - // count is for validation purposes - mappingFieldCount -) - -func (f MappingField) Valid() bool { - return f > 0 && f < mappingFieldCount -} diff --git a/internal/v2/repository/idpconfig/idp_config.go b/internal/v2/repository/idpconfig/idp_config.go new file mode 100644 index 0000000000..6541e5a666 --- /dev/null +++ b/internal/v2/repository/idpconfig/idp_config.go @@ -0,0 +1,187 @@ +package idpconfig + +import ( + "encoding/json" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" +) + +type IDPConfigAddedEvent struct { + eventstore.BaseEvent `json:"-"` + + ConfigID string `json:"idpConfigId"` + Name string `json:"name,omitempty"` + Typ domain.IDPConfigType `json:"idpType,omitempty"` + StylingType domain.IDPConfigStylingType `json:"stylingType,omitempty"` +} + +func NewIDPConfigAddedEvent( + base *eventstore.BaseEvent, + configID string, + name string, + configType domain.IDPConfigType, + stylingType domain.IDPConfigStylingType, +) *IDPConfigAddedEvent { + + return &IDPConfigAddedEvent{ + BaseEvent: *base, + ConfigID: configID, + Name: name, + StylingType: stylingType, + Typ: configType, + } +} + +func (e *IDPConfigAddedEvent) Data() interface{} { + return e +} + +func IDPConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &IDPConfigAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") + } + + return e, nil +} + +type IDPConfigChangedEvent struct { + eventstore.BaseEvent `json:"-"` + + ConfigID string `json:"idpConfigId"` + Name string `json:"name,omitempty"` + StylingType domain.IDPConfigStylingType `json:"stylingType,omitempty"` +} + +func (e *IDPConfigChangedEvent) Data() interface{} { + return e +} + +func NewIDPConfigChangedEvent( + base *eventstore.BaseEvent, +) *IDPConfigChangedEvent { + return &IDPConfigChangedEvent{ + BaseEvent: *base, + } +} + +func IDPConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &IDPConfigChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") + } + + return e, nil +} + +type IDPConfigDeactivatedEvent struct { + eventstore.BaseEvent `json:"-"` + + ConfigID string `idpConfigId` +} + +func NewIDPConfigDeactivatedEvent( + base *eventstore.BaseEvent, + configID string, +) *IDPConfigDeactivatedEvent { + + return &IDPConfigDeactivatedEvent{ + BaseEvent: *base, + ConfigID: configID, + } +} + +func (e *IDPConfigDeactivatedEvent) Data() interface{} { + return e +} + +func IDPConfigDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &IDPConfigDeactivatedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") + } + + return e, nil +} + +type IDPConfigReactivatedEvent struct { + eventstore.BaseEvent `json:"-"` + + ConfigID string `idpConfigId` +} + +func NewIDPConfigReactivatedEvent( + base *eventstore.BaseEvent, + configID string, +) *IDPConfigReactivatedEvent { + + return &IDPConfigReactivatedEvent{ + BaseEvent: *base, + ConfigID: configID, + } +} + +func (e *IDPConfigReactivatedEvent) Data() interface{} { + return e +} + +func IDPConfigReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &IDPConfigReactivatedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") + } + + return e, nil +} + +type IDPConfigRemovedEvent struct { + eventstore.BaseEvent `json:"-"` + + ConfigID string `idpConfigId` +} + +func NewIDPConfigRemovedEvent( + base *eventstore.BaseEvent, + configID string, +) *IDPConfigRemovedEvent { + + return &IDPConfigRemovedEvent{ + BaseEvent: *base, + ConfigID: configID, + } +} + +func (e *IDPConfigRemovedEvent) Data() interface{} { + return e +} + +func IDPConfigRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &IDPConfigRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") + } + + return e, nil +} diff --git a/internal/v2/repository/idpconfig/oidc_config.go b/internal/v2/repository/idpconfig/oidc_config.go new file mode 100644 index 0000000000..54b6a09065 --- /dev/null +++ b/internal/v2/repository/idpconfig/oidc_config.go @@ -0,0 +1,107 @@ +package idpconfig + +import ( + "encoding/json" + "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" +) + +const ( + OIDCConfigAddedEventType eventstore.EventType = "oidc.config.added" + ConfigChangedEventType eventstore.EventType = "oidc.config.changed" +) + +type OIDCConfigAddedEvent struct { + eventstore.BaseEvent + + IDPConfigID string `json:"idpConfigId"` + ClientID string `json:"clientId,omitempty"` + ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"` + Issuer string `json:"issuer,omitempty"` + Scopes []string `json:"scpoes,omitempty"` + + IDPDisplayNameMapping domain.OIDCMappingField `json:"idpDisplayNameMapping,omitempty"` + UserNameMapping domain.OIDCMappingField `json:"usernameMapping,omitempty"` +} + +func (e *OIDCConfigAddedEvent) Data() interface{} { + return e +} + +func NewOIDCConfigAddedEvent( + base *eventstore.BaseEvent, + clientID, + idpConfigID, + issuer string, + clientSecret *crypto.CryptoValue, + idpDisplayNameMapping, + userNameMapping domain.OIDCMappingField, + scopes ...string, +) *OIDCConfigAddedEvent { + + return &OIDCConfigAddedEvent{ + BaseEvent: *base, + IDPConfigID: idpConfigID, + ClientID: clientID, + ClientSecret: clientSecret, + Issuer: issuer, + Scopes: scopes, + IDPDisplayNameMapping: idpDisplayNameMapping, + UserNameMapping: userNameMapping, + } +} + +func OIDCConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &OIDCConfigAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") + } + + return e, nil +} + +type OIDCConfigChangedEvent struct { + eventstore.BaseEvent `json:"-"` + + IDPConfigID string `json:"idpConfigId"` + + ClientID string `json:"clientId,omitempty"` + ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"` + Issuer string `json:"issuer,omitempty"` + Scopes []string `json:"scpoes,omitempty"` + + IDPDisplayNameMapping domain.OIDCMappingField `json:"idpDisplayNameMapping,omitempty"` + UserNameMapping domain.OIDCMappingField `json:"usernameMapping,omitempty"` +} + +func (e *OIDCConfigChangedEvent) Data() interface{} { + return e +} + +func NewOIDCConfigChangedEvent( + base *eventstore.BaseEvent, +) *OIDCConfigChangedEvent { + return &OIDCConfigChangedEvent{ + BaseEvent: *base, + } +} + +func OIDCConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &OIDCConfigChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "OIDC-plaBZ", "unable to unmarshal event") + } + + return e, nil +} diff --git a/internal/v2/repository/member/event_added.go b/internal/v2/repository/member/event_added.go deleted file mode 100644 index 4f5c4055d0..0000000000 --- a/internal/v2/repository/member/event_added.go +++ /dev/null @@ -1,50 +0,0 @@ -package member - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - es_repo "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -const ( - AddedEventType = "member.added" -) - -type AddedEvent struct { - eventstore.BaseEvent `json:"-"` - - Roles []string `json:"roles"` - UserID string `json:"userId"` -} - -func (e *AddedEvent) Data() interface{} { - return e -} - -func NewAddedEvent( - base *eventstore.BaseEvent, - userID string, - roles ...string, -) *AddedEvent { - - return &AddedEvent{ - BaseEvent: *base, - Roles: roles, - UserID: userID, - } -} - -func AddedEventMapper(event *es_repo.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "POLIC-puqv4", "unable to unmarshal label policy") - } - - return e, nil -} diff --git a/internal/v2/repository/member/event_changed.go b/internal/v2/repository/member/event_changed.go deleted file mode 100644 index a39b611108..0000000000 --- a/internal/v2/repository/member/event_changed.go +++ /dev/null @@ -1,75 +0,0 @@ -package member - -import ( - "encoding/json" - "reflect" - "sort" - - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -const ( - ChangedEventType = "member.changed" -) - -type ChangedEvent struct { - eventstore.BaseEvent `json:"-"` - - Roles []string `json:"roles,omitempty"` - UserID string `json:"userId,omitempty"` -} - -func (e *ChangedEvent) Data() interface{} { - return e -} - -func ChangeEventFromExisting( - base *eventstore.BaseEvent, - current *WriteModel, - roles ...string, -) (*ChangedEvent, error) { - - change := NewChangedEvent(base, current.UserID) - hasChanged := false - - sort.Strings(current.Roles) - sort.Strings(roles) - if !reflect.DeepEqual(current.Roles, roles) { - change.Roles = roles - hasChanged = true - } - - if !hasChanged { - return nil, errors.ThrowPreconditionFailed(nil, "MEMBE-SeKlD", "Errors.NoChanges") - } - - return change, nil -} - -func NewChangedEvent( - base *eventstore.BaseEvent, - userID string, - roles ...string, -) *ChangedEvent { - - return &ChangedEvent{ - BaseEvent: *base, - UserID: userID, - Roles: roles, - } -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ChangedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "POLIC-puqv4", "unable to unmarshal label policy") - } - - return e, nil -} diff --git a/internal/v2/repository/member/event_removed.go b/internal/v2/repository/member/event_removed.go deleted file mode 100644 index 788cf21915..0000000000 --- a/internal/v2/repository/member/event_removed.go +++ /dev/null @@ -1,47 +0,0 @@ -package member - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -const ( - RemovedEventType = "member.removed" -) - -type RemovedEvent struct { - eventstore.BaseEvent `json:"-"` - - UserID string `json:"userId"` -} - -func (e *RemovedEvent) Data() interface{} { - return e -} - -func NewRemovedEvent( - base *eventstore.BaseEvent, - userID string, -) *RemovedEvent { - - return &RemovedEvent{ - BaseEvent: *base, - UserID: userID, - } -} - -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &RemovedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "POLIC-Ep4ip", "unable to unmarshal label policy") - } - - return e, nil -} diff --git a/internal/v2/repository/member/events.go b/internal/v2/repository/member/events.go new file mode 100644 index 0000000000..c4d8c018e3 --- /dev/null +++ b/internal/v2/repository/member/events.go @@ -0,0 +1,121 @@ +package member + +import ( + "encoding/json" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" +) + +const ( + AddedEventType = "member.added" + ChangedEventType = "member.changed" + RemovedEventType = "member.removed" +) + +type MemberAddedEvent struct { + eventstore.BaseEvent `json:"-"` + + Roles []string `json:"roles"` + UserID string `json:"userId"` +} + +func (e *MemberAddedEvent) Data() interface{} { + return e +} + +func NewMemberAddedEvent( + base *eventstore.BaseEvent, + userID string, + roles ...string, +) *MemberAddedEvent { + + return &MemberAddedEvent{ + BaseEvent: *base, + Roles: roles, + UserID: userID, + } +} + +func MemberAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &MemberAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-puqv4", "unable to unmarshal label policy") + } + + return e, nil +} + +type MemberChangedEvent struct { + eventstore.BaseEvent `json:"-"` + + Roles []string `json:"roles,omitempty"` + UserID string `json:"userId,omitempty"` +} + +func (e *MemberChangedEvent) Data() interface{} { + return e +} + +func NewMemberChangedEvent( + base *eventstore.BaseEvent, + userID string, + roles ...string, +) *MemberChangedEvent { + return &MemberChangedEvent{ + BaseEvent: *base, + Roles: roles, + UserID: userID, + } +} + +func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &MemberChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-puqv4", "unable to unmarshal label policy") + } + + return e, nil +} + +type MemberRemovedEvent struct { + eventstore.BaseEvent `json:"-"` + + UserID string `json:"userId"` +} + +func (e *MemberRemovedEvent) Data() interface{} { + return e +} + +func NewRemovedEvent( + base *eventstore.BaseEvent, + userID string, +) *MemberRemovedEvent { + + return &MemberRemovedEvent{ + BaseEvent: *base, + UserID: userID, + } +} + +func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &MemberRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-Ep4ip", "unable to unmarshal label policy") + } + + return e, nil +} diff --git a/internal/v2/repository/member/read_model.go b/internal/v2/repository/member/read_model.go deleted file mode 100644 index c954833b85..0000000000 --- a/internal/v2/repository/member/read_model.go +++ /dev/null @@ -1,32 +0,0 @@ -package member - -import "github.com/caos/zitadel/internal/eventstore/v2" - -//ReadModel represenets the default member view. -// It's computed from events. -type ReadModel struct { - eventstore.ReadModel - - UserID string - Roles []string -} - -//NewReadModel is the default constructor of ReadModel -func NewReadModel(userID string) *ReadModel { - return &ReadModel{ - UserID: userID, - } -} - -//Reduce extends eventstore.ReadModel -func (rm *ReadModel) Reduce() error { - for _, event := range rm.Events { - switch e := event.(type) { - case *AddedEvent: - rm.Roles = e.Roles - case *ChangedEvent: - rm.Roles = e.Roles - } - } - return rm.ReadModel.Reduce() -} diff --git a/internal/v2/repository/member/write_model.go b/internal/v2/repository/member/write_model.go deleted file mode 100644 index be0283a963..0000000000 --- a/internal/v2/repository/member/write_model.go +++ /dev/null @@ -1,43 +0,0 @@ -package member - -import "github.com/caos/zitadel/internal/eventstore/v2" - -//WriteModel is used to create events -// It has no computed fields and represents the data -// which can be changed -type WriteModel struct { - eventstore.WriteModel - - UserID string - Roles []string - IsActive bool -} - -func NewWriteModel(userID string) *WriteModel { - return &WriteModel{ - UserID: userID, - } -} - -//Reduce extends eventstore.ReadModel -func (wm *WriteModel) Reduce() error { - for _, event := range wm.Events { - switch e := event.(type) { - case *AddedEvent: - wm.UserID = e.UserID - wm.Roles = e.Roles - wm.IsActive = true - case *ChangedEvent: - wm.Roles = e.Roles - case *RemovedEvent: - wm.Roles = nil - wm.IsActive = false - } - } - return wm.WriteModel.Reduce() -} - -// func (wm *WriteModel) Query() *eventstore.SearchQueryFactory { -// return eventstore.NewSearchQueryFactory(eventstore.ColumnsEvent, wm.aggregateType). -// AggregateIDs(wm.aggregateID) -// } diff --git a/internal/v2/repository/org/aggregate.go b/internal/v2/repository/org/aggregate.go new file mode 100644 index 0000000000..02aeaf9cee --- /dev/null +++ b/internal/v2/repository/org/aggregate.go @@ -0,0 +1,35 @@ +package org + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" +) + +const ( + iamEventTypePrefix = eventstore.EventType("org.") +) + +const ( + AggregateType = "org" + AggregateVersion = "v1" +) + +type Aggregate struct { + eventstore.Aggregate +} + +func NewAggregate( + id, + resourceOwner string, + previousSequence uint64, +) *Aggregate { + + return &Aggregate{ + Aggregate: *eventstore.NewAggregate( + id, + AggregateType, + resourceOwner, + AggregateVersion, + previousSequence, + ), + } +} diff --git a/internal/v2/repository/org/member.go b/internal/v2/repository/org/member.go index a2017275c9..74995b6739 100644 --- a/internal/v2/repository/org/member.go +++ b/internal/v2/repository/org/member.go @@ -2,10 +2,8 @@ package org import ( "context" - "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/repository/member" - "github.com/caos/zitadel/internal/v2/repository/members" ) const ( @@ -18,58 +16,8 @@ var ( MemberRemovedEventType = orgEventTypePrefix + member.RemovedEventType ) -type MemberWriteModel struct { - member.WriteModel -} - -// func NewMemberAggregate(userID string) *MemberAggregate { -// return &MemberAggregate{ -// Aggregate: member.NewAggregate( -// eventstore.NewAggregate(userID, MemberAggregateType, "RO", AggregateVersion, 0), -// ), -// // Aggregate: member.NewMemberAggregate(userID), -// } -// } - -type MembersReadModel struct { - members.ReadModel -} - -func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *MemberAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *MemberChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *MemberRemovedEvent: - rm.ReadModel.AppendEvents(&e.RemovedEvent) - } - } -} - -type MemberReadModel member.ReadModel - -func (rm *MemberReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *MemberAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *MemberChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - } - } -} - type MemberAddedEvent struct { - member.AddedEvent -} - -type MemberChangedEvent struct { - member.ChangedEvent -} -type MemberRemovedEvent struct { - member.RemovedEvent + member.MemberAddedEvent } func NewMemberAddedEvent( @@ -77,9 +25,8 @@ func NewMemberAddedEvent( userID string, roles ...string, ) *MemberAddedEvent { - return &MemberAddedEvent{ - AddedEvent: *member.NewAddedEvent( + MemberAddedEvent: *member.NewMemberAddedEvent( eventstore.NewBaseEventForPush( ctx, MemberAddedEventType, @@ -90,27 +37,8 @@ func NewMemberAddedEvent( } } -func MemberChangedEventFromExisting( - ctx context.Context, - current *MemberWriteModel, - roles ...string, -) (*MemberChangedEvent, error) { - - m, err := member.ChangeEventFromExisting( - eventstore.NewBaseEventForPush( - ctx, - MemberChangedEventType, - ), - ¤t.WriteModel, - roles..., - ) - if err != nil { - return nil, err - } - - return &MemberChangedEvent{ - ChangedEvent: *m, - }, nil +type MemberChangedEvent struct { + member.MemberChangedEvent } func NewMemberChangedEvent( @@ -120,7 +48,7 @@ func NewMemberChangedEvent( ) *MemberChangedEvent { return &MemberChangedEvent{ - ChangedEvent: *member.NewChangedEvent( + MemberChangedEvent: *member.NewMemberChangedEvent( eventstore.NewBaseEventForPush( ctx, MemberChangedEventType, @@ -131,13 +59,17 @@ func NewMemberChangedEvent( } } +type MemberRemovedEvent struct { + member.MemberRemovedEvent +} + func NewMemberRemovedEvent( ctx context.Context, userID string, ) *MemberRemovedEvent { return &MemberRemovedEvent{ - RemovedEvent: *member.NewRemovedEvent( + MemberRemovedEvent: *member.NewRemovedEvent( eventstore.NewBaseEventForPush( ctx, MemberRemovedEventType, diff --git a/internal/v2/repository/org/policy_label.go b/internal/v2/repository/org/policy_label.go index 110859bd96..2d0869786c 100644 --- a/internal/v2/repository/org/policy_label.go +++ b/internal/v2/repository/org/policy_label.go @@ -1,64 +1,18 @@ package org import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/label" + "github.com/caos/zitadel/internal/v2/repository/policy" ) var ( - LabelPolicyAddedEventType = orgEventTypePrefix + label.LabelPolicyAddedEventType - LabelPolicyChangedEventType = orgEventTypePrefix + label.LabelPolicyChangedEventType + LabelPolicyAddedEventType = orgEventTypePrefix + policy.LabelPolicyAddedEventType + LabelPolicyChangedEventType = orgEventTypePrefix + policy.LabelPolicyChangedEventType ) -type LabelPolicyReadModel struct{ label.ReadModel } - -func (rm *LabelPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *LabelPolicyAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *LabelPolicyChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *label.AddedEvent, *label.ChangedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} - type LabelPolicyAddedEvent struct { - label.AddedEvent + policy.LabelPolicyAddedEvent } type LabelPolicyChangedEvent struct { - label.ChangedEvent + policy.LabelPolicyChangedEvent } - -// func NewAddedEvent( -// ctx context.Context, -// primaryColor, -// secondaryColor string, -// ) *AddedEvent { - -// return &AddedEvent{ -// AddedEvent: *policy.NewAddedEvent( -// ctx, -// primaryColor, -// secondaryColor, -// ), -// } -// } - -// func NewChangedEvent( -// ctx context.Context, -// primaryColor, -// secondaryColor string, -// ) *MemberChangedEvent { - -// return &ChangedEvent{ -// ChangedEvent: *policy.NewChangedEvent( -// ctx, -// primaryColor, -// secondaryColor, -// ), -// } -// } diff --git a/internal/v2/repository/org/policy_login.go b/internal/v2/repository/org/policy_login.go index 4823bd90b7..2323c932bd 100644 --- a/internal/v2/repository/org/policy_login.go +++ b/internal/v2/repository/org/policy_login.go @@ -1,34 +1,18 @@ package org import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/login" + "github.com/caos/zitadel/internal/v2/repository/policy" ) var ( - LoginPolicyAddedEventType = orgEventTypePrefix + login.LoginPolicyAddedEventType - LoginPolicyChangedEventType = orgEventTypePrefix + login.LoginPolicyChangedEventType + LoginPolicyAddedEventType = orgEventTypePrefix + policy.LoginPolicyAddedEventType + LoginPolicyChangedEventType = orgEventTypePrefix + policy.LoginPolicyChangedEventType ) -type LoginPolicyReadModel struct{ login.ReadModel } - -func (rm *LoginPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *LoginPolicyAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *LoginPolicyChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *login.AddedEvent, *login.ChangedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} - type LoginPolicyAddedEvent struct { - login.AddedEvent + policy.LoginPolicyAddedEvent } type LoginPolicyChangedEvent struct { - login.ChangedEvent + policy.LoginPolicyChangedEvent } diff --git a/internal/v2/repository/org/policy_org_iam.go b/internal/v2/repository/org/policy_org_iam.go index 2867bb9fe8..da52d29ef1 100644 --- a/internal/v2/repository/org/policy_org_iam.go +++ b/internal/v2/repository/org/policy_org_iam.go @@ -1,27 +1,40 @@ package org import ( + "context" "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/org_iam" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" ) var ( - OrgIAMPolicyAddedEventType = orgEventTypePrefix + org_iam.OrgIAMPolicyAddedEventType + OrgIAMPolicyAddedEventType = orgEventTypePrefix + policy.OrgIAMPolicyAddedEventType + OrgIAMPolicyChangedEventType = orgEventTypePrefix + policy.OrgIAMPolicyChangedEventType ) -type OrgIAMPolicyReadModel struct{ org_iam.ReadModel } +type OrgIAMPolicyAddedEvent struct { + policy.OrgIAMPolicyAddedEvent +} -func (rm *OrgIAMPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *OrgIAMPolicyAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *org_iam.AddedEvent: - rm.ReadModel.AppendEvents(e) - } +type OrgIAMPolicyChangedEvent struct { + policy.OrgIAMPolicyChangedEvent +} + +func NewOrgIAMPolicyChangedEvent( + ctx context.Context, +) *OrgIAMPolicyChangedEvent { + return &OrgIAMPolicyChangedEvent{ + OrgIAMPolicyChangedEvent: *policy.NewOrgIAMPolicyChangedEvent( + eventstore.NewBaseEventForPush(ctx, OrgIAMPolicyChangedEventType), + ), } } -type OrgIAMPolicyAddedEvent struct { - org_iam.AddedEvent +func OrgIAMPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.OrgIAMPolicyChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &OrgIAMPolicyChangedEvent{OrgIAMPolicyChangedEvent: *e.(*policy.OrgIAMPolicyChangedEvent)}, nil } diff --git a/internal/v2/repository/org/policy_password_age.go b/internal/v2/repository/org/policy_password_age.go index 17f393d770..da92f15c1c 100644 --- a/internal/v2/repository/org/policy_password_age.go +++ b/internal/v2/repository/org/policy_password_age.go @@ -1,36 +1,18 @@ package org import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_age" + "github.com/caos/zitadel/internal/v2/repository/policy" ) var ( - PasswordAgePolicyAddedEventType = orgEventTypePrefix + password_age.PasswordAgePolicyAddedEventType - PasswordAgePolicyChangedEventType = orgEventTypePrefix + password_age.PasswordAgePolicyChangedEventType + PasswordAgePolicyAddedEventType = orgEventTypePrefix + policy.PasswordAgePolicyAddedEventType + PasswordAgePolicyChangedEventType = orgEventTypePrefix + policy.PasswordAgePolicyChangedEventType ) -type PasswordAgePolicyReadModel struct { - password_age.ReadModel -} - -func (rm *PasswordAgePolicyReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *PasswordAgePolicyAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *PasswordAgePolicyChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *password_age.AddedEvent, *password_age.ChangedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} - type PasswordAgePolicyAddedEvent struct { - password_age.AddedEvent + policy.PasswordAgePolicyAddedEvent } type PasswordAgePolicyChangedEvent struct { - password_age.ChangedEvent + policy.PasswordAgePolicyChangedEvent } diff --git a/internal/v2/repository/org/policy_password_complexity.go b/internal/v2/repository/org/policy_password_complexity.go index e435d6f24d..471cf0c0e2 100644 --- a/internal/v2/repository/org/policy_password_complexity.go +++ b/internal/v2/repository/org/policy_password_complexity.go @@ -1,36 +1,68 @@ package org import ( + "context" "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_complexity" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/repository/policy" ) var ( - PasswordComplexityPolicyAddedEventType = orgEventTypePrefix + password_complexity.PasswordComplexityPolicyAddedEventType - PasswordComplexityPolicyChangedEventType = orgEventTypePrefix + password_complexity.PasswordComplexityPolicyChangedEventType + PasswordComplexityPolicyAddedEventType = orgEventTypePrefix + policy.PasswordComplexityPolicyAddedEventType + PasswordComplexityPolicyChangedEventType = orgEventTypePrefix + policy.PasswordComplexityPolicyChangedEventType ) -type PasswordComplexityPolicyReadModel struct { - password_complexity.ReadModel +type PasswordComplexityPolicyAddedEvent struct { + policy.PasswordComplexityPolicyAddedEvent } -func (rm *PasswordComplexityPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *PasswordComplexityPolicyAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *PasswordComplexityPolicyChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *password_complexity.AddedEvent, *password_complexity.ChangedEvent: - rm.ReadModel.AppendEvents(e) - } +func NewPasswordComplexityPolicyAddedEvent( + ctx context.Context, + minLength uint64, + hasLowercase, + hasUppercase, + hasNumber, + hasSymbol bool, +) *PasswordComplexityPolicyAddedEvent { + return &PasswordComplexityPolicyAddedEvent{ + PasswordComplexityPolicyAddedEvent: *policy.NewPasswordComplexityPolicyAddedEvent( + eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyAddedEventType), + minLength, + hasLowercase, + hasUppercase, + hasNumber, + hasSymbol), } } -type PasswordComplexityPolicyAddedEvent struct { - password_complexity.AddedEvent +func PasswordComplexityPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.PasswordComplexityPolicyAddedEventMapper(event) + if err != nil { + return nil, err + } + + return &PasswordComplexityPolicyAddedEvent{PasswordComplexityPolicyAddedEvent: *e.(*policy.PasswordComplexityPolicyAddedEvent)}, nil } type PasswordComplexityPolicyChangedEvent struct { - password_complexity.ChangedEvent + policy.PasswordComplexityPolicyChangedEvent +} + +func NewPasswordComplexityPolicyChangedEvent( + ctx context.Context, +) *PasswordComplexityPolicyChangedEvent { + return &PasswordComplexityPolicyChangedEvent{ + PasswordComplexityPolicyChangedEvent: *policy.NewPasswordComplexityPolicyChangedEvent( + eventstore.NewBaseEventForPush(ctx, PasswordComplexityPolicyAddedEventType), + ), + } +} + +func PasswordComplexityPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e, err := policy.PasswordComplexityPolicyChangedEventMapper(event) + if err != nil { + return nil, err + } + + return &PasswordComplexityPolicyChangedEvent{PasswordComplexityPolicyChangedEvent: *e.(*policy.PasswordComplexityPolicyChangedEvent)}, nil } diff --git a/internal/v2/repository/org/policy_password_lockout.go b/internal/v2/repository/org/policy_password_lockout.go index 61c3c73999..0eb2b18a13 100644 --- a/internal/v2/repository/org/policy_password_lockout.go +++ b/internal/v2/repository/org/policy_password_lockout.go @@ -1,36 +1,18 @@ package org import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/policy/password_lockout" + "github.com/caos/zitadel/internal/v2/repository/policy" ) var ( - PasswordLockoutPolicyAddedEventType = orgEventTypePrefix + password_lockout.PasswordLockoutPolicyAddedEventType - PasswordLockoutPolicyChangedEventType = orgEventTypePrefix + password_lockout.PasswordLockoutPolicyChangedEventType + PasswordLockoutPolicyAddedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyAddedEventType + PasswordLockoutPolicyChangedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyChangedEventType ) -type PasswordLockoutPolicyReadModel struct { - password_lockout.ReadModel -} - -func (rm *PasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) { - for _, event := range events { - switch e := event.(type) { - case *PasswordLockoutPolicyAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *PasswordLockoutPolicyChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *password_lockout.AddedEvent, *password_lockout.ChangedEvent: - rm.ReadModel.AppendEvents(e) - } - } -} - type PasswordLockoutPolicyAddedEvent struct { - password_lockout.AddedEvent + policy.PasswordLockoutPolicyAddedEvent } type PasswordLockoutPolicyChangedEvent struct { - password_lockout.ChangedEvent + policy.PasswordLockoutPolicyChangedEvent } diff --git a/internal/v2/repository/policy/label/events.go b/internal/v2/repository/policy/label.go similarity index 62% rename from internal/v2/repository/policy/label/events.go rename to internal/v2/repository/policy/label.go index 06bf052c3a..aab6ef71a3 100644 --- a/internal/v2/repository/policy/label/events.go +++ b/internal/v2/repository/policy/label.go @@ -1,4 +1,4 @@ -package label +package policy import ( "encoding/json" @@ -13,32 +13,32 @@ const ( LabelPolicyRemovedEventType = "policy.label.removed" ) -type AddedEvent struct { +type LabelPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` PrimaryColor string `json:"primaryColor,omitempty"` SecondaryColor string `json:"secondaryColor,omitempty"` } -func (e *AddedEvent) Data() interface{} { +func (e *LabelPolicyAddedEvent) Data() interface{} { return e } -func NewAddedEvent( +func NewLabelPolicyAddedEvent( base *eventstore.BaseEvent, primaryColor, secondaryColor string, -) *AddedEvent { +) *LabelPolicyAddedEvent { - return &AddedEvent{ + return &LabelPolicyAddedEvent{ BaseEvent: *base, PrimaryColor: primaryColor, SecondaryColor: secondaryColor, } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ +func LabelPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &LabelPolicyAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -50,39 +50,27 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return e, nil } -type ChangedEvent struct { +type LabelPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` PrimaryColor string `json:"primaryColor,omitempty"` SecondaryColor string `json:"secondaryColor,omitempty"` } -func (e *ChangedEvent) Data() interface{} { +func (e *LabelPolicyChangedEvent) Data() interface{} { return e } -func NewChangedEvent( +func NewLabelPolicyChangedEvent( base *eventstore.BaseEvent, - current *WriteModel, - primaryColor, - secondaryColor string, -) *ChangedEvent { - - e := &ChangedEvent{ +) *LabelPolicyChangedEvent { + return &LabelPolicyChangedEvent{ BaseEvent: *base, } - if primaryColor != "" && current.PrimaryColor != primaryColor { - e.PrimaryColor = primaryColor - } - if secondaryColor != "" && current.SecondaryColor != secondaryColor { - e.SecondaryColor = secondaryColor - } - - return e } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ChangedEvent{ +func LabelPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &LabelPolicyChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -94,22 +82,22 @@ func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) return e, nil } -type RemovedEvent struct { +type LabelPolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *RemovedEvent) Data() interface{} { +func (e *LabelPolicyRemovedEvent) Data() interface{} { return nil } -func NewRemovedEvent(base *eventstore.BaseEvent) *RemovedEvent { - return &RemovedEvent{ +func NewRemovedEvent(base *eventstore.BaseEvent) *LabelPolicyRemovedEvent { + return &LabelPolicyRemovedEvent{ BaseEvent: *base, } } func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &RemovedEvent{ + return &LabelPolicyRemovedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } diff --git a/internal/v2/repository/policy/label/read_model.go b/internal/v2/repository/policy/label/read_model.go deleted file mode 100644 index 3c55ce09fa..0000000000 --- a/internal/v2/repository/policy/label/read_model.go +++ /dev/null @@ -1,24 +0,0 @@ -package label - -import "github.com/caos/zitadel/internal/eventstore/v2" - -type ReadModel struct { - eventstore.ReadModel - - PrimaryColor string - SecondaryColor string -} - -func (rm *ReadModel) Reduce() error { - for _, event := range rm.Events { - switch e := event.(type) { - case *AddedEvent: - rm.PrimaryColor = e.PrimaryColor - rm.SecondaryColor = e.SecondaryColor - case *ChangedEvent: - rm.PrimaryColor = e.PrimaryColor - rm.SecondaryColor = e.SecondaryColor - } - } - return rm.ReadModel.Reduce() -} diff --git a/internal/v2/repository/policy/login.go b/internal/v2/repository/policy/login.go new file mode 100644 index 0000000000..21e3c35adb --- /dev/null +++ b/internal/v2/repository/policy/login.go @@ -0,0 +1,119 @@ +package policy + +import ( + "encoding/json" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" +) + +const ( + loginPolicyPrefix = "policy.login." + LoginPolicyAddedEventType = loginPolicyPrefix + "added" + LoginPolicyChangedEventType = loginPolicyPrefix + "changed" + LoginPolicyRemovedEventType = loginPolicyPrefix + "removed" +) + +type LoginPolicyAddedEvent struct { + eventstore.BaseEvent `json:"-"` + + AllowUserNamePassword bool `json:"allowUsernamePassword"` + AllowRegister bool `json:"allowRegister"` + AllowExternalIDP bool `json:"allowExternalIdp"` + ForceMFA bool `json:"forceMFA"` + PasswordlessType domain.PasswordlessType `json:"passwordlessType"` +} + +func (e *LoginPolicyAddedEvent) Data() interface{} { + return e +} + +func NewLoginPolicyAddedEvent( + base *eventstore.BaseEvent, + allowUserNamePassword, + allowRegister, + allowExternalIDP, + forceMFA bool, + passwordlessType domain.PasswordlessType, +) *LoginPolicyAddedEvent { + return &LoginPolicyAddedEvent{ + BaseEvent: *base, + AllowExternalIDP: allowExternalIDP, + AllowRegister: allowRegister, + AllowUserNamePassword: allowUserNamePassword, + ForceMFA: forceMFA, + PasswordlessType: passwordlessType, + } +} + +func LoginPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &LoginPolicyAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-nWndT", "unable to unmarshal policy") + } + + return e, nil +} + +type LoginPolicyChangedEvent struct { + eventstore.BaseEvent `json:"-"` + + AllowUserNamePassword bool `json:"allowUsernamePassword,omitempty"` + AllowRegister bool `json:"allowRegister"` + AllowExternalIDP bool `json:"allowExternalIdp"` + ForceMFA bool `json:"forceMFA"` + PasswordlessType domain.PasswordlessType `json:"passwordlessType"` +} + +type LoginPolicyEventData struct { +} + +func (e *LoginPolicyChangedEvent) Data() interface{} { + return e +} + +func NewLoginPolicyChangedEvent( + base *eventstore.BaseEvent, +) *LoginPolicyChangedEvent { + return &LoginPolicyChangedEvent{ + BaseEvent: *base, + } +} + +func LoginPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &LoginPolicyChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-ehssl", "unable to unmarshal policy") + } + + return e, nil +} + +type LoginPolicyRemovedEvent struct { + eventstore.BaseEvent `json:"-"` +} + +func (e *LoginPolicyRemovedEvent) Data() interface{} { + return nil +} + +func NewLoginPolicyRemovedEvent(base *eventstore.BaseEvent) *LoginPolicyRemovedEvent { + return &LoginPolicyRemovedEvent{ + BaseEvent: *base, + } +} + +func LoginPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &LoginPolicyRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} diff --git a/internal/v2/repository/policy/login/events.go b/internal/v2/repository/policy/login/events.go deleted file mode 100644 index f792d97226..0000000000 --- a/internal/v2/repository/policy/login/events.go +++ /dev/null @@ -1,143 +0,0 @@ -package login - -import ( - "encoding/json" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/policy/login/idpprovider" -) - -const ( - loginPolicyPrefix = "policy.login." - LoginPolicyAddedEventType = loginPolicyPrefix + "added" - LoginPolicyChangedEventType = loginPolicyPrefix + "changed" - LoginPolicyRemovedEventType = loginPolicyPrefix + "removed" - LoginPolicyIDPProviderAddedEventType = loginPolicyPrefix + idpprovider.AddedEventType - LoginPolicyIDPProviderRemovedEventType = loginPolicyPrefix + idpprovider.RemovedEventType -) - -type AddedEvent struct { - eventstore.BaseEvent `json:"-"` - - AllowUserNamePassword bool `json:"allowUsernamePassword"` - AllowRegister bool `json:"allowRegister"` - AllowExternalIDP bool `json:"allowExternalIdp"` - ForceMFA bool `json:"forceMFA"` - PasswordlessType PasswordlessType `json:"passwordlessType"` -} - -func (e *AddedEvent) Data() interface{} { - return e -} - -func NewAddedEvent( - base *eventstore.BaseEvent, - allowUserNamePassword, - allowRegister, - allowExternalIDP, - forceMFA bool, - passwordlessType PasswordlessType, -) *AddedEvent { - return &AddedEvent{ - BaseEvent: *base, - AllowExternalIDP: allowExternalIDP, - AllowRegister: allowRegister, - AllowUserNamePassword: allowUserNamePassword, - ForceMFA: forceMFA, - PasswordlessType: passwordlessType, - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "POLIC-nWndT", "unable to unmarshal policy") - } - - return e, nil -} - -type ChangedEvent struct { - eventstore.BaseEvent `json:"-"` - - AllowUserNamePassword bool `json:"allowUsernamePassword,omitempty"` - AllowRegister bool `json:"allowRegister"` - AllowExternalIDP bool `json:"allowExternalIdp"` - ForceMFA bool `json:"forceMFA"` - PasswordlessType PasswordlessType `json:"passwordlessType"` -} - -func (e *ChangedEvent) Data() interface{} { - return e -} - -func NewChangedEvent( - base *eventstore.BaseEvent, - current *WriteModel, - allowUserNamePassword, - allowRegister, - allowExternalIDP, - forceMFA bool, - passwordlessType PasswordlessType, -) *ChangedEvent { - - e := &ChangedEvent{ - BaseEvent: *base, - } - - if current.AllowUserNamePassword != allowUserNamePassword { - e.AllowUserNamePassword = allowUserNamePassword - } - if current.AllowRegister != allowRegister { - e.AllowRegister = allowRegister - } - if current.AllowExternalIDP != allowExternalIDP { - e.AllowExternalIDP = allowExternalIDP - } - if current.ForceMFA != forceMFA { - e.ForceMFA = forceMFA - } - if current.PasswordlessType != passwordlessType { - e.PasswordlessType = passwordlessType - } - - return e -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ChangedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "POLIC-ehssl", "unable to unmarshal policy") - } - - return e, nil -} - -type RemovedEvent struct { - eventstore.BaseEvent `json:"-"` -} - -func (e *RemovedEvent) Data() interface{} { - return nil -} - -func NewRemovedEvent(base *eventstore.BaseEvent) *RemovedEvent { - return &RemovedEvent{ - BaseEvent: *base, - } -} - -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &RemovedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - }, nil -} diff --git a/internal/v2/repository/policy/login/idpprovider/events.go b/internal/v2/repository/policy/login/idpprovider/events.go deleted file mode 100644 index 0e74e03563..0000000000 --- a/internal/v2/repository/policy/login/idpprovider/events.go +++ /dev/null @@ -1,83 +0,0 @@ -package idpprovider - -import ( - "encoding/json" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -const ( - AddedEventType = "idpprovider.added" - RemovedEventType = "idpprovider.removed" -) - -type AddedEvent struct { - eventstore.BaseEvent - - IDPConfigID string `json:"idpConfigId"` - IDPProviderType Type `json:"idpProviderType"` -} - -func (e *AddedEvent) Data() interface{} { - return e -} - -func NewAddedEvent( - base *eventstore.BaseEvent, - idpConfigID string, - idpProviderType Type, -) *AddedEvent { - - return &AddedEvent{ - *base, - idpConfigID, - idpProviderType, - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "PROVI-bfNnp", "Errors.Internal") - } - - return e, nil -} - -type RemovedEvent struct { - eventstore.BaseEvent - - IDPConfigID string `json:"idpConfigId"` -} - -func (e *RemovedEvent) Data() interface{} { - return e -} - -func NewRemovedEvent( - base *eventstore.BaseEvent, - idpConfigID string, -) *RemovedEvent { - return &RemovedEvent{ - BaseEvent: *base, - IDPConfigID: idpConfigID, - } -} - -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &RemovedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - - err := json.Unmarshal(event.Data, e) - if err != nil { - return nil, errors.ThrowInternal(err, "PROVI-6H0KQ", "Errors.Internal") - } - - return e, nil -} diff --git a/internal/v2/repository/policy/login/idpprovider/provider.go b/internal/v2/repository/policy/login/idpprovider/provider.go deleted file mode 100644 index 0eb1239255..0000000000 --- a/internal/v2/repository/policy/login/idpprovider/provider.go +++ /dev/null @@ -1,14 +0,0 @@ -package idpprovider - -type Type int8 - -const ( - TypeSystem Type = iota - TypeOrg - - typeCount -) - -func (f Type) Valid() bool { - return f >= 0 && f < typeCount -} diff --git a/internal/v2/repository/policy/login/idpprovider/write_model.go b/internal/v2/repository/policy/login/idpprovider/write_model.go deleted file mode 100644 index 9db97ae52a..0000000000 --- a/internal/v2/repository/policy/login/idpprovider/write_model.go +++ /dev/null @@ -1,23 +0,0 @@ -package idpprovider - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" -) - -type WriteModel struct { - eventstore.WriteModel - - IDPConfigID string - IDPProviderType Type -} - -func (wm *WriteModel) Reduce() error { - for _, event := range wm.Events { - switch e := event.(type) { - case *AddedEvent: - wm.IDPConfigID = e.IDPConfigID - wm.IDPProviderType = e.IDPProviderType - } - } - return wm.WriteModel.Reduce() -} diff --git a/internal/v2/repository/policy/login/login.go b/internal/v2/repository/policy/login/login.go deleted file mode 100644 index 1092157792..0000000000 --- a/internal/v2/repository/policy/login/login.go +++ /dev/null @@ -1,8 +0,0 @@ -package login - -type PasswordlessType int32 - -const ( - PasswordlessTypeNotAllowed PasswordlessType = iota - PasswordlessTypeAllowed -) diff --git a/internal/v2/repository/policy/org_iam/read_model.go b/internal/v2/repository/policy/org_iam/read_model.go deleted file mode 100644 index f3b7bd853f..0000000000 --- a/internal/v2/repository/policy/org_iam/read_model.go +++ /dev/null @@ -1,21 +0,0 @@ -package org_iam - -import "github.com/caos/zitadel/internal/eventstore/v2" - -type ReadModel struct { - eventstore.ReadModel - - UserLoginMustBeDomain bool -} - -func (rm *ReadModel) Reduce() error { - for _, event := range rm.Events { - switch e := event.(type) { - case *AddedEvent: - rm.UserLoginMustBeDomain = e.UserLoginMustBeDomain - case *ChangedEvent: - rm.UserLoginMustBeDomain = e.UserLoginMustBeDomain - } - } - return rm.ReadModel.Reduce() -} diff --git a/internal/v2/repository/policy/org_iam/write_model.go b/internal/v2/repository/policy/org_iam/write_model.go deleted file mode 100644 index 58903030ee..0000000000 --- a/internal/v2/repository/policy/org_iam/write_model.go +++ /dev/null @@ -1,21 +0,0 @@ -package org_iam - -import "github.com/caos/zitadel/internal/eventstore/v2" - -type WriteModel struct { - eventstore.WriteModel - - UserLoginMustBeDomain bool -} - -func (wm *WriteModel) Reduce() error { - for _, event := range wm.Events { - switch e := event.(type) { - case *AddedEvent: - wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain - case *ChangedEvent: - wm.UserLoginMustBeDomain = e.UserLoginMustBeDomain - } - } - return wm.WriteModel.Reduce() -} diff --git a/internal/v2/repository/policy/login/factors/events.go b/internal/v2/repository/policy/policy_login_factors.go similarity index 86% rename from internal/v2/repository/policy/login/factors/events.go rename to internal/v2/repository/policy/policy_login_factors.go index ea834dc41d..f1e5bd1106 100644 --- a/internal/v2/repository/policy/login/factors/events.go +++ b/internal/v2/repository/policy/policy_login_factors.go @@ -1,14 +1,15 @@ -package factors +package policy import ( "encoding/json" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" ) const ( - loginPolicySecondFactorPrefix = "policy.login.secondfactor." + loginPolicySecondFactorPrefix = loginPolicyPrefix + "secondfactor." LoginPolicySecondFactorAddedEventType = loginPolicySecondFactorPrefix + "added" LoginPolicySecondFactorRemovedEventType = loginPolicySecondFactorPrefix + "removed" @@ -20,12 +21,12 @@ const ( type SecondFactorAddedEvent struct { eventstore.BaseEvent `json:"-"` - MFAType SecondFactorType `json:"mfaType"` + MFAType domain.SecondFactorType `json:"mfaType"` } func NewSecondFactorAddedEvent( base *eventstore.BaseEvent, - mfaType SecondFactorType, + mfaType domain.SecondFactorType, ) *SecondFactorAddedEvent { return &SecondFactorAddedEvent{ BaseEvent: *base, @@ -52,12 +53,12 @@ func (e *SecondFactorAddedEvent) Data() interface{} { type SecondFactorRemovedEvent struct { eventstore.BaseEvent `json:"-"` - MFAType SecondFactorType `json:"mfaType"` + MFAType domain.SecondFactorType `json:"mfaType"` } func NewSecondFactorRemovedEvent( base *eventstore.BaseEvent, - mfaType SecondFactorType, + mfaType domain.SecondFactorType, ) *SecondFactorRemovedEvent { return &SecondFactorRemovedEvent{ BaseEvent: *base, @@ -85,12 +86,12 @@ func (e *SecondFactorRemovedEvent) Data() interface{} { type MultiFactorAddedEvent struct { eventstore.BaseEvent `json:"-"` - MFAType MultiFactorType `json:"mfaType"` + MFAType domain.MultiFactorType `json:"mfaType"` } func NewMultiFactorAddedEvent( base *eventstore.BaseEvent, - mfaType MultiFactorType, + mfaType domain.MultiFactorType, ) *MultiFactorAddedEvent { return &MultiFactorAddedEvent{ BaseEvent: *base, @@ -117,12 +118,12 @@ func (e *MultiFactorAddedEvent) Data() interface{} { type MultiFactorRemovedEvent struct { eventstore.BaseEvent `json:"-"` - MFAType MultiFactorType `json:"mfaType"` + MFAType domain.MultiFactorType `json:"mfaType"` } func NewMultiFactorRemovedEvent( base *eventstore.BaseEvent, - mfaType MultiFactorType, + mfaType domain.MultiFactorType, ) *MultiFactorRemovedEvent { return &MultiFactorRemovedEvent{ BaseEvent: *base, diff --git a/internal/v2/repository/policy/policy_login_identity_provider.go b/internal/v2/repository/policy/policy_login_identity_provider.go new file mode 100644 index 0000000000..ecda6127ea --- /dev/null +++ b/internal/v2/repository/policy/policy_login_identity_provider.go @@ -0,0 +1,85 @@ +package policy + +import ( + "encoding/json" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" +) + +const ( + loginPolicyIDPProviderPrevix = loginPolicyPrefix + "idpprovider." + LoginPolicyIDPProviderAddedType = loginPolicyIDPProviderPrevix + "added" + LoginPolicyIDPProviderRemovedType = loginPolicyIDPProviderPrevix + "removed" +) + +type IdentityProviderAddedEvent struct { + eventstore.BaseEvent + + IDPConfigID string `json:"idpConfigId"` + IDPProviderType domain.IdentityProviderType `json:"idpProviderType"` +} + +func (e *IdentityProviderAddedEvent) Data() interface{} { + return e +} + +func NewIdentityProviderAddedEvent( + base *eventstore.BaseEvent, + idpConfigID string, + idpProviderType domain.IdentityProviderType, +) *IdentityProviderAddedEvent { + + return &IdentityProviderAddedEvent{ + *base, + idpConfigID, + idpProviderType, + } +} + +func IdentityProviderAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &IdentityProviderAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "PROVI-bfNnp", "Errors.Internal") + } + + return e, nil +} + +type IdentityProviderRemovedEvent struct { + eventstore.BaseEvent + + IDPConfigID string `json:"idpConfigId"` +} + +func (e *IdentityProviderRemovedEvent) Data() interface{} { + return e +} + +func NewIdentityProviderRemovedEvent( + base *eventstore.BaseEvent, + idpConfigID string, +) *IdentityProviderRemovedEvent { + return &IdentityProviderRemovedEvent{ + BaseEvent: *base, + IDPConfigID: idpConfigID, + } +} + +func IdentityProviderRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &IdentityProviderRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "PROVI-6H0KQ", "Errors.Internal") + } + + return e, nil +} diff --git a/internal/v2/repository/policy/org_iam/events.go b/internal/v2/repository/policy/policy_org_iam.go similarity index 64% rename from internal/v2/repository/policy/org_iam/events.go rename to internal/v2/repository/policy/policy_org_iam.go index 7821a4e6db..2718c7e47d 100644 --- a/internal/v2/repository/policy/org_iam/events.go +++ b/internal/v2/repository/policy/policy_org_iam.go @@ -1,4 +1,4 @@ -package org_iam +package policy import ( "encoding/json" @@ -12,29 +12,29 @@ const ( OrgIAMPolicyChangedEventType = "policy.org.iam.changed" ) -type AddedEvent struct { +type OrgIAMPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` UserLoginMustBeDomain bool `json:"userLoginMustBeDomain"` } -func (e *AddedEvent) Data() interface{} { +func (e *OrgIAMPolicyAddedEvent) Data() interface{} { return e } -func NewAddedEvent( +func NewOrgIAMPolicyAddedEvent( base *eventstore.BaseEvent, userLoginMustBeDomain bool, -) *AddedEvent { +) *OrgIAMPolicyAddedEvent { - return &AddedEvent{ + return &OrgIAMPolicyAddedEvent{ BaseEvent: *base, UserLoginMustBeDomain: userLoginMustBeDomain, } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ +func OrgIAMPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &OrgIAMPolicyAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -46,32 +46,26 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return e, nil } -type ChangedEvent struct { +type OrgIAMPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` UserLoginMustBeDomain bool `json:"userLoginMustBeDomain"` } -func (e *ChangedEvent) Data() interface{} { +func (e *OrgIAMPolicyChangedEvent) Data() interface{} { return e } -func NewChangedEvent( +func NewOrgIAMPolicyChangedEvent( base *eventstore.BaseEvent, - current *WriteModel, - userLoginMustBeDomain bool, -) *ChangedEvent { - e := &ChangedEvent{ +) *OrgIAMPolicyChangedEvent { + return &OrgIAMPolicyChangedEvent{ BaseEvent: *base, } - if current.UserLoginMustBeDomain != userLoginMustBeDomain { - e.UserLoginMustBeDomain = userLoginMustBeDomain - } - return e } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ChangedEvent{ +func OrgIAMPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &OrgIAMPolicyChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } diff --git a/internal/v2/repository/policy/password_age/events.go b/internal/v2/repository/policy/policy_password_age.go similarity index 60% rename from internal/v2/repository/policy/password_age/events.go rename to internal/v2/repository/policy/policy_password_age.go index 9cebd54d58..da07913a7c 100644 --- a/internal/v2/repository/policy/password_age/events.go +++ b/internal/v2/repository/policy/policy_password_age.go @@ -1,4 +1,4 @@ -package password_age +package policy import ( "encoding/json" @@ -13,32 +13,32 @@ const ( PasswordAgePolicyRemovedEventType = "policy.password.age.removed" ) -type AddedEvent struct { +type PasswordAgePolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` ExpireWarnDays uint64 `json:"expireWarnDays"` MaxAgeDays uint64 `json:"maxAgeDays"` } -func (e *AddedEvent) Data() interface{} { +func (e *PasswordAgePolicyAddedEvent) Data() interface{} { return e } -func NewAddedEvent( +func NewPasswordAgePolicyAddedEvent( base *eventstore.BaseEvent, expireWarnDays, maxAgeDays uint64, -) *AddedEvent { +) *PasswordAgePolicyAddedEvent { - return &AddedEvent{ + return &PasswordAgePolicyAddedEvent{ BaseEvent: *base, ExpireWarnDays: expireWarnDays, MaxAgeDays: maxAgeDays, } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ +func PasswordAgePolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordAgePolicyAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -50,40 +50,27 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return e, nil } -type ChangedEvent struct { +type PasswordAgePolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` ExpireWarnDays uint64 `json:"expireWarnDays,omitempty"` MaxAgeDays uint64 `json:"maxAgeDays,omitempty"` } -func (e *ChangedEvent) Data() interface{} { +func (e *PasswordAgePolicyChangedEvent) Data() interface{} { return e } -func NewChangedEvent( +func NewPasswordAgePolicyChangedEvent( base *eventstore.BaseEvent, - current *WriteModel, - expireWarnDays, - maxAgeDays uint64, -) *ChangedEvent { - - e := &ChangedEvent{ +) *PasswordAgePolicyChangedEvent { + return &PasswordAgePolicyChangedEvent{ BaseEvent: *base, } - - if current.ExpireWarnDays != expireWarnDays { - e.ExpireWarnDays = expireWarnDays - } - if current.MaxAgeDays != maxAgeDays { - e.MaxAgeDays = maxAgeDays - } - - return e } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ChangedEvent{ +func PasswordAgePolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordAgePolicyChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -95,24 +82,24 @@ func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) return e, nil } -type RemovedEvent struct { +type PasswordAgePolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *RemovedEvent) Data() interface{} { +func (e *PasswordAgePolicyRemovedEvent) Data() interface{} { return nil } -func NewRemovedEvent( +func NewPasswordAgePolicyRemovedEvent( base *eventstore.BaseEvent, -) *RemovedEvent { - return &RemovedEvent{ +) *PasswordAgePolicyRemovedEvent { + return &PasswordAgePolicyRemovedEvent{ BaseEvent: *base, } } -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &RemovedEvent{ +func PasswordAgePolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordAgePolicyRemovedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } diff --git a/internal/v2/repository/policy/password_complexity/events.go b/internal/v2/repository/policy/policy_password_complexity.go similarity index 59% rename from internal/v2/repository/policy/password_complexity/events.go rename to internal/v2/repository/policy/policy_password_complexity.go index ae903c917c..96a161f59f 100644 --- a/internal/v2/repository/policy/password_complexity/events.go +++ b/internal/v2/repository/policy/policy_password_complexity.go @@ -1,4 +1,4 @@ -package password_complexity +package policy import ( "encoding/json" @@ -13,7 +13,7 @@ const ( PasswordComplexityPolicyRemovedEventType = "policy.password.complexity.removed" ) -type AddedEvent struct { +type PasswordComplexityPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` MinLength uint64 `json:"minLength,omitempty"` @@ -23,19 +23,19 @@ type AddedEvent struct { HasSymbol bool `json:"hasSymbol"` } -func (e *AddedEvent) Data() interface{} { +func (e *PasswordComplexityPolicyAddedEvent) Data() interface{} { return e } -func NewAddedEvent( +func NewPasswordComplexityPolicyAddedEvent( base *eventstore.BaseEvent, minLength uint64, hasLowerCase, hasUpperCase, hasNumber, hasSymbol bool, -) *AddedEvent { - return &AddedEvent{ +) *PasswordComplexityPolicyAddedEvent { + return &PasswordComplexityPolicyAddedEvent{ BaseEvent: *base, MinLength: minLength, HasLowercase: hasLowerCase, @@ -45,8 +45,8 @@ func NewAddedEvent( } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ +func PasswordComplexityPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordComplexityPolicyAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -58,7 +58,7 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return e, nil } -type ChangedEvent struct { +type PasswordComplexityPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` MinLength uint64 `json:"minLength"` @@ -68,45 +68,20 @@ type ChangedEvent struct { HasSymbol bool `json:"hasSymbol"` } -func (e *ChangedEvent) Data() interface{} { +func (e *PasswordComplexityPolicyChangedEvent) Data() interface{} { return e } -func NewChangedEvent( +func NewPasswordComplexityPolicyChangedEvent( base *eventstore.BaseEvent, - current *WriteModel, - minLength uint64, - hasLowerCase, - hasUpperCase, - hasNumber, - hasSymbol bool, -) *ChangedEvent { - - e := &ChangedEvent{ +) *PasswordComplexityPolicyChangedEvent { + return &PasswordComplexityPolicyChangedEvent{ BaseEvent: *base, } - - if current.MinLength != minLength { - e.MinLength = minLength - } - if current.HasLowercase != hasLowerCase { - e.HasLowercase = hasLowerCase - } - if current.HasUpperCase != hasUpperCase { - e.HasUpperCase = hasUpperCase - } - if current.HasNumber != hasNumber { - e.HasNumber = hasNumber - } - if current.HasSymbol != hasSymbol { - e.HasSymbol = hasSymbol - } - - return e } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ChangedEvent{ +func PasswordComplexityPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordComplexityPolicyChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -118,22 +93,22 @@ func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) return e, nil } -type RemovedEvent struct { +type PasswordComplexityPolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *RemovedEvent) Data() interface{} { +func (e *PasswordComplexityPolicyRemovedEvent) Data() interface{} { return nil } -func NewRemovedEvent(base *eventstore.BaseEvent) *RemovedEvent { - return &RemovedEvent{ +func NewPasswordComplexityPolicyRemovedEvent(base *eventstore.BaseEvent) *PasswordComplexityPolicyRemovedEvent { + return &PasswordComplexityPolicyRemovedEvent{ BaseEvent: *base, } } -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &RemovedEvent{ +func PasswordComplexityPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &PasswordComplexityPolicyRemovedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } diff --git a/internal/v2/repository/policy/password_lockout/events.go b/internal/v2/repository/policy/policy_password_lockout.go similarity index 58% rename from internal/v2/repository/policy/password_lockout/events.go rename to internal/v2/repository/policy/policy_password_lockout.go index 505b7fa4fc..00d80194cf 100644 --- a/internal/v2/repository/policy/password_lockout/events.go +++ b/internal/v2/repository/policy/policy_password_lockout.go @@ -1,4 +1,4 @@ -package password_lockout +package policy import ( "encoding/json" @@ -13,32 +13,32 @@ const ( PasswordLockoutPolicyRemovedEventType = "policy.password.lockout.removed" ) -type AddedEvent struct { +type PasswordLockoutPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` MaxAttempts uint64 `json:"maxAttempts,omitempty"` ShowLockOutFailures bool `json:"showLockOutFailures"` } -func (e *AddedEvent) Data() interface{} { +func (e *PasswordLockoutPolicyAddedEvent) Data() interface{} { return e } -func NewAddedEvent( +func NewPasswordLockoutPolicyAddedEvent( base *eventstore.BaseEvent, maxAttempts uint64, showLockOutFailures bool, -) *AddedEvent { +) *PasswordLockoutPolicyAddedEvent { - return &AddedEvent{ + return &PasswordLockoutPolicyAddedEvent{ BaseEvent: *base, MaxAttempts: maxAttempts, ShowLockOutFailures: showLockOutFailures, } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ +func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordLockoutPolicyAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -50,40 +50,27 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return e, nil } -type ChangedEvent struct { +type PasswordLockoutPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` MaxAttempts uint64 `json:"maxAttempts,omitempty"` ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"` } -func (e *ChangedEvent) Data() interface{} { +func (e *PasswordLockoutPolicyChangedEvent) Data() interface{} { return e } -func NewChangedEvent( +func NewPasswordLockoutPolicyChangedEvent( base *eventstore.BaseEvent, - current *WriteModel, - maxAttempts uint64, - showLockOutFailures bool, -) *ChangedEvent { - - e := &ChangedEvent{ +) *PasswordLockoutPolicyChangedEvent { + return &PasswordLockoutPolicyChangedEvent{ BaseEvent: *base, } - - if current.MaxAttempts != maxAttempts { - e.MaxAttempts = maxAttempts - } - if current.ShowLockOutFailures != showLockOutFailures { - e.ShowLockOutFailures = showLockOutFailures - } - - return e } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &ChangedEvent{ +func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordLockoutPolicyChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -95,25 +82,25 @@ func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) return e, nil } -type RemovedEvent struct { +type PasswordLockoutPolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *RemovedEvent) Data() interface{} { +func (e *PasswordLockoutPolicyRemovedEvent) Data() interface{} { return nil } -func NewRemovedEvent( +func NewPasswordLockoutPolicyRemovedEvent( base *eventstore.BaseEvent, -) *RemovedEvent { +) *PasswordLockoutPolicyRemovedEvent { - return &RemovedEvent{ + return &PasswordLockoutPolicyRemovedEvent{ BaseEvent: *base, } } -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &RemovedEvent{ +func PasswordLockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &PasswordLockoutPolicyRemovedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } diff --git a/internal/v2/repository/user/aggregate.go b/internal/v2/repository/user/aggregate.go index b002e71fc2..3147bec8ff 100644 --- a/internal/v2/repository/user/aggregate.go +++ b/internal/v2/repository/user/aggregate.go @@ -29,21 +29,3 @@ func NewAggregate( ), } } - -func AggregateFromWriteModel(wm *eventstore.WriteModel) *Aggregate { - return &Aggregate{ - Aggregate: *eventstore.AggregateFromWriteModel(wm, AggregateType, AggregateVersion), - } -} - -func AggregateFromReadModel(rm *ReadModel) *Aggregate { - return &Aggregate{ - Aggregate: *eventstore.NewAggregate( - rm.AggregateID, - AggregateType, - rm.ResourceOwner, - AggregateVersion, - rm.ProcessedSequence, - ), - } -} diff --git a/internal/v2/repository/user/eventstore.go b/internal/v2/repository/user/eventstore.go index 73e2ecf869..69083a4d84 100644 --- a/internal/v2/repository/user/eventstore.go +++ b/internal/v2/repository/user/eventstore.go @@ -2,113 +2,100 @@ package user import ( "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/user/human" - "github.com/caos/zitadel/internal/v2/repository/user/human/address" - "github.com/caos/zitadel/internal/v2/repository/user/human/email" - "github.com/caos/zitadel/internal/v2/repository/user/human/external_idp" - "github.com/caos/zitadel/internal/v2/repository/user/human/mfa" - "github.com/caos/zitadel/internal/v2/repository/user/human/mfa/otp" - "github.com/caos/zitadel/internal/v2/repository/user/human/mfa/web_auth_n" - "github.com/caos/zitadel/internal/v2/repository/user/human/password" - "github.com/caos/zitadel/internal/v2/repository/user/human/phone" - "github.com/caos/zitadel/internal/v2/repository/user/human/profile" - "github.com/caos/zitadel/internal/v2/repository/user/machine" - "github.com/caos/zitadel/internal/v2/repository/user/machine/keys" - "github.com/caos/zitadel/internal/v2/repository/user/v1" ) func RegisterEventMappers(es *eventstore.Eventstore) { - es.RegisterFilterEventMapper(v1.UserV1AddedType, human.AddedEventMapper). - RegisterFilterEventMapper(v1.UserV1RegisteredType, human.RegisteredEventMapper). - RegisterFilterEventMapper(v1.UserV1InitialCodeAddedType, human.InitialCodeAddedEventMapper). - RegisterFilterEventMapper(v1.UserV1InitialCodeSentType, human.InitialCodeSentEventMapper). - RegisterFilterEventMapper(v1.UserV1InitializedCheckSucceededType, human.InitializedCheckSucceededEventMapper). - RegisterFilterEventMapper(v1.UserV1InitializedCheckFailedType, human.InitializedCheckFailedEventMapper). - RegisterFilterEventMapper(v1.UserV1SignedOutType, human.SignedOutEventMapper). - RegisterFilterEventMapper(v1.UserV1PasswordChangedType, password.ChangedEventMapper). - RegisterFilterEventMapper(v1.UserV1PasswordCodeAddedType, password.CodeAddedEventMapper). - RegisterFilterEventMapper(v1.UserV1PasswordCodeSentType, password.CodeSentEventMapper). - RegisterFilterEventMapper(v1.UserV1PasswordCheckSucceededType, password.CheckSucceededEventMapper). - RegisterFilterEventMapper(v1.UserV1PasswordCheckFailedType, password.CheckFailedEventMapper). - RegisterFilterEventMapper(v1.UserV1EmailChangedType, email.ChangedEventMapper). - RegisterFilterEventMapper(v1.UserV1EmailVerifiedType, email.VerifiedEventMapper). - RegisterFilterEventMapper(v1.UserV1EmailVerificationFailedType, email.VerificationFailedEventMapper). - RegisterFilterEventMapper(v1.UserV1EmailCodeAddedType, email.CodeAddedEventMapper). - RegisterFilterEventMapper(v1.UserV1EmailCodeSentType, email.CodeSentEventMapper). - RegisterFilterEventMapper(v1.UserV1PhoneChangedType, phone.ChangedEventMapper). - RegisterFilterEventMapper(v1.UserV1PhoneRemovedType, phone.RemovedEventMapper). - RegisterFilterEventMapper(v1.UserV1PhoneVerifiedType, phone.VerifiedEventMapper). - RegisterFilterEventMapper(v1.UserV1PhoneVerificationFailedType, phone.VerificationFailedEventMapper). - RegisterFilterEventMapper(v1.UserV1PhoneCodeAddedType, phone.CodeAddedEventMapper). - RegisterFilterEventMapper(v1.UserV1PhoneCodeSentType, phone.CodeSentEventMapper). - RegisterFilterEventMapper(v1.UserV1ProfileChangedType, profile.ChangedEventMapper). - RegisterFilterEventMapper(v1.UserV1AddressChangedType, address.ChangedEventMapper). - RegisterFilterEventMapper(v1.UserV1MFAInitSkippedType, mfa.InitSkippedEventMapper). - RegisterFilterEventMapper(v1.UserV1MFAOTPAddedType, otp.AddedEventMapper). - RegisterFilterEventMapper(v1.UserV1MFAOTPVerifiedType, otp.VerifiedEventMapper). - RegisterFilterEventMapper(v1.UserV1MFAOTPRemovedType, otp.RemovedEventMapper). - RegisterFilterEventMapper(v1.UserV1MFAOTPCheckSucceededType, otp.CheckSucceededEventMapper). - RegisterFilterEventMapper(v1.UserV1MFAOTPCheckFailedType, otp.CheckFailedEventMapper). - RegisterFilterEventMapper(UserLockedType, LockedEventMapper). - RegisterFilterEventMapper(UserUnlockedType, LockedEventMapper). - RegisterFilterEventMapper(UserDeactivatedType, DeactivatedEventMapper). - RegisterFilterEventMapper(UserReactivatedType, ReactivatedEventMapper). - RegisterFilterEventMapper(UserRemovedType, RemovedEventMapper). - RegisterFilterEventMapper(UserTokenAddedType, TokenAddedEventMapper). + es.RegisterFilterEventMapper(UserV1AddedType, HumanAddedEventMapper). + RegisterFilterEventMapper(UserV1RegisteredType, HumanRegisteredEventMapper). + RegisterFilterEventMapper(UserV1InitialCodeAddedType, HumanInitialCodeAddedEventMapper). + RegisterFilterEventMapper(UserV1InitialCodeSentType, HumanInitialCodeSentEventMapper). + RegisterFilterEventMapper(UserV1InitializedCheckSucceededType, HumanInitializedCheckSucceededEventMapper). + RegisterFilterEventMapper(UserV1InitializedCheckFailedType, HumanInitializedCheckFailedEventMapper). + RegisterFilterEventMapper(UserV1SignedOutType, HumanSignedOutEventMapper). + RegisterFilterEventMapper(UserV1PasswordChangedType, HumanPasswordChangedEventMapper). + RegisterFilterEventMapper(UserV1PasswordCodeAddedType, HumanPasswordCodeAddedEventMapper). + RegisterFilterEventMapper(UserV1PasswordCodeSentType, HumanPasswordCodeSentEventMapper). + RegisterFilterEventMapper(UserV1PasswordCheckSucceededType, HumanPasswordCheckSucceededEventMapper). + RegisterFilterEventMapper(UserV1PasswordCheckFailedType, HumanPasswordCheckFailedEventMapper). + RegisterFilterEventMapper(UserV1EmailChangedType, HumanEmailChangedEventMapper). + RegisterFilterEventMapper(UserV1EmailVerifiedType, HumanEmailVerifiedEventMapper). + RegisterFilterEventMapper(UserV1EmailVerificationFailedType, HumanEmailVerificationFailedEventMapper). + RegisterFilterEventMapper(UserV1EmailCodeAddedType, HumanEmailCodeAddedEventMapper). + RegisterFilterEventMapper(UserV1EmailCodeSentType, HumanEmailCodeSentEventMapper). + RegisterFilterEventMapper(UserV1PhoneChangedType, HumanPhoneChangedEventMapper). + RegisterFilterEventMapper(UserV1PhoneRemovedType, HumanPhoneRemovedEventMapper). + RegisterFilterEventMapper(UserV1PhoneVerifiedType, HumanPhoneVerifiedEventMapper). + RegisterFilterEventMapper(UserV1PhoneVerificationFailedType, HumanPhoneVerificationFailedEventMapper). + RegisterFilterEventMapper(UserV1PhoneCodeAddedType, HumanPhoneCodeAddedEventMapper). + RegisterFilterEventMapper(UserV1PhoneCodeSentType, HumanPhoneCodeSentEventMapper). + RegisterFilterEventMapper(UserV1ProfileChangedType, HumanProfileChangedEventMapper). + RegisterFilterEventMapper(UserV1AddressChangedType, HumanAddressChangedEventMapper). + RegisterFilterEventMapper(UserV1MFAInitSkippedType, HumanMFAInitSkippedEventMapper). + RegisterFilterEventMapper(UserV1MFAOTPAddedType, HumanOTPAddedEventMapper). + RegisterFilterEventMapper(UserV1MFAOTPVerifiedType, HumanOTPVerifiedEventMapper). + RegisterFilterEventMapper(UserV1MFAOTPRemovedType, HumanOTPRemovedEventMapper). + RegisterFilterEventMapper(UserV1MFAOTPCheckSucceededType, HumanOTPCheckSucceededEventMapper). + RegisterFilterEventMapper(UserV1MFAOTPCheckFailedType, HumanOTPCheckFailedEventMapper). + RegisterFilterEventMapper(UserLockedType, UserLockedEventMapper). + RegisterFilterEventMapper(UserUnlockedType, UserLockedEventMapper). + RegisterFilterEventMapper(UserDeactivatedType, UserDeactivatedEventMapper). + RegisterFilterEventMapper(UserReactivatedType, UserReactivatedEventMapper). + RegisterFilterEventMapper(UserRemovedType, UserRemovedEventMapper). + RegisterFilterEventMapper(UserTokenAddedType, UserTokenAddedEventMapper). RegisterFilterEventMapper(UserDomainClaimedType, DomainClaimedEventMapper). RegisterFilterEventMapper(UserDomainClaimedSentType, DomainClaimedEventMapper). RegisterFilterEventMapper(UserUserNameChangedType, UsernameChangedEventMapper). - RegisterFilterEventMapper(human.HumanAddedType, human.AddedEventMapper). - RegisterFilterEventMapper(human.HumanRegisteredType, human.RegisteredEventMapper). - RegisterFilterEventMapper(human.HumanInitialCodeAddedType, human.InitialCodeAddedEventMapper). - RegisterFilterEventMapper(human.HumanInitialCodeSentType, human.InitialCodeSentEventMapper). - RegisterFilterEventMapper(human.HumanInitializedCheckSucceededType, human.InitializedCheckSucceededEventMapper). - RegisterFilterEventMapper(human.HumanInitializedCheckFailedType, human.InitializedCheckFailedEventMapper). - RegisterFilterEventMapper(human.HumanSignedOutType, human.SignedOutEventMapper). - RegisterFilterEventMapper(password.HumanPasswordChangedType, password.ChangedEventMapper). - RegisterFilterEventMapper(password.HumanPasswordCodeAddedType, password.CodeAddedEventMapper). - RegisterFilterEventMapper(password.HumanPasswordCodeSentType, password.CodeSentEventMapper). - RegisterFilterEventMapper(password.HumanPasswordCheckSucceededType, password.CheckSucceededEventMapper). - RegisterFilterEventMapper(password.HumanPasswordCheckFailedType, password.CheckFailedEventMapper). - RegisterFilterEventMapper(external_idp.HumanExternalIDPAddedType, external_idp.AddedEventMapper). - RegisterFilterEventMapper(external_idp.HumanExternalIDPRemovedType, external_idp.RemovedEventMapper). - RegisterFilterEventMapper(external_idp.HumanExternalIDPCascadeRemovedType, external_idp.CascadeRemovedEventMapper). - RegisterFilterEventMapper(external_idp.HumanExternalLoginCheckSucceededType, external_idp.CheckSucceededEventMapper). - RegisterFilterEventMapper(email.HumanEmailChangedType, email.ChangedEventMapper). - RegisterFilterEventMapper(email.HumanEmailVerifiedType, email.VerifiedEventMapper). - RegisterFilterEventMapper(email.HumanEmailVerificationFailedType, email.VerificationFailedEventMapper). - RegisterFilterEventMapper(email.HumanEmailCodeAddedType, email.CodeAddedEventMapper). - RegisterFilterEventMapper(email.HumanEmailCodeSentType, email.CodeSentEventMapper). - RegisterFilterEventMapper(phone.HumanPhoneChangedType, phone.ChangedEventMapper). - RegisterFilterEventMapper(phone.HumanPhoneRemovedType, phone.RemovedEventMapper). - RegisterFilterEventMapper(phone.HumanPhoneVerifiedType, phone.VerifiedEventMapper). - RegisterFilterEventMapper(phone.HumanPhoneVerificationFailedType, phone.VerificationFailedEventMapper). - RegisterFilterEventMapper(phone.HumanPhoneCodeAddedType, phone.CodeAddedEventMapper). - RegisterFilterEventMapper(phone.HumanPhoneCodeSentType, phone.CodeSentEventMapper). - RegisterFilterEventMapper(profile.HumanProfileChangedType, profile.ChangedEventMapper). - RegisterFilterEventMapper(address.HumanAddressChangedType, address.ChangedEventMapper). - RegisterFilterEventMapper(mfa.HumanMFAInitSkippedType, mfa.InitSkippedEventMapper). - RegisterFilterEventMapper(otp.HumanMFAOTPAddedType, otp.AddedEventMapper). - RegisterFilterEventMapper(otp.HumanMFAOTPVerifiedType, otp.VerifiedEventMapper). - RegisterFilterEventMapper(otp.HumanMFAOTPRemovedType, otp.RemovedEventMapper). - RegisterFilterEventMapper(otp.HumanMFAOTPCheckSucceededType, otp.CheckSucceededEventMapper). - RegisterFilterEventMapper(otp.HumanMFAOTPCheckFailedType, otp.CheckFailedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanU2FTokenAddedType, web_auth_n.AddedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanU2FTokenVerifiedType, web_auth_n.VerifiedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanU2FTokenSignCountChangedType, web_auth_n.SignCountChangedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanU2FTokenRemovedType, web_auth_n.RemovedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanU2FTokenBeginLoginType, web_auth_n.BeginLoginEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanU2FTokenCheckSucceededType, web_auth_n.CheckSucceededEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanU2FTokenCheckFailedType, web_auth_n.CheckFailedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanPasswordlessTokenAddedType, web_auth_n.AddedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanPasswordlessTokenVerifiedType, web_auth_n.VerifiedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanPasswordlessTokenSignCountChangedType, web_auth_n.SignCountChangedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanPasswordlessTokenRemovedType, web_auth_n.RemovedEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanPasswordlessTokenBeginLoginType, web_auth_n.BeginLoginEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanPasswordlessTokenCheckSucceededType, web_auth_n.CheckSucceededEventMapper). - RegisterFilterEventMapper(web_auth_n.HumanPasswordlessTokenCheckFailedType, web_auth_n.CheckFailedEventMapper). - RegisterFilterEventMapper(machine.MachineAddedEventType, machine.AddedEventMapper). - RegisterFilterEventMapper(machine.MachineChangedEventType, machine.ChangedEventMapper). - RegisterFilterEventMapper(keys.MachineKeyAddedEventType, keys.AddedEventMapper). - RegisterFilterEventMapper(keys.MachineKeyRemovedEventType, keys.RemovedEventMapper) + RegisterFilterEventMapper(HumanAddedType, HumanAddedEventMapper). + RegisterFilterEventMapper(HumanRegisteredType, HumanRegisteredEventMapper). + RegisterFilterEventMapper(HumanInitialCodeAddedType, HumanInitialCodeAddedEventMapper). + RegisterFilterEventMapper(HumanInitialCodeSentType, HumanInitialCodeSentEventMapper). + RegisterFilterEventMapper(HumanInitializedCheckSucceededType, HumanInitializedCheckSucceededEventMapper). + RegisterFilterEventMapper(HumanInitializedCheckFailedType, HumanInitializedCheckFailedEventMapper). + RegisterFilterEventMapper(HumanSignedOutType, HumanSignedOutEventMapper). + RegisterFilterEventMapper(HumanPasswordChangedType, HumanPasswordChangedEventMapper). + RegisterFilterEventMapper(HumanPasswordCodeAddedType, HumanPasswordCodeAddedEventMapper). + RegisterFilterEventMapper(HumanPasswordCodeSentType, HumanPasswordCodeSentEventMapper). + RegisterFilterEventMapper(HumanPasswordCheckSucceededType, HumanPasswordCheckSucceededEventMapper). + RegisterFilterEventMapper(HumanPasswordCheckFailedType, HumanPasswordCheckFailedEventMapper). + RegisterFilterEventMapper(HumanExternalIDPAddedType, HumanExternalIDPAddedEventMapper). + RegisterFilterEventMapper(HumanExternalIDPRemovedType, HumanExternalIDPRemovedEventMapper). + RegisterFilterEventMapper(HumanExternalIDPCascadeRemovedType, HumanExternalIDPCascadeRemovedEventMapper). + RegisterFilterEventMapper(HumanExternalLoginCheckSucceededType, HumanExternalIDPCheckSucceededEventMapper). + RegisterFilterEventMapper(HumanEmailChangedType, HumanEmailChangedEventMapper). + RegisterFilterEventMapper(HumanEmailVerifiedType, HumanEmailVerifiedEventMapper). + RegisterFilterEventMapper(HumanEmailVerificationFailedType, HumanEmailVerificationFailedEventMapper). + RegisterFilterEventMapper(HumanEmailCodeAddedType, HumanEmailCodeAddedEventMapper). + RegisterFilterEventMapper(HumanEmailCodeSentType, HumanEmailCodeSentEventMapper). + RegisterFilterEventMapper(HumanPhoneChangedType, HumanPhoneChangedEventMapper). + RegisterFilterEventMapper(HumanPhoneRemovedType, HumanPhoneRemovedEventMapper). + RegisterFilterEventMapper(HumanPhoneVerifiedType, HumanPhoneVerifiedEventMapper). + RegisterFilterEventMapper(HumanPhoneVerificationFailedType, HumanPhoneVerificationFailedEventMapper). + RegisterFilterEventMapper(HumanPhoneCodeAddedType, HumanPhoneCodeAddedEventMapper). + RegisterFilterEventMapper(HumanPhoneCodeSentType, HumanPhoneCodeSentEventMapper). + RegisterFilterEventMapper(HumanProfileChangedType, HumanProfileChangedEventMapper). + RegisterFilterEventMapper(HumanAddressChangedType, HumanAddressChangedEventMapper). + RegisterFilterEventMapper(HumanMFAInitSkippedType, HumanMFAInitSkippedEventMapper). + RegisterFilterEventMapper(HumanMFAOTPAddedType, HumanOTPAddedEventMapper). + RegisterFilterEventMapper(HumanMFAOTPVerifiedType, HumanOTPVerifiedEventMapper). + RegisterFilterEventMapper(HumanMFAOTPRemovedType, HumanOTPRemovedEventMapper). + RegisterFilterEventMapper(HumanMFAOTPCheckSucceededType, HumanOTPCheckSucceededEventMapper). + RegisterFilterEventMapper(HumanMFAOTPCheckFailedType, HumanOTPCheckFailedEventMapper). + RegisterFilterEventMapper(HumanU2FTokenAddedType, WebAuthNAddedEventMapper). + RegisterFilterEventMapper(HumanU2FTokenVerifiedType, HumanWebAuthNVerifiedEventMapper). + RegisterFilterEventMapper(HumanU2FTokenSignCountChangedType, HumanWebAuthNSignCountChangedEventMapper). + RegisterFilterEventMapper(HumanU2FTokenRemovedType, HumanWebAuthNRemovedEventMapper). + RegisterFilterEventMapper(HumanU2FTokenBeginLoginType, HumanWebAuthNBeginLoginEventMapper). + RegisterFilterEventMapper(HumanU2FTokenCheckSucceededType, HumanWebAuthNCheckSucceededEventMapper). + RegisterFilterEventMapper(HumanU2FTokenCheckFailedType, HumanWebAuthNCheckFailedEventMapper). + RegisterFilterEventMapper(HumanPasswordlessTokenAddedType, WebAuthNAddedEventMapper). + RegisterFilterEventMapper(HumanPasswordlessTokenVerifiedType, HumanWebAuthNVerifiedEventMapper). + RegisterFilterEventMapper(HumanPasswordlessTokenSignCountChangedType, HumanWebAuthNSignCountChangedEventMapper). + RegisterFilterEventMapper(HumanPasswordlessTokenRemovedType, HumanWebAuthNRemovedEventMapper). + RegisterFilterEventMapper(HumanPasswordlessTokenBeginLoginType, HumanWebAuthNBeginLoginEventMapper). + RegisterFilterEventMapper(HumanPasswordlessTokenCheckSucceededType, HumanWebAuthNCheckSucceededEventMapper). + RegisterFilterEventMapper(HumanPasswordlessTokenCheckFailedType, HumanWebAuthNCheckFailedEventMapper). + RegisterFilterEventMapper(MachineAddedEventType, MachineAddedEventMapper). + RegisterFilterEventMapper(MachineChangedEventType, MachineChangedEventMapper). + RegisterFilterEventMapper(MachineKeyAddedEventType, MachineKeyAddedEventMapper). + RegisterFilterEventMapper(MachineKeyRemovedEventType, MachineKeyRemovedEventMapper) } diff --git a/internal/v2/repository/user/human/events.go b/internal/v2/repository/user/human.go similarity index 60% rename from internal/v2/repository/user/human/events.go rename to internal/v2/repository/user/human.go index e7419b6836..6d1e030ef4 100644 --- a/internal/v2/repository/user/human/events.go +++ b/internal/v2/repository/user/human.go @@ -1,4 +1,4 @@ -package human +package user import ( "context" @@ -7,12 +7,13 @@ import ( "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" "golang.org/x/text/language" "time" ) const ( - humanEventPrefix = eventstore.EventType("user.human.") + humanEventPrefix = userEventTypePrefix + "human." HumanAddedType = humanEventPrefix + "added" HumanRegisteredType = humanEventPrefix + "selfregistered" HumanInitialCodeAddedType = humanEventPrefix + "initialization.code.added" @@ -22,17 +23,17 @@ const ( HumanSignedOutType = humanEventPrefix + "signed.out" ) -type AddedEvent struct { +type HumanAddedEvent struct { eventstore.BaseEvent `json:"-"` UserName string `json:"userName"` - FirstName string `json:"firstName,omitempty"` - LastName string `json:"lastName,omitempty"` - NickName string `json:"nickName,omitempty"` - DisplayName string `json:"displayName,omitempty"` - PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"` - Gender Gender `json:"gender,omitempty"` + FirstName string `json:"firstName,omitempty"` + LastName string `json:"lastName,omitempty"` + NickName string `json:"nickName,omitempty"` + DisplayName string `json:"displayName,omitempty"` + PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"` + Gender domain.Gender `json:"gender,omitempty"` EmailAddress string `json:"email,omitempty"` @@ -43,13 +44,16 @@ type AddedEvent struct { PostalCode string `json:"postalCode,omitempty"` Region string `json:"region,omitempty"` StreetAddress string `json:"streetAddress,omitempty"` + + Secret *crypto.CryptoValue `json:"secret,omitempty"` + ChangeRequired bool `json:"changeRequired,omitempty"` } -func (e *AddedEvent) Data() interface{} { +func (e *HumanAddedEvent) Data() interface{} { return e } -func NewAddedEvent( +func NewHumanAddedEvent( ctx context.Context, userName, firstName, @@ -57,7 +61,7 @@ func NewAddedEvent( nickName, displayName string, preferredLanguage language.Tag, - gender Gender, + gender domain.Gender, emailAddress, phoneNumber, country, @@ -65,8 +69,8 @@ func NewAddedEvent( postalCode, region, streetAddress string, -) *AddedEvent { - return &AddedEvent{ +) *HumanAddedEvent { + return &HumanAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanAddedType, @@ -88,8 +92,8 @@ func NewAddedEvent( } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - humanAdded := &AddedEvent{ +func HumanAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + humanAdded := &HumanAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, humanAdded) @@ -100,17 +104,17 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return humanAdded, nil } -type RegisteredEvent struct { +type HumanRegisteredEvent struct { eventstore.BaseEvent `json:"-"` UserName string `json:"userName"` - FirstName string `json:"firstName,omitempty"` - LastName string `json:"lastName,omitempty"` - NickName string `json:"nickName,omitempty"` - DisplayName string `json:"displayName,omitempty"` - PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"` - Gender int32 `json:"gender,omitempty"` + FirstName string `json:"firstName,omitempty"` + LastName string `json:"lastName,omitempty"` + NickName string `json:"nickName,omitempty"` + DisplayName string `json:"displayName,omitempty"` + PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"` + Gender domain.Gender `json:"gender,omitempty"` EmailAddress string `json:"email,omitempty"` @@ -123,11 +127,11 @@ type RegisteredEvent struct { StreetAddress string `json:"streetAddress,omitempty"` } -func (e *RegisteredEvent) Data() interface{} { +func (e *HumanRegisteredEvent) Data() interface{} { return e } -func NewRegisteredEvent( +func NewHumanRegisteredEvent( ctx context.Context, userName, firstName, @@ -135,7 +139,7 @@ func NewRegisteredEvent( nickName, displayName string, preferredLanguage language.Tag, - gender int32, + gender domain.Gender, emailAddress, phoneNumber, country, @@ -143,8 +147,8 @@ func NewRegisteredEvent( postalCode, region, streetAddress string, -) *RegisteredEvent { - return &RegisteredEvent{ +) *HumanRegisteredEvent { + return &HumanRegisteredEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanRegisteredType, @@ -166,8 +170,8 @@ func NewRegisteredEvent( } } -func RegisteredEventMapper(event *repository.Event) (eventstore.EventReader, error) { - humanRegistered := &RegisteredEvent{ +func HumanRegisteredEventMapper(event *repository.Event) (eventstore.EventReader, error) { + humanRegistered := &HumanRegisteredEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, humanRegistered) @@ -178,22 +182,22 @@ func RegisteredEventMapper(event *repository.Event) (eventstore.EventReader, err return humanRegistered, nil } -type InitialCodeAddedEvent struct { +type HumanInitialCodeAddedEvent struct { eventstore.BaseEvent `json:"-"` Code *crypto.CryptoValue `json:"code,omitempty"` Expiry time.Duration `json:"expiry,omitempty"` } -func (e *InitialCodeAddedEvent) Data() interface{} { +func (e *HumanInitialCodeAddedEvent) Data() interface{} { return e } -func NewInitialCodeAddedEvent( +func NewHumanInitialCodeAddedEvent( ctx context.Context, code *crypto.CryptoValue, expiry time.Duration, -) *InitialCodeAddedEvent { - return &InitialCodeAddedEvent{ +) *HumanInitialCodeAddedEvent { + return &HumanInitialCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanInitialCodeAddedType, @@ -203,8 +207,8 @@ func NewInitialCodeAddedEvent( } } -func InitialCodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - humanRegistered := &InitialCodeAddedEvent{ +func HumanInitialCodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + humanRegistered := &HumanInitialCodeAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, humanRegistered) @@ -215,16 +219,16 @@ func InitialCodeAddedEventMapper(event *repository.Event) (eventstore.EventReade return humanRegistered, nil } -type InitialCodeSentEvent struct { +type HumanInitialCodeSentEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *InitialCodeSentEvent) Data() interface{} { +func (e *HumanInitialCodeSentEvent) Data() interface{} { return nil } -func NewInitialCodeSentEvent(ctx context.Context) *InitialCodeSentEvent { - return &InitialCodeSentEvent{ +func NewHumanInitialCodeSentEvent(ctx context.Context) *HumanInitialCodeSentEvent { + return &HumanInitialCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanInitialCodeSentType, @@ -232,22 +236,22 @@ func NewInitialCodeSentEvent(ctx context.Context) *InitialCodeSentEvent { } } -func InitialCodeSentEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &InitialCodeSentEvent{ +func HumanInitialCodeSentEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanInitialCodeSentEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type InitializedCheckSucceededEvent struct { +type HumanInitializedCheckSucceededEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *InitializedCheckSucceededEvent) Data() interface{} { +func (e *HumanInitializedCheckSucceededEvent) Data() interface{} { return nil } -func NewInitializedCheckSucceededEvent(ctx context.Context) *InitializedCheckSucceededEvent { - return &InitializedCheckSucceededEvent{ +func NewHumanInitializedCheckSucceededEvent(ctx context.Context) *HumanInitializedCheckSucceededEvent { + return &HumanInitializedCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanInitializedCheckSucceededType, @@ -255,22 +259,22 @@ func NewInitializedCheckSucceededEvent(ctx context.Context) *InitializedCheckSuc } } -func InitializedCheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &InitializedCheckSucceededEvent{ +func HumanInitializedCheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanInitializedCheckSucceededEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type InitializedCheckFailedEvent struct { +type HumanInitializedCheckFailedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *InitializedCheckFailedEvent) Data() interface{} { +func (e *HumanInitializedCheckFailedEvent) Data() interface{} { return nil } -func NewInitializedCheckFailedEvent(ctx context.Context) *InitializedCheckFailedEvent { - return &InitializedCheckFailedEvent{ +func NewHumanInitializedCheckFailedEvent(ctx context.Context) *HumanInitializedCheckFailedEvent { + return &HumanInitializedCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanInitializedCheckFailedType, @@ -278,22 +282,22 @@ func NewInitializedCheckFailedEvent(ctx context.Context) *InitializedCheckFailed } } -func InitializedCheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &InitializedCheckFailedEvent{ +func HumanInitializedCheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanInitializedCheckFailedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type SignedOutEvent struct { +type HumanSignedOutEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *SignedOutEvent) Data() interface{} { +func (e *HumanSignedOutEvent) Data() interface{} { return nil } -func NewSignedOutEvent(ctx context.Context) *SignedOutEvent { - return &SignedOutEvent{ +func NewHumanSignedOutEvent(ctx context.Context) *HumanSignedOutEvent { + return &HumanSignedOutEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanSignedOutType, @@ -301,8 +305,8 @@ func NewSignedOutEvent(ctx context.Context) *SignedOutEvent { } } -func SignedOutEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &SignedOutEvent{ +func HumanSignedOutEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanSignedOutEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } diff --git a/internal/v2/repository/user/human/address/write_model.go b/internal/v2/repository/user/human/address/write_model.go deleted file mode 100644 index 735a13466e..0000000000 --- a/internal/v2/repository/user/human/address/write_model.go +++ /dev/null @@ -1,13 +0,0 @@ -package address - -import "github.com/caos/zitadel/internal/eventstore/v2" - -type WriteModel struct { - eventstore.WriteModel - - Country string - Locality string - PostalCode string - Region string - StreetAddress string -} diff --git a/internal/v2/repository/user/human/email/write_model.go b/internal/v2/repository/user/human/email/write_model.go deleted file mode 100644 index 3cf04143fc..0000000000 --- a/internal/v2/repository/user/human/email/write_model.go +++ /dev/null @@ -1,9 +0,0 @@ -package email - -import "github.com/caos/zitadel/internal/eventstore/v2" - -type WriteModel struct { - eventstore.WriteModel - - Email string -} diff --git a/internal/v2/repository/user/human/mfa/events.go b/internal/v2/repository/user/human/mfa/events.go deleted file mode 100644 index 3b0df0d672..0000000000 --- a/internal/v2/repository/user/human/mfa/events.go +++ /dev/null @@ -1,35 +0,0 @@ -package mfa - -import ( - "context" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" -) - -const ( - mfaEventPrefix = eventstore.EventType("user.human.mfa.") - HumanMFAInitSkippedType = mfaEventPrefix + "init.skiped" -) - -type InitSkippedEvent struct { - eventstore.BaseEvent `json:"-"` -} - -func (e *InitSkippedEvent) Data() interface{} { - return e -} - -func NewInitSkippedEvent(ctx context.Context) *InitSkippedEvent { - return &InitSkippedEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - HumanMFAInitSkippedType, - ), - } -} - -func InitSkippedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &InitSkippedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - }, nil -} diff --git a/internal/v2/repository/user/human/mfa/mfa.go b/internal/v2/repository/user/human/mfa/mfa.go deleted file mode 100644 index 19df406bd6..0000000000 --- a/internal/v2/repository/user/human/mfa/mfa.go +++ /dev/null @@ -1,15 +0,0 @@ -package mfa - -type State int32 - -const ( - StateUnspecified State = iota - StateNotReady - StateReady - - stateCount -) - -func (f State) Valid() bool { - return f >= 0 && f < stateCount -} diff --git a/internal/v2/repository/user/human/mfa/otp/events.go b/internal/v2/repository/user/human/mfa/otp/events.go deleted file mode 100644 index 55db777665..0000000000 --- a/internal/v2/repository/user/human/mfa/otp/events.go +++ /dev/null @@ -1,148 +0,0 @@ -package otp - -import ( - "context" - "encoding/json" - "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/user/human/mfa" -) - -const ( - otpEventPrefix = eventstore.EventType("user.human.mfa.otp.") - HumanMFAOTPAddedType = otpEventPrefix + "added" - HumanMFAOTPVerifiedType = otpEventPrefix + "verified" - HumanMFAOTPRemovedType = otpEventPrefix + "removed" - HumanMFAOTPCheckSucceededType = otpEventPrefix + "check.succeeded" - HumanMFAOTPCheckFailedType = otpEventPrefix + "check.failed" -) - -type AddedEvent struct { - eventstore.BaseEvent `json:"-"` - - Secret *crypto.CryptoValue `json:"otpSecret,omitempty"` - State mfa.State `json:"-"` -} - -func (e *AddedEvent) Data() interface{} { - return e -} - -func NewAddedEvent(ctx context.Context, - secret *crypto.CryptoValue) *AddedEvent { - return &AddedEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - HumanMFAOTPAddedType, - ), - Secret: secret, - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - otpAdded := &AddedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - State: mfa.StateNotReady, - } - err := json.Unmarshal(event.Data, otpAdded) - if err != nil { - return nil, errors.ThrowInternal(err, "USER-Ns9df", "unable to unmarshal human otp added") - } - return otpAdded, nil -} - -type VerifiedEvent struct { - eventstore.BaseEvent `json:"-"` - State mfa.State `json:"-"` -} - -func (e *VerifiedEvent) Data() interface{} { - return nil -} - -func NewVerifiedEvent(ctx context.Context) *VerifiedEvent { - return &VerifiedEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - HumanMFAOTPVerifiedType, - ), - } -} - -func VerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &VerifiedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - State: mfa.StateReady, - }, nil -} - -type RemovedEvent struct { - eventstore.BaseEvent `json:"-"` -} - -func (e *RemovedEvent) Data() interface{} { - return nil -} - -func NewRemovedEvent(ctx context.Context) *RemovedEvent { - return &RemovedEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - HumanMFAOTPRemovedType, - ), - } -} - -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &RemovedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - }, nil -} - -type CheckSucceededEvent struct { - eventstore.BaseEvent `json:"-"` -} - -func (e *CheckSucceededEvent) Data() interface{} { - return nil -} - -func NewCheckSucceededEvent(ctx context.Context) *CheckSucceededEvent { - return &CheckSucceededEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - HumanMFAOTPCheckSucceededType, - ), - } -} - -func CheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &CheckSucceededEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - }, nil -} - -type CheckFailedEvent struct { - eventstore.BaseEvent `json:"-"` -} - -func (e *CheckFailedEvent) Data() interface{} { - return nil -} - -func NewCheckFailedEvent(ctx context.Context) *CheckFailedEvent { - return &CheckFailedEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - HumanMFAOTPCheckFailedType, - ), - } -} - -func CheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &CheckFailedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - }, nil -} diff --git a/internal/v2/repository/user/human/notification.go b/internal/v2/repository/user/human/notification.go deleted file mode 100644 index 6ee815e0c7..0000000000 --- a/internal/v2/repository/user/human/notification.go +++ /dev/null @@ -1,8 +0,0 @@ -package human - -type NotificationType int32 - -const ( - NotificationTypeEmail NotificationType = iota - NotificationTypeSms -) diff --git a/internal/v2/repository/user/human/profile/events.go b/internal/v2/repository/user/human/profile/events.go deleted file mode 100644 index a2ac67e16d..0000000000 --- a/internal/v2/repository/user/human/profile/events.go +++ /dev/null @@ -1,80 +0,0 @@ -package profile - -import ( - "context" - "encoding/json" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/user/human" - "golang.org/x/text/language" -) - -const ( - profileEventPrefix = eventstore.EventType("user.human.profile.") - HumanProfileChangedType = profileEventPrefix + "changed" -) - -type ChangedEvent struct { - eventstore.BaseEvent `json:"-"` - - FirstName string `json:"firstName,omitempty"` - LastName string `json:"lastName,omitempty"` - NickName string `json:"nickName,omitempty"` - DisplayName string `json:"displayName,omitempty"` - PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"` - Gender human.Gender `json:"gender,omitempty"` -} - -func (e *ChangedEvent) Data() interface{} { - return e -} - -func NewChangedEvent( - ctx context.Context, - current *WriteModel, - firstName, - lastName, - nickName, - displayName string, - preferredLanguage language.Tag, - gender human.Gender, -) *ChangedEvent { - e := &ChangedEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - HumanProfileChangedType, - ), - } - if current.FirstName != firstName { - e.FirstName = firstName - } - if current.LastName != lastName { - e.LastName = lastName - } - if current.NickName != nickName { - e.NickName = nickName - } - if current.DisplayName != displayName { - e.DisplayName = displayName - } - if current.PreferredLanguage != preferredLanguage { - e.PreferredLanguage = preferredLanguage - } - if current.Gender != gender { - e.Gender = gender - } - return e -} - -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - profileChanged := &ChangedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - err := json.Unmarshal(event.Data, profileChanged) - if err != nil { - return nil, errors.ThrowInternal(err, "USER-5M0pd", "unable to unmarshal human profile changed") - } - - return profileChanged, nil -} diff --git a/internal/v2/repository/user/human/profile/write_model.go b/internal/v2/repository/user/human/profile/write_model.go deleted file mode 100644 index 767e61046e..0000000000 --- a/internal/v2/repository/user/human/profile/write_model.go +++ /dev/null @@ -1,18 +0,0 @@ -package profile - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/user/human" - "golang.org/x/text/language" -) - -type WriteModel struct { - eventstore.WriteModel - - FirstName string - LastName string - NickName string - DisplayName string - PreferredLanguage language.Tag - Gender human.Gender -} diff --git a/internal/v2/repository/user/human/address/events.go b/internal/v2/repository/user/human_address.go similarity index 53% rename from internal/v2/repository/user/human/address/events.go rename to internal/v2/repository/user/human_address.go index 0e7ebbcf25..68163af252 100644 --- a/internal/v2/repository/user/human/address/events.go +++ b/internal/v2/repository/user/human_address.go @@ -1,4 +1,4 @@ -package address +package user import ( "context" @@ -9,11 +9,11 @@ import ( ) const ( - addressEventPrefix = eventstore.EventType("user.human.address.") + addressEventPrefix = humanEventPrefix + "address." HumanAddressChangedType = addressEventPrefix + "changed" ) -type ChangedEvent struct { +type HumanAddressChangedEvent struct { eventstore.BaseEvent `json:"-"` Country string `json:"country,omitempty"` @@ -23,47 +23,21 @@ type ChangedEvent struct { StreetAddress string `json:"streetAddress,omitempty"` } -func (e *ChangedEvent) Data() interface{} { +func (e *HumanAddressChangedEvent) Data() interface{} { return e } -func NewChangedEvent( - ctx context.Context, - current *WriteModel, - country, - locality, - postalCode, - region, - streetAddress string, -) *ChangedEvent { - e := &ChangedEvent{ +func NewHumanAddressChangedEvent(ctx context.Context) *HumanAddressChangedEvent { + return &HumanAddressChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanAddressChangedType, ), } - - if current.Country != country { - e.Country = country - } - if current.Locality != locality { - e.Locality = locality - } - if current.PostalCode != postalCode { - e.PostalCode = postalCode - } - if current.Region != region { - e.Region = region - } - if current.StreetAddress != streetAddress { - e.StreetAddress = streetAddress - } - - return e } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - addressChanged := &ChangedEvent{ +func HumanAddressChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + addressChanged := &HumanAddressChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, addressChanged) diff --git a/internal/v2/repository/user/human/email/events.go b/internal/v2/repository/user/human_email.go similarity index 56% rename from internal/v2/repository/user/human/email/events.go rename to internal/v2/repository/user/human_email.go index 0b533303c3..302259efee 100644 --- a/internal/v2/repository/user/human/email/events.go +++ b/internal/v2/repository/user/human_email.go @@ -1,4 +1,4 @@ -package email +package user import ( "context" @@ -11,7 +11,7 @@ import ( ) const ( - emailEventPrefix = eventstore.EventType("user.human.email.") + emailEventPrefix = humanEventPrefix + "email." HumanEmailChangedType = emailEventPrefix + "changed" HumanEmailVerifiedType = emailEventPrefix + "verified" HumanEmailVerificationFailedType = emailEventPrefix + "verification.failed" @@ -19,35 +19,27 @@ const ( HumanEmailCodeSentType = emailEventPrefix + "code.sent" ) -type ChangedEvent struct { +type HumanEmailChangedEvent struct { eventstore.BaseEvent `json:"-"` EmailAddress string `json:"email,omitempty"` } -func (e *ChangedEvent) Data() interface{} { +func (e *HumanEmailChangedEvent) Data() interface{} { return e } -func NewChangedEvent( - ctx context.Context, - current *WriteModel, - emailAddress string, -) *ChangedEvent { - e := &ChangedEvent{ +func NewHumanEmailChangedEvent(ctx context.Context) *HumanEmailChangedEvent { + return &HumanEmailChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanEmailChangedType, ), } - if current.Email != emailAddress { - e.EmailAddress = emailAddress - } - return e } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - emailChangedEvent := &ChangedEvent{ +func HumanEmailChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + emailChangedEvent := &HumanEmailChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, emailChangedEvent) @@ -58,18 +50,18 @@ func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) return emailChangedEvent, nil } -type VerifiedEvent struct { +type HumanEmailVerifiedEvent struct { eventstore.BaseEvent `json:"-"` IsEmailVerified bool `json:"-"` } -func (e *VerifiedEvent) Data() interface{} { +func (e *HumanEmailVerifiedEvent) Data() interface{} { return nil } -func NewVerifiedEvent(ctx context.Context) *VerifiedEvent { - return &VerifiedEvent{ +func NewHumanEmailVerifiedEvent(ctx context.Context) *HumanEmailVerifiedEvent { + return &HumanEmailVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanEmailVerifiedType, @@ -77,24 +69,24 @@ func NewVerifiedEvent(ctx context.Context) *VerifiedEvent { } } -func VerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - emailVerified := &VerifiedEvent{ +func HumanEmailVerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + emailVerified := &HumanEmailVerifiedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), IsEmailVerified: true, } return emailVerified, nil } -type VerificationFailedEvent struct { +type HumanEmailVerificationFailedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *VerificationFailedEvent) Data() interface{} { +func (e *HumanEmailVerificationFailedEvent) Data() interface{} { return nil } -func NewVerificationFailedEvent(ctx context.Context) *VerificationFailedEvent { - return &VerificationFailedEvent{ +func NewHumanEmailVerificationFailedEvent(ctx context.Context) *HumanEmailVerificationFailedEvent { + return &HumanEmailVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanEmailVerificationFailedType, @@ -102,28 +94,28 @@ func NewVerificationFailedEvent(ctx context.Context) *VerificationFailedEvent { } } -func VerificationFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &VerificationFailedEvent{ +func HumanEmailVerificationFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanEmailVerificationFailedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type CodeAddedEvent struct { +type HumanEmailCodeAddedEvent struct { eventstore.BaseEvent `json:"-"` Code *crypto.CryptoValue `json:"code,omitempty"` Expiry time.Duration `json:"expiry,omitempty"` } -func (e *CodeAddedEvent) Data() interface{} { +func (e *HumanEmailCodeAddedEvent) Data() interface{} { return e } -func NewCodeAddedEvent( +func NewHumanEmailCodeAddedEvent( ctx context.Context, code *crypto.CryptoValue, - expiry time.Duration) *CodeAddedEvent { - return &CodeAddedEvent{ + expiry time.Duration) *HumanEmailCodeAddedEvent { + return &HumanEmailCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanEmailCodeAddedType, @@ -133,8 +125,8 @@ func NewCodeAddedEvent( } } -func CodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - codeAdded := &CodeAddedEvent{ +func HumanEmailCodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + codeAdded := &HumanEmailCodeAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, codeAdded) @@ -145,16 +137,16 @@ func CodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, erro return codeAdded, nil } -type CodeSentEvent struct { +type HumanEmailCodeSentEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *CodeSentEvent) Data() interface{} { +func (e *HumanEmailCodeSentEvent) Data() interface{} { return nil } -func NewCodeSentEvent(ctx context.Context) *CodeSentEvent { - return &CodeSentEvent{ +func NewHumanEmailCodeSentEvent(ctx context.Context) *HumanEmailCodeSentEvent { + return &HumanEmailCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanEmailCodeSentType, @@ -162,8 +154,8 @@ func NewCodeSentEvent(ctx context.Context) *CodeSentEvent { } } -func CodeSentEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &CodeSentEvent{ +func HumanEmailCodeSentEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanEmailCodeSentEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } diff --git a/internal/v2/repository/user/human/external_idp/events.go b/internal/v2/repository/user/human_external_idp.go similarity index 54% rename from internal/v2/repository/user/human/external_idp/events.go rename to internal/v2/repository/user/human_external_idp.go index 875a3d5d9d..72311ea094 100644 --- a/internal/v2/repository/user/human/external_idp/events.go +++ b/internal/v2/repository/user/human_external_idp.go @@ -1,4 +1,4 @@ -package external_idp +package user import ( "context" @@ -9,8 +9,8 @@ import ( ) const ( - externalIDPEventPrefix = eventstore.EventType("user.human.externalidp.") - externalLoginEventPrefix = eventstore.EventType("user.human.externallogin.") + externalIDPEventPrefix = humanEventPrefix + "externalidp." + externalLoginEventPrefix = humanEventPrefix + "externallogin." //TODO: Handle unique Aggregate HumanExternalIDPReservedType = externalIDPEventPrefix + "reserved" @@ -23,16 +23,16 @@ const ( HumanExternalLoginCheckSucceededType = externalLoginEventPrefix + "check.succeeded" ) -type ReservedEvent struct { +type HumanExternalIDPReservedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *ReservedEvent) Data() interface{} { +func (e *HumanExternalIDPReservedEvent) Data() interface{} { return nil } -func NewReservedEvent(ctx context.Context) *ReservedEvent { - return &ReservedEvent{ +func NewHumanExternalIDPReservedEvent(ctx context.Context) *HumanExternalIDPReservedEvent { + return &HumanExternalIDPReservedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanExternalIDPReservedType, @@ -40,16 +40,16 @@ func NewReservedEvent(ctx context.Context) *ReservedEvent { } } -type ReleasedEvent struct { +type HumanExternalIDPReleasedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *ReleasedEvent) Data() interface{} { +func (e *HumanExternalIDPReleasedEvent) Data() interface{} { return nil } -func NewReleasedEvent(ctx context.Context) *ReleasedEvent { - return &ReleasedEvent{ +func NewHumanExternalIDPReleasedEvent(ctx context.Context) *HumanExternalIDPReleasedEvent { + return &HumanExternalIDPReleasedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanExternalIDPReleasedType, @@ -57,19 +57,19 @@ func NewReleasedEvent(ctx context.Context) *ReleasedEvent { } } -type AddedEvent struct { +type HumanExternalIDPAddedEvent struct { eventstore.BaseEvent `json:"-"` IDPConfigID string `json:"idpConfigId,omitempty"` DisplayName string `json:"displayName,omitempty"` } -func (e *AddedEvent) Data() interface{} { +func (e *HumanExternalIDPAddedEvent) Data() interface{} { return e } -func NewAddedEvent(ctx context.Context, idpConfigID, displayName string) *AddedEvent { - return &AddedEvent{ +func NewHumanExternalIDPAddedEvent(ctx context.Context, idpConfigID, displayName string) *HumanExternalIDPAddedEvent { + return &HumanExternalIDPAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanExternalIDPAddedType, @@ -79,8 +79,8 @@ func NewAddedEvent(ctx context.Context, idpConfigID, displayName string) *AddedE } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &AddedEvent{ +func HumanExternalIDPAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &HumanExternalIDPAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -92,18 +92,18 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return e, nil } -type RemovedEvent struct { +type HumanExternalIDPRemovedEvent struct { eventstore.BaseEvent `json:"-"` IDPConfigID string `json:"idpConfigId"` } -func (e *RemovedEvent) Data() interface{} { +func (e *HumanExternalIDPRemovedEvent) Data() interface{} { return e } -func NewRemovedEvent(ctx context.Context, idpConfigID string) *RemovedEvent { - return &RemovedEvent{ +func NewHumanExternalIDPRemovedEvent(ctx context.Context, idpConfigID string) *HumanExternalIDPRemovedEvent { + return &HumanExternalIDPRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanExternalIDPRemovedType, @@ -112,8 +112,8 @@ func NewRemovedEvent(ctx context.Context, idpConfigID string) *RemovedEvent { } } -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &RemovedEvent{ +func HumanExternalIDPRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &HumanExternalIDPRemovedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -125,18 +125,18 @@ func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) return e, nil } -type CascadeRemovedEvent struct { +type HumanExternalIDPCascadeRemovedEvent struct { eventstore.BaseEvent `json:"-"` IDPConfigID string `json:"idpConfigId"` } -func (e *CascadeRemovedEvent) Data() interface{} { +func (e *HumanExternalIDPCascadeRemovedEvent) Data() interface{} { return e } -func NewCascadeRemovedEvent(ctx context.Context, idpConfigID string) *CascadeRemovedEvent { - return &CascadeRemovedEvent{ +func NewHumanExternalIDPCascadeRemovedEvent(ctx context.Context, idpConfigID string) *HumanExternalIDPCascadeRemovedEvent { + return &HumanExternalIDPCascadeRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanExternalIDPCascadeRemovedType, @@ -145,8 +145,8 @@ func NewCascadeRemovedEvent(ctx context.Context, idpConfigID string) *CascadeRem } } -func CascadeRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - e := &CascadeRemovedEvent{ +func HumanExternalIDPCascadeRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &HumanExternalIDPCascadeRemovedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } @@ -158,16 +158,16 @@ func CascadeRemovedEventMapper(event *repository.Event) (eventstore.EventReader, return e, nil } -type CheckSucceededEvent struct { +type HumanExternalIDPCheckSucceededEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *CheckSucceededEvent) Data() interface{} { +func (e *HumanExternalIDPCheckSucceededEvent) Data() interface{} { return nil } -func NewCheckSucceededEvent(ctx context.Context) *CheckSucceededEvent { - return &CheckSucceededEvent{ +func NewHumanExternalIDPCheckSucceededEvent(ctx context.Context) *HumanExternalIDPCheckSucceededEvent { + return &HumanExternalIDPCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanExternalLoginCheckSucceededType, @@ -175,8 +175,8 @@ func NewCheckSucceededEvent(ctx context.Context) *CheckSucceededEvent { } } -func CheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &CheckSucceededEvent{ +func HumanExternalIDPCheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanExternalIDPCheckSucceededEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } diff --git a/internal/v2/repository/user/human_mfa_events.go b/internal/v2/repository/user/human_mfa_events.go new file mode 100644 index 0000000000..eed43b5cdd --- /dev/null +++ b/internal/v2/repository/user/human_mfa_events.go @@ -0,0 +1,35 @@ +package user + +import ( + "context" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" +) + +const ( + mfaEventPrefix = humanEventPrefix + "mfa." + HumanMFAInitSkippedType = mfaEventPrefix + "init.skiped" +) + +type HumanMFAInitSkippedEvent struct { + eventstore.BaseEvent `json:"-"` +} + +func (e *HumanMFAInitSkippedEvent) Data() interface{} { + return e +} + +func NewHumanMFAInitSkippedEvent(ctx context.Context) *HumanMFAInitSkippedEvent { + return &HumanMFAInitSkippedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + HumanMFAInitSkippedType, + ), + } +} + +func HumanMFAInitSkippedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanMFAInitSkippedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} diff --git a/internal/v2/repository/user/human_mfa_otp.go b/internal/v2/repository/user/human_mfa_otp.go new file mode 100644 index 0000000000..3ba9529f3b --- /dev/null +++ b/internal/v2/repository/user/human_mfa_otp.go @@ -0,0 +1,148 @@ +package user + +import ( + "context" + "encoding/json" + "github.com/caos/zitadel/internal/crypto" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" +) + +const ( + otpEventPrefix = mfaEventPrefix + "otp." + HumanMFAOTPAddedType = otpEventPrefix + "added" + HumanMFAOTPVerifiedType = otpEventPrefix + "verified" + HumanMFAOTPRemovedType = otpEventPrefix + "removed" + HumanMFAOTPCheckSucceededType = otpEventPrefix + "check.succeeded" + HumanMFAOTPCheckFailedType = otpEventPrefix + "check.failed" +) + +type HumanOTPAddedEvent struct { + eventstore.BaseEvent `json:"-"` + + Secret *crypto.CryptoValue `json:"otpSecret,omitempty"` + State domain.MFAState `json:"-"` +} + +func (e *HumanOTPAddedEvent) Data() interface{} { + return e +} + +func NewHumanOTPAddedEvent(ctx context.Context, + secret *crypto.CryptoValue) *HumanOTPAddedEvent { + return &HumanOTPAddedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + HumanMFAOTPAddedType, + ), + Secret: secret, + } +} + +func HumanOTPAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + otpAdded := &HumanOTPAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + State: domain.MFAStateNotReady, + } + err := json.Unmarshal(event.Data, otpAdded) + if err != nil { + return nil, errors.ThrowInternal(err, "USER-Ns9df", "unable to unmarshal human otp added") + } + return otpAdded, nil +} + +type HumanOTPVerifiedEvent struct { + eventstore.BaseEvent `json:"-"` + State domain.MFAState `json:"-"` +} + +func (e *HumanOTPVerifiedEvent) Data() interface{} { + return nil +} + +func NewHumanOTPVerifiedEvent(ctx context.Context) *HumanOTPVerifiedEvent { + return &HumanOTPVerifiedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + HumanMFAOTPVerifiedType, + ), + } +} + +func HumanOTPVerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanOTPVerifiedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + State: domain.MFAStateReady, + }, nil +} + +type HumanOTPRemovedEvent struct { + eventstore.BaseEvent `json:"-"` +} + +func (e *HumanOTPRemovedEvent) Data() interface{} { + return nil +} + +func NewHumanOTPRemovedEvent(ctx context.Context) *HumanOTPRemovedEvent { + return &HumanOTPRemovedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + HumanMFAOTPRemovedType, + ), + } +} + +func HumanOTPRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanOTPRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} + +type HumanOTPCheckSucceededEvent struct { + eventstore.BaseEvent `json:"-"` +} + +func (e *HumanOTPCheckSucceededEvent) Data() interface{} { + return nil +} + +func NewHumanOTPCheckSucceededEvent(ctx context.Context) *HumanOTPCheckSucceededEvent { + return &HumanOTPCheckSucceededEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + HumanMFAOTPCheckSucceededType, + ), + } +} + +func HumanOTPCheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanOTPCheckSucceededEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} + +type HumanOTPCheckFailedEvent struct { + eventstore.BaseEvent `json:"-"` +} + +func (e *HumanOTPCheckFailedEvent) Data() interface{} { + return nil +} + +func NewHumanOTPCheckFailedEvent(ctx context.Context) *HumanOTPCheckFailedEvent { + return &HumanOTPCheckFailedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + HumanMFAOTPCheckFailedType, + ), + } +} + +func HumanOTPCheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanOTPCheckFailedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} diff --git a/internal/v2/repository/user/human/mfa/web_auth_n/events.go b/internal/v2/repository/user/human_mfa_web_auth_n.go similarity index 59% rename from internal/v2/repository/user/human/mfa/web_auth_n/events.go rename to internal/v2/repository/user/human_mfa_web_auth_n.go index ec85898ce5..0d7dff661c 100644 --- a/internal/v2/repository/user/human/mfa/web_auth_n/events.go +++ b/internal/v2/repository/user/human_mfa_web_auth_n.go @@ -1,4 +1,4 @@ -package web_auth_n +package user import ( "context" @@ -6,11 +6,11 @@ import ( "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/user/human/mfa" + "github.com/caos/zitadel/internal/v2/domain" ) const ( - u2fEventPrefix = eventstore.EventType("user.human.mfa.u2f.token.") + u2fEventPrefix = mfaEventPrefix + "u2f.token." HumanU2FTokenAddedType = u2fEventPrefix + "added" HumanU2FTokenVerifiedType = u2fEventPrefix + "verified" HumanU2FTokenSignCountChangedType = u2fEventPrefix + "signcount.changed" @@ -19,7 +19,7 @@ const ( HumanU2FTokenCheckSucceededType = u2fEventPrefix + "check.succeeded" HumanU2FTokenCheckFailedType = u2fEventPrefix + "check.failed" - passwordlessEventPrefix = eventstore.EventType("user.human.mfa.passwordless.token.") + passwordlessEventPrefix = humanEventPrefix + "passwordless.token." HumanPasswordlessTokenAddedType = passwordlessEventPrefix + "added" HumanPasswordlessTokenVerifiedType = passwordlessEventPrefix + "verified" HumanPasswordlessTokenSignCountChangedType = passwordlessEventPrefix + "signcount.changed" @@ -29,24 +29,24 @@ const ( HumanPasswordlessTokenCheckFailedType = passwordlessEventPrefix + "check.failed" ) -type AddedEvent struct { +type HumanWebAuthNAddedEvent struct { eventstore.BaseEvent `json:"-"` - WebAuthNTokenID string `json:"webAuthNTokenId"` - Challenge string `json:"challenge"` - State mfa.State `json:"-"` + WebAuthNTokenID string `json:"webAuthNTokenId"` + Challenge string `json:"challenge"` + State domain.MFAState `json:"-"` } -func (e *AddedEvent) Data() interface{} { +func (e *HumanWebAuthNAddedEvent) Data() interface{} { return e } -func NewU2FAddedEvent( +func NewHumanU2FAddedEvent( ctx context.Context, webAuthNTokenID, challenge string, -) *AddedEvent { - return &AddedEvent{ +) *HumanWebAuthNAddedEvent { + return &HumanWebAuthNAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanU2FTokenAddedType, @@ -56,12 +56,12 @@ func NewU2FAddedEvent( } } -func NewPasswordlessAddedEvent( +func NewHumanPasswordlessAddedEvent( ctx context.Context, webAuthNTokenID, challenge string, -) *AddedEvent { - return &AddedEvent{ +) *HumanWebAuthNAddedEvent { + return &HumanWebAuthNAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordlessTokenAddedType, @@ -71,10 +71,10 @@ func NewPasswordlessAddedEvent( } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - webAuthNAdded := &AddedEvent{ +func WebAuthNAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + webAuthNAdded := &HumanWebAuthNAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), - State: mfa.StateNotReady, + State: domain.MFAStateNotReady, } err := json.Unmarshal(event.Data, webAuthNAdded) if err != nil { @@ -83,24 +83,24 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return webAuthNAdded, nil } -type VerifiedEvent struct { +type HumanWebAuthNVerifiedEvent struct { eventstore.BaseEvent `json:"-"` - WebAuthNTokenID string `json:"webAuthNTokenId"` - KeyID []byte `json:"keyId"` - PublicKey []byte `json:"publicKey"` - AttestationType string `json:"attestationType"` - AAGUID []byte `json:"aaguid"` - SignCount uint32 `json:"signCount"` - WebAuthNTokenName string `json:"webAuthNTokenName"` - State mfa.State `json:"-"` + WebAuthNTokenID string `json:"webAuthNTokenId"` + KeyID []byte `json:"keyId"` + PublicKey []byte `json:"publicKey"` + AttestationType string `json:"attestationType"` + AAGUID []byte `json:"aaguid"` + SignCount uint32 `json:"signCount"` + WebAuthNTokenName string `json:"webAuthNTokenName"` + State domain.MFAState `json:"-"` } -func (e *VerifiedEvent) Data() interface{} { +func (e *HumanWebAuthNVerifiedEvent) Data() interface{} { return e } -func NewU2FVerifiedEvent( +func NewHumanU2FVerifiedEvent( ctx context.Context, webAuthNTokenID, webAuthNTokenName, @@ -109,8 +109,8 @@ func NewU2FVerifiedEvent( publicKey, aaguid []byte, signCount uint32, -) *VerifiedEvent { - return &VerifiedEvent{ +) *HumanWebAuthNVerifiedEvent { + return &HumanWebAuthNVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanU2FTokenVerifiedType, @@ -125,7 +125,7 @@ func NewU2FVerifiedEvent( } } -func NewPasswordlessVerifiedEvent( +func NewHumanPasswordlessVerifiedEvent( ctx context.Context, webAuthNTokenID, webAuthNTokenName, @@ -134,8 +134,8 @@ func NewPasswordlessVerifiedEvent( publicKey, aaguid []byte, signCount uint32, -) *VerifiedEvent { - return &VerifiedEvent{ +) *HumanWebAuthNVerifiedEvent { + return &HumanWebAuthNVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordlessTokenVerifiedType, @@ -150,10 +150,10 @@ func NewPasswordlessVerifiedEvent( } } -func VerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - webauthNVerified := &VerifiedEvent{ +func HumanWebAuthNVerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + webauthNVerified := &HumanWebAuthNVerifiedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), - State: mfa.StateReady, + State: domain.MFAStateReady, } err := json.Unmarshal(event.Data, webauthNVerified) if err != nil { @@ -162,24 +162,24 @@ func VerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error return webauthNVerified, nil } -type SignCountChangedEvent struct { +type HumanWebAuthNSignCountChangedEvent struct { eventstore.BaseEvent `json:"-"` - WebAuthNTokenID string `json:"webAuthNTokenId"` - SignCount uint32 `json:"signCount"` - State mfa.State `json:"-"` + WebAuthNTokenID string `json:"webAuthNTokenId"` + SignCount uint32 `json:"signCount"` + State domain.MFAState `json:"-"` } -func (e *SignCountChangedEvent) Data() interface{} { +func (e *HumanWebAuthNSignCountChangedEvent) Data() interface{} { return e } -func NewU2FSignCountChangedEvent( +func NewHumanU2FSignCountChangedEvent( ctx context.Context, webAuthNTokenID string, signCount uint32, -) *SignCountChangedEvent { - return &SignCountChangedEvent{ +) *HumanWebAuthNSignCountChangedEvent { + return &HumanWebAuthNSignCountChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanU2FTokenSignCountChangedType, @@ -189,12 +189,12 @@ func NewU2FSignCountChangedEvent( } } -func NewPasswordlessSignCountChangedEvent( +func NewHumanPasswordlessSignCountChangedEvent( ctx context.Context, webAuthNTokenID string, signCount uint32, -) *SignCountChangedEvent { - return &SignCountChangedEvent{ +) *HumanWebAuthNSignCountChangedEvent { + return &HumanWebAuthNSignCountChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordlessTokenSignCountChangedType, @@ -204,8 +204,8 @@ func NewPasswordlessSignCountChangedEvent( } } -func SignCountChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - webauthNVerified := &SignCountChangedEvent{ +func HumanWebAuthNSignCountChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + webauthNVerified := &HumanWebAuthNSignCountChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, webauthNVerified) @@ -215,22 +215,22 @@ func SignCountChangedEventMapper(event *repository.Event) (eventstore.EventReade return webauthNVerified, nil } -type RemovedEvent struct { +type HumanWebAuthNRemovedEvent struct { eventstore.BaseEvent `json:"-"` - WebAuthNTokenID string `json:"webAuthNTokenId"` - State mfa.State `json:"-"` + WebAuthNTokenID string `json:"webAuthNTokenId"` + State domain.MFAState `json:"-"` } -func (e *RemovedEvent) Data() interface{} { +func (e *HumanWebAuthNRemovedEvent) Data() interface{} { return e } -func NewU2FRemovedEvent( +func NewHumanU2FRemovedEvent( ctx context.Context, webAuthNTokenID string, -) *RemovedEvent { - return &RemovedEvent{ +) *HumanWebAuthNRemovedEvent { + return &HumanWebAuthNRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanU2FTokenRemovedType, @@ -239,11 +239,11 @@ func NewU2FRemovedEvent( } } -func NewPasswordlessRemovedEvent( +func NewHumanPasswordlessRemovedEvent( ctx context.Context, webAuthNTokenID string, -) *RemovedEvent { - return &RemovedEvent{ +) *HumanWebAuthNRemovedEvent { + return &HumanWebAuthNRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordlessTokenRemovedType, @@ -252,8 +252,8 @@ func NewPasswordlessRemovedEvent( } } -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - webauthNVerified := &RemovedEvent{ +func HumanWebAuthNRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + webauthNVerified := &HumanWebAuthNRemovedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, webauthNVerified) @@ -263,7 +263,7 @@ func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) return webauthNVerified, nil } -type BeginLoginEvent struct { +type HumanWebAuthNBeginLoginEvent struct { eventstore.BaseEvent `json:"-"` WebAuthNTokenID string `json:"webAuthNTokenId"` @@ -272,16 +272,16 @@ type BeginLoginEvent struct { //*AuthRequest } -func (e *BeginLoginEvent) Data() interface{} { +func (e *HumanWebAuthNBeginLoginEvent) Data() interface{} { return e } -func NewU2FBeginLoginEvent( +func NewHumanU2FBeginLoginEvent( ctx context.Context, webAuthNTokenID, challenge string, -) *BeginLoginEvent { - return &BeginLoginEvent{ +) *HumanWebAuthNBeginLoginEvent { + return &HumanWebAuthNBeginLoginEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanU2FTokenRemovedType, @@ -291,12 +291,12 @@ func NewU2FBeginLoginEvent( } } -func NewPasswordlessBeginLoginEvent( +func NewHumanPasswordlessBeginLoginEvent( ctx context.Context, webAuthNTokenID, challenge string, -) *BeginLoginEvent { - return &BeginLoginEvent{ +) *HumanWebAuthNBeginLoginEvent { + return &HumanWebAuthNBeginLoginEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordlessTokenRemovedType, @@ -306,8 +306,8 @@ func NewPasswordlessBeginLoginEvent( } } -func BeginLoginEventMapper(event *repository.Event) (eventstore.EventReader, error) { - webAuthNAdded := &BeginLoginEvent{ +func HumanWebAuthNBeginLoginEventMapper(event *repository.Event) (eventstore.EventReader, error) { + webAuthNAdded := &HumanWebAuthNBeginLoginEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, webAuthNAdded) @@ -317,19 +317,19 @@ func BeginLoginEventMapper(event *repository.Event) (eventstore.EventReader, err return webAuthNAdded, nil } -type CheckSucceededEvent struct { +type HumanWebAuthNCheckSucceededEvent struct { eventstore.BaseEvent `json:"-"` //TODO: Handle Auth Req?? //*AuthRequest } -func (e *CheckSucceededEvent) Data() interface{} { +func (e *HumanWebAuthNCheckSucceededEvent) Data() interface{} { return e } -func NewU2FCheckSucceededEvent(ctx context.Context) *CheckSucceededEvent { - return &CheckSucceededEvent{ +func NewHumanU2FCheckSucceededEvent(ctx context.Context) *HumanWebAuthNCheckSucceededEvent { + return &HumanWebAuthNCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanU2FTokenCheckSucceededType, @@ -337,8 +337,8 @@ func NewU2FCheckSucceededEvent(ctx context.Context) *CheckSucceededEvent { } } -func NewPasswordlessCheckSucceededEvent(ctx context.Context) *CheckSucceededEvent { - return &CheckSucceededEvent{ +func NewHumanPasswordlessCheckSucceededEvent(ctx context.Context) *HumanWebAuthNCheckSucceededEvent { + return &HumanWebAuthNCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordlessTokenCheckSucceededType, @@ -346,8 +346,8 @@ func NewPasswordlessCheckSucceededEvent(ctx context.Context) *CheckSucceededEven } } -func CheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { - webAuthNAdded := &CheckSucceededEvent{ +func HumanWebAuthNCheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { + webAuthNAdded := &HumanWebAuthNCheckSucceededEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, webAuthNAdded) @@ -357,19 +357,19 @@ func CheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, return webAuthNAdded, nil } -type CheckFailedEvent struct { +type HumanWebAuthNCheckFailedEvent struct { eventstore.BaseEvent `json:"-"` //TODO: Handle Auth Req?? //*AuthRequest } -func (e *CheckFailedEvent) Data() interface{} { +func (e *HumanWebAuthNCheckFailedEvent) Data() interface{} { return e } -func NewU2FCheckFailedEvent(ctx context.Context) *CheckFailedEvent { - return &CheckFailedEvent{ +func NewHumanU2FCheckFailedEvent(ctx context.Context) *HumanWebAuthNCheckFailedEvent { + return &HumanWebAuthNCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanU2FTokenCheckFailedType, @@ -377,8 +377,8 @@ func NewU2FCheckFailedEvent(ctx context.Context) *CheckFailedEvent { } } -func NewPasswordlessCheckFailedEvent(ctx context.Context) *CheckFailedEvent { - return &CheckFailedEvent{ +func NewHumanPasswordlessCheckFailedEvent(ctx context.Context) *HumanWebAuthNCheckFailedEvent { + return &HumanWebAuthNCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordlessTokenCheckFailedType, @@ -386,8 +386,8 @@ func NewPasswordlessCheckFailedEvent(ctx context.Context) *CheckFailedEvent { } } -func CheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - webAuthNAdded := &CheckFailedEvent{ +func HumanWebAuthNCheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + webAuthNAdded := &HumanWebAuthNCheckFailedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, webAuthNAdded) diff --git a/internal/v2/repository/user/human/password/events.go b/internal/v2/repository/user/human_password.go similarity index 52% rename from internal/v2/repository/user/human/password/events.go rename to internal/v2/repository/user/human_password.go index 37288222be..e6ddf50abd 100644 --- a/internal/v2/repository/user/human/password/events.go +++ b/internal/v2/repository/user/human_password.go @@ -1,4 +1,4 @@ -package password +package user import ( "context" @@ -7,12 +7,12 @@ import ( "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2/repository" - "github.com/caos/zitadel/internal/v2/repository/user/human" + "github.com/caos/zitadel/internal/v2/domain" "time" ) const ( - passwordEventPrefix = eventstore.EventType("user.human.password.") + passwordEventPrefix = humanEventPrefix + "password." HumanPasswordChangedType = passwordEventPrefix + "changed" HumanPasswordCodeAddedType = passwordEventPrefix + "code.added" HumanPasswordCodeSentType = passwordEventPrefix + "code.sent" @@ -20,23 +20,23 @@ const ( HumanPasswordCheckFailedType = passwordEventPrefix + "check.failed" ) -type ChangedEvent struct { +type HumanPasswordChangedChangedEvent struct { eventstore.BaseEvent `json:"-"` Secret *crypto.CryptoValue `json:"secret,omitempty"` ChangeRequired bool `json:"changeRequired,omitempty"` } -func (e *ChangedEvent) Data() interface{} { +func (e *HumanPasswordChangedChangedEvent) Data() interface{} { return e } -func NewChangedEvent( +func NewHumanPasswordChangedEvent( ctx context.Context, secret *crypto.CryptoValue, changeRequired bool, -) *ChangedEvent { - return &ChangedEvent{ +) *HumanPasswordChangedChangedEvent { + return &HumanPasswordChangedChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordChangedType, @@ -46,8 +46,8 @@ func NewChangedEvent( } } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - humanAdded := &ChangedEvent{ +func HumanPasswordChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + humanAdded := &HumanPasswordChangedChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, humanAdded) @@ -58,25 +58,25 @@ func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) return humanAdded, nil } -type CodeAddedEvent struct { +type HumanPasswordCodeAddedEvent struct { eventstore.BaseEvent `json:"-"` - Code *crypto.CryptoValue `json:"code,omitempty"` - Expiry time.Duration `json:"expiry,omitempty"` - NotificationType human.NotificationType `json:"notificationType,omitempty"` + Code *crypto.CryptoValue `json:"code,omitempty"` + Expiry time.Duration `json:"expiry,omitempty"` + NotificationType domain.NotificationType `json:"notificationType,omitempty"` } -func (e *CodeAddedEvent) Data() interface{} { +func (e *HumanPasswordCodeAddedEvent) Data() interface{} { return e } -func NewPasswordCodeAddedEvent( +func NewHumanPasswordCodeAddedEvent( ctx context.Context, code *crypto.CryptoValue, expiry time.Duration, - notificationType human.NotificationType, -) *CodeAddedEvent { - return &CodeAddedEvent{ + notificationType domain.NotificationType, +) *HumanPasswordCodeAddedEvent { + return &HumanPasswordCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordCodeAddedType, @@ -87,8 +87,8 @@ func NewPasswordCodeAddedEvent( } } -func CodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - humanAdded := &CodeAddedEvent{ +func HumanPasswordCodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + humanAdded := &HumanPasswordCodeAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, humanAdded) @@ -99,16 +99,16 @@ func CodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, erro return humanAdded, nil } -type CodeSentEvent struct { +type HumanPasswordCodeSentEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *CodeSentEvent) Data() interface{} { +func (e *HumanPasswordCodeSentEvent) Data() interface{} { return nil } -func NewCodeSentEvent(ctx context.Context) *CodeSentEvent { - return &CodeSentEvent{ +func NewHumanPasswordCodeSentEvent(ctx context.Context) *HumanPasswordCodeSentEvent { + return &HumanPasswordCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordCodeSentType, @@ -116,22 +116,22 @@ func NewCodeSentEvent(ctx context.Context) *CodeSentEvent { } } -func CodeSentEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &CodeSentEvent{ +func HumanPasswordCodeSentEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanPasswordCodeSentEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type CheckSucceededEvent struct { +type HumanPasswordCheckSucceededEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *CheckSucceededEvent) Data() interface{} { +func (e *HumanPasswordCheckSucceededEvent) Data() interface{} { return nil } -func NewCheckSucceededEvent(ctx context.Context) *CheckSucceededEvent { - return &CheckSucceededEvent{ +func NewHumanPasswordCheckSucceededEvent(ctx context.Context) *HumanPasswordCheckSucceededEvent { + return &HumanPasswordCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordCheckSucceededType, @@ -139,22 +139,22 @@ func NewCheckSucceededEvent(ctx context.Context) *CheckSucceededEvent { } } -func CheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &CheckSucceededEvent{ +func HumanPasswordCheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanPasswordCheckSucceededEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type CheckFailedEvent struct { +type HumanPasswordCheckFailedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *CheckFailedEvent) Data() interface{} { +func (e *HumanPasswordCheckFailedEvent) Data() interface{} { return nil } -func NewCheckFailedEvent(ctx context.Context) *CheckFailedEvent { - return &CheckFailedEvent{ +func NewHumanPasswordCheckFailedEvent(ctx context.Context) *HumanPasswordCheckFailedEvent { + return &HumanPasswordCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPasswordCheckFailedType, @@ -162,8 +162,8 @@ func NewCheckFailedEvent(ctx context.Context) *CheckFailedEvent { } } -func CheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &CheckFailedEvent{ +func HumanPasswordCheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanPasswordCheckFailedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } diff --git a/internal/v2/repository/user/human/phone/events.go b/internal/v2/repository/user/human_phone.go similarity index 55% rename from internal/v2/repository/user/human/phone/events.go rename to internal/v2/repository/user/human_phone.go index 86a79668bf..a5bd2a9bbf 100644 --- a/internal/v2/repository/user/human/phone/events.go +++ b/internal/v2/repository/user/human_phone.go @@ -1,4 +1,4 @@ -package phone +package user import ( "context" @@ -11,7 +11,7 @@ import ( ) const ( - phoneEventPrefix = eventstore.EventType("user.human.phone.") + phoneEventPrefix = humanEventPrefix + "phone." HumanPhoneChangedType = phoneEventPrefix + "changed" HumanPhoneRemovedType = phoneEventPrefix + "removed" HumanPhoneVerifiedType = phoneEventPrefix + "verified" @@ -20,18 +20,18 @@ const ( HumanPhoneCodeSentType = phoneEventPrefix + "code.sent" ) -type ChangedEvent struct { +type HumanPhoneChangedEvent struct { eventstore.BaseEvent `json:"-"` PhoneNumber string `json:"phone,omitempty"` } -func (e *ChangedEvent) Data() interface{} { +func (e *HumanPhoneChangedEvent) Data() interface{} { return e } -func NewChangedEvent(ctx context.Context, phone string) *ChangedEvent { - return &ChangedEvent{ +func NewHumanPhoneChangedEvent(ctx context.Context, phone string) *HumanPhoneChangedEvent { + return &HumanPhoneChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPhoneChangedType, @@ -40,8 +40,8 @@ func NewChangedEvent(ctx context.Context, phone string) *ChangedEvent { } } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - phoneChangedEvent := &ChangedEvent{ +func HumanPhoneChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + phoneChangedEvent := &HumanPhoneChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, phoneChangedEvent) @@ -52,16 +52,16 @@ func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) return phoneChangedEvent, nil } -type RemovedEvent struct { +type HumanPhoneRemovedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *RemovedEvent) Data() interface{} { +func (e *HumanPhoneRemovedEvent) Data() interface{} { return nil } -func NewRemovedEvent(ctx context.Context) *RemovedEvent { - return &RemovedEvent{ +func NewHumanPhoneRemovedEvent(ctx context.Context) *HumanPhoneRemovedEvent { + return &HumanPhoneRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPhoneRemovedType, @@ -69,24 +69,24 @@ func NewRemovedEvent(ctx context.Context) *RemovedEvent { } } -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &ChangedEvent{ +func HumanPhoneRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanPhoneChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type VerifiedEvent struct { +type HumanPhoneVerifiedEvent struct { eventstore.BaseEvent `json:"-"` IsPhoneVerified bool `json:"-"` } -func (e *VerifiedEvent) Data() interface{} { +func (e *HumanPhoneVerifiedEvent) Data() interface{} { return nil } -func NewVerifiedEvent(ctx context.Context) *VerifiedEvent { - return &VerifiedEvent{ +func NewHumanPhoneVerifiedEvent(ctx context.Context) *HumanPhoneVerifiedEvent { + return &HumanPhoneVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPhoneVerifiedType, @@ -94,23 +94,23 @@ func NewVerifiedEvent(ctx context.Context) *VerifiedEvent { } } -func VerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &VerifiedEvent{ +func HumanPhoneVerifiedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanPhoneVerifiedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), IsPhoneVerified: true, }, nil } -type VerificationFailedEvent struct { +type HumanPhoneVerificationFailedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *VerificationFailedEvent) Data() interface{} { +func (e *HumanPhoneVerificationFailedEvent) Data() interface{} { return nil } -func NewVerificationFailedEvent(ctx context.Context) *VerificationFailedEvent { - return &VerificationFailedEvent{ +func NewHumanPhoneVerificationFailedEvent(ctx context.Context) *HumanPhoneVerificationFailedEvent { + return &HumanPhoneVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPhoneVerificationFailedType, @@ -118,29 +118,29 @@ func NewVerificationFailedEvent(ctx context.Context) *VerificationFailedEvent { } } -func VerificationFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &VerificationFailedEvent{ +func HumanPhoneVerificationFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanPhoneVerificationFailedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type CodeAddedEvent struct { +type HumanPhoneCodeAddedEvent struct { eventstore.BaseEvent `json:"-"` Code *crypto.CryptoValue `json:"code,omitempty"` Expiry time.Duration `json:"expiry,omitempty"` } -func (e *CodeAddedEvent) Data() interface{} { +func (e *HumanPhoneCodeAddedEvent) Data() interface{} { return e } -func NewCodeAddedEvent( +func NewHumanPhoneCodeAddedEvent( ctx context.Context, code *crypto.CryptoValue, expiry time.Duration, -) *CodeAddedEvent { - return &CodeAddedEvent{ +) *HumanPhoneCodeAddedEvent { + return &HumanPhoneCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPhoneCodeAddedType, @@ -150,8 +150,8 @@ func NewCodeAddedEvent( } } -func CodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - codeAdded := &CodeAddedEvent{ +func HumanPhoneCodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + codeAdded := &HumanPhoneCodeAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, codeAdded) @@ -162,16 +162,16 @@ func CodeAddedEventMapper(event *repository.Event) (eventstore.EventReader, erro return codeAdded, nil } -type CodeSentEvent struct { +type HumanPhoneCodeSentEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *CodeSentEvent) Data() interface{} { +func (e *HumanPhoneCodeSentEvent) Data() interface{} { return e } -func NewCodeSentEvent(ctx context.Context) *CodeSentEvent { - return &CodeSentEvent{ +func NewHumanPhoneCodeSentEvent(ctx context.Context) *HumanPhoneCodeSentEvent { + return &HumanPhoneCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, HumanPhoneCodeSentType, @@ -179,8 +179,8 @@ func NewCodeSentEvent(ctx context.Context) *CodeSentEvent { } } -func CodeSentEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &CodeSentEvent{ +func HumanPhoneCodeSentEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &HumanPhoneCodeSentEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } diff --git a/internal/v2/repository/user/human_profile.go b/internal/v2/repository/user/human_profile.go new file mode 100644 index 0000000000..2d797e31de --- /dev/null +++ b/internal/v2/repository/user/human_profile.go @@ -0,0 +1,52 @@ +package user + +import ( + "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" + "golang.org/x/text/language" +) + +const ( + profileEventPrefix = humanEventPrefix + "profile." + HumanProfileChangedType = profileEventPrefix + "changed" +) + +type HumanProfileChangedEvent struct { + eventstore.BaseEvent `json:"-"` + + FirstName string `json:"firstName,omitempty"` + LastName string `json:"lastName,omitempty"` + NickName string `json:"nickName,omitempty"` + DisplayName string `json:"displayName,omitempty"` + PreferredLanguage language.Tag `json:"preferredLanguage,omitempty"` + Gender domain.Gender `json:"gender,omitempty"` +} + +func (e *HumanProfileChangedEvent) Data() interface{} { + return e +} + +func NewHumanProfileChangedEvent(ctx context.Context) *HumanProfileChangedEvent { + return &HumanProfileChangedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + HumanProfileChangedType, + ), + } +} + +func HumanProfileChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + profileChanged := &HumanProfileChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + err := json.Unmarshal(event.Data, profileChanged) + if err != nil { + return nil, errors.ThrowInternal(err, "USER-5M0pd", "unable to unmarshal human profile changed") + } + + return profileChanged, nil +} diff --git a/internal/v2/repository/user/machine/events.go b/internal/v2/repository/user/machine.go similarity index 69% rename from internal/v2/repository/user/machine/events.go rename to internal/v2/repository/user/machine.go index 894c016ad3..bb61409e56 100644 --- a/internal/v2/repository/user/machine/events.go +++ b/internal/v2/repository/user/machine.go @@ -1,4 +1,4 @@ -package machine +package user import ( "context" @@ -9,12 +9,12 @@ import ( ) const ( - machineEventPrefix = eventstore.EventType("user.machine.") + machineEventPrefix = userEventTypePrefix + "machine." MachineAddedEventType = machineEventPrefix + "added" MachineChangedEventType = machineEventPrefix + "changed" ) -type AddedEvent struct { +type MachineAddedEvent struct { eventstore.BaseEvent `json:"-"` UserName string `json:"userName"` @@ -23,17 +23,17 @@ type AddedEvent struct { Description string `json:"description,omitempty"` } -func (e *AddedEvent) Data() interface{} { +func (e *MachineAddedEvent) Data() interface{} { return e } -func NewAddedEvent( +func NewMachineAddedEvent( ctx context.Context, userName, name, description string, -) *AddedEvent { - return &AddedEvent{ +) *MachineAddedEvent { + return &MachineAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, MachineAddedEventType, @@ -44,8 +44,8 @@ func NewAddedEvent( } } -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - machineAdded := &AddedEvent{ +func MachineAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + machineAdded := &MachineAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, machineAdded) @@ -56,7 +56,7 @@ func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { return machineAdded, nil } -type ChangedEvent struct { +type MachineChangedEvent struct { eventstore.BaseEvent `json:"-"` UserName string `json:"userName"` @@ -65,29 +65,23 @@ type ChangedEvent struct { Description string `json:"description,omitempty"` } -func (e *ChangedEvent) Data() interface{} { +func (e *MachineChangedEvent) Data() interface{} { return e } -func NewChangedEvent( +func NewMachineChangedEvent( ctx context.Context, - userName, - name, - description string, -) *ChangedEvent { - return &ChangedEvent{ +) *MachineChangedEvent { + return &MachineChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, MachineChangedEventType, ), - UserName: userName, - Name: name, - Description: description, } } -func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - machineChanged := &ChangedEvent{ +func MachineChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + machineChanged := &MachineChangedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, machineChanged) diff --git a/internal/v2/repository/user/machine/keys/events.go b/internal/v2/repository/user/machine/keys/events.go deleted file mode 100644 index 164fd645d9..0000000000 --- a/internal/v2/repository/user/machine/keys/events.go +++ /dev/null @@ -1,95 +0,0 @@ -package keys - -import ( - "context" - "encoding/json" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/eventstore/v2/repository" - "time" -) - -const ( - machineKeyEventPrefix = eventstore.EventType("user.machine.key.") - MachineKeyAddedEventType = machineKeyEventPrefix + "added" - MachineKeyRemovedEventType = machineKeyEventPrefix + "removed" -) - -type AddedEvent struct { - eventstore.BaseEvent `json:"-"` - - KeyID string `json:"keyId,omitempty"` - Type MachineKeyType `json:"type,omitempty"` - ExpirationDate time.Time `json:"expirationDate,omitempty"` - PublicKey []byte `json:"publicKey,omitempty"` -} - -func (e *AddedEvent) Data() interface{} { - return e -} - -func NewAddedEvent( - ctx context.Context, - keyID string, - keyType MachineKeyType, - expirationDate time.Time, - publicKey []byte, -) *AddedEvent { - return &AddedEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - MachineKeyAddedEventType, - ), - KeyID: keyID, - Type: keyType, - ExpirationDate: expirationDate, - PublicKey: publicKey, - } -} - -func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - machineAdded := &AddedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - err := json.Unmarshal(event.Data, machineAdded) - if err != nil { - return nil, errors.ThrowInternal(err, "USER-rEs8f", "unable to unmarshal machine key added") - } - - return machineAdded, nil -} - -type RemovedEvent struct { - eventstore.BaseEvent `json:"-"` - - KeyID string `json:"keyId,omitempty"` -} - -func (e *RemovedEvent) Data() interface{} { - return e -} - -func NewRemovedEvent( - ctx context.Context, - keyID string, -) *RemovedEvent { - return &RemovedEvent{ - BaseEvent: *eventstore.NewBaseEventForPush( - ctx, - MachineKeyRemovedEventType, - ), - KeyID: keyID, - } -} - -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - machineRemoved := &RemovedEvent{ - BaseEvent: *eventstore.BaseEventFromRepo(event), - } - err := json.Unmarshal(event.Data, machineRemoved) - if err != nil { - return nil, errors.ThrowInternal(err, "USER-5Gm9s", "unable to unmarshal machine key removed") - } - - return machineRemoved, nil -} diff --git a/internal/v2/repository/user/machine_key.go b/internal/v2/repository/user/machine_key.go new file mode 100644 index 0000000000..8730e1e306 --- /dev/null +++ b/internal/v2/repository/user/machine_key.go @@ -0,0 +1,96 @@ +package user + +import ( + "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" + "github.com/caos/zitadel/internal/v2/domain" + "time" +) + +const ( + machineKeyEventPrefix = machineEventPrefix + "key." + MachineKeyAddedEventType = machineKeyEventPrefix + "added" + MachineKeyRemovedEventType = machineKeyEventPrefix + "removed" +) + +type MachineKeyAddedEvent struct { + eventstore.BaseEvent `json:"-"` + + KeyID string `json:"keyId,omitempty"` + KeyType domain.MachineKeyType `json:"type,omitempty"` + ExpirationDate time.Time `json:"expirationDate,omitempty"` + PublicKey []byte `json:"publicKey,omitempty"` +} + +func (e *MachineKeyAddedEvent) Data() interface{} { + return e +} + +func NewMachineKeyAddedEvent( + ctx context.Context, + keyID string, + keyType domain.MachineKeyType, + expirationDate time.Time, + publicKey []byte, +) *MachineKeyAddedEvent { + return &MachineKeyAddedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + MachineKeyAddedEventType, + ), + KeyID: keyID, + KeyType: keyType, + ExpirationDate: expirationDate, + PublicKey: publicKey, + } +} + +func MachineKeyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + machineKeyAdded := &MachineKeyAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + err := json.Unmarshal(event.Data, machineKeyAdded) + if err != nil { + return nil, errors.ThrowInternal(err, "USER-p0ovS", "unable to unmarshal machine key removed") + } + + return machineKeyAdded, nil +} + +type MachineKeyRemovedEvent struct { + eventstore.BaseEvent `json:"-"` + + KeyID string `json:"keyId,omitempty"` +} + +func (e *MachineKeyRemovedEvent) Data() interface{} { + return e +} + +func NewMachineKeyRemovedEvent( + ctx context.Context, + keyID string, +) *MachineKeyRemovedEvent { + return &MachineKeyRemovedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + MachineKeyRemovedEventType, + ), + KeyID: keyID, + } +} + +func MachineKeyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + machineRemoved := &MachineKeyRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + err := json.Unmarshal(event.Data, machineRemoved) + if err != nil { + return nil, errors.ThrowInternal(err, "USER-5Gm9s", "unable to unmarshal machine key removed") + } + + return machineRemoved, nil +} diff --git a/internal/v2/repository/user/read_model.go b/internal/v2/repository/user/read_model.go deleted file mode 100644 index 5caf9f51f3..0000000000 --- a/internal/v2/repository/user/read_model.go +++ /dev/null @@ -1,52 +0,0 @@ -package user - -import ( - "github.com/caos/zitadel/internal/eventstore/v2" -) - -type ReadModel struct { - eventstore.ReadModel -} - -func NewReadModel(id string) *ReadModel { - return &ReadModel{ - ReadModel: eventstore.ReadModel{ - AggregateID: id, - }, - } -} - -func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) { - rm.ReadModel.AppendEvents(events...) - for _, event := range events { - switch event.(type) { - // TODO: implement append events - } - } -} - -func (rm *ReadModel) Reduce() (err error) { - for _, event := range rm.Events { - switch event.(type) { - //TODO: implement reduce - } - } - for _, reduce := range []func() error{ - rm.ReadModel.Reduce, - } { - if err = reduce(); err != nil { - return err - } - } - - return nil -} - -func (rm *ReadModel) AppendAndReduce(events ...eventstore.EventReader) error { - rm.AppendEvents(events...) - return rm.Reduce() -} - -func (rm *ReadModel) Query() *eventstore.SearchQueryBuilder { - return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, AggregateType).AggregateIDs(rm.AggregateID) -} diff --git a/internal/v2/repository/user/events.go b/internal/v2/repository/user/user.go similarity index 74% rename from internal/v2/repository/user/events.go rename to internal/v2/repository/user/user.go index a402cada61..01ecf03cfe 100644 --- a/internal/v2/repository/user/events.go +++ b/internal/v2/repository/user/user.go @@ -22,16 +22,16 @@ const ( UserUserNameChangedType = userEventTypePrefix + "username.changed" ) -type LockedEvent struct { +type UserLockedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *LockedEvent) Data() interface{} { +func (e *UserLockedEvent) Data() interface{} { return nil } -func NewLockedEvent(ctx context.Context) *LockedEvent { - return &LockedEvent{ +func NewUserLockedEvent(ctx context.Context) *UserLockedEvent { + return &UserLockedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserLockedType, @@ -39,22 +39,22 @@ func NewLockedEvent(ctx context.Context) *LockedEvent { } } -func LockedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &LockedEvent{ +func UserLockedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &UserLockedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type UnlockedEvent struct { +type UserUnlockedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *UnlockedEvent) Data() interface{} { +func (e *UserUnlockedEvent) Data() interface{} { return nil } -func NewUnlockedEvent(ctx context.Context) *UnlockedEvent { - return &UnlockedEvent{ +func NewUserUnlockedEvent(ctx context.Context) *UserUnlockedEvent { + return &UserUnlockedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserUnlockedType, @@ -62,22 +62,22 @@ func NewUnlockedEvent(ctx context.Context) *UnlockedEvent { } } -func UnlockedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &UnlockedEvent{ +func UserUnlockedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &UserUnlockedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type DeactivatedEvent struct { +type UserDeactivatedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *DeactivatedEvent) Data() interface{} { +func (e *UserDeactivatedEvent) Data() interface{} { return nil } -func NewDeactivatedEvent(ctx context.Context) *DeactivatedEvent { - return &DeactivatedEvent{ +func NewUserDeactivatedEvent(ctx context.Context) *UserDeactivatedEvent { + return &UserDeactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserDeactivatedType, @@ -85,22 +85,22 @@ func NewDeactivatedEvent(ctx context.Context) *DeactivatedEvent { } } -func DeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &DeactivatedEvent{ +func UserDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &UserDeactivatedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type ReactivatedEvent struct { +type UserReactivatedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *ReactivatedEvent) Data() interface{} { +func (e *UserReactivatedEvent) Data() interface{} { return nil } -func NewReactivatedEvent(ctx context.Context) *ReactivatedEvent { - return &ReactivatedEvent{ +func NewUserReactivatedEvent(ctx context.Context) *UserReactivatedEvent { + return &UserReactivatedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserReactivatedType, @@ -108,22 +108,22 @@ func NewReactivatedEvent(ctx context.Context) *ReactivatedEvent { } } -func ReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &ReactivatedEvent{ +func UserReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &UserReactivatedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type RemovedEvent struct { +type UserRemovedEvent struct { eventstore.BaseEvent `json:"-"` } -func (e *RemovedEvent) Data() interface{} { +func (e *UserRemovedEvent) Data() interface{} { return nil } -func NewRemovedEvent(ctx context.Context) *RemovedEvent { - return &RemovedEvent{ +func NewUserRemovedEvent(ctx context.Context) *UserRemovedEvent { + return &UserRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserRemovedType, @@ -131,13 +131,13 @@ func NewRemovedEvent(ctx context.Context) *RemovedEvent { } } -func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - return &RemovedEvent{ +func UserRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &UserRemovedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), }, nil } -type TokenAddedEvent struct { +type UserTokenAddedEvent struct { eventstore.BaseEvent `json:"-"` TokenID string `json:"tokenId"` @@ -149,11 +149,11 @@ type TokenAddedEvent struct { PreferredLanguage string `json:"preferredLanguage"` } -func (e *TokenAddedEvent) Data() interface{} { +func (e *UserTokenAddedEvent) Data() interface{} { return e } -func NewTokenAddedEvent( +func NewUserTokenAddedEvent( ctx context.Context, tokenID, applicationID, @@ -162,8 +162,8 @@ func NewTokenAddedEvent( audience, scopes []string, expiration time.Time, -) *TokenAddedEvent { - return &TokenAddedEvent{ +) *UserTokenAddedEvent { + return &UserTokenAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserTokenAddedType, @@ -177,8 +177,8 @@ func NewTokenAddedEvent( } } -func TokenAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { - tokenAdded := &TokenAddedEvent{ +func UserTokenAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + tokenAdded := &UserTokenAddedEvent{ BaseEvent: *eventstore.BaseEventFromRepo(event), } err := json.Unmarshal(event.Data, tokenAdded) diff --git a/internal/v2/repository/user/v1/events.go b/internal/v2/repository/user/v1.go similarity index 73% rename from internal/v2/repository/user/v1/events.go rename to internal/v2/repository/user/v1.go index 299fa657ca..1605251659 100644 --- a/internal/v2/repository/user/v1/events.go +++ b/internal/v2/repository/user/v1.go @@ -1,23 +1,15 @@ -package v1 +package user import ( "context" "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/eventstore/v2" - "github.com/caos/zitadel/internal/v2/repository/user/human" - "github.com/caos/zitadel/internal/v2/repository/user/human/address" - "github.com/caos/zitadel/internal/v2/repository/user/human/email" - "github.com/caos/zitadel/internal/v2/repository/user/human/mfa" - "github.com/caos/zitadel/internal/v2/repository/user/human/mfa/otp" - "github.com/caos/zitadel/internal/v2/repository/user/human/password" - "github.com/caos/zitadel/internal/v2/repository/user/human/phone" - "github.com/caos/zitadel/internal/v2/repository/user/human/profile" + "github.com/caos/zitadel/internal/v2/domain" "golang.org/x/text/language" "time" ) const ( - userEventTypePrefix = eventstore.EventType("user.") UserV1AddedType = userEventTypePrefix + "added" UserV1RegisteredType = userEventTypePrefix + "selfregistered" UserV1InitialCodeAddedType = userEventTypePrefix + "initialization.code.added" @@ -73,7 +65,7 @@ func NewUserV1AddedEvent( nickName, displayName string, preferredLanguage language.Tag, - gender human.Gender, + gender domain.Gender, emailAddress, phoneNumber, country, @@ -81,8 +73,8 @@ func NewUserV1AddedEvent( postalCode, region, streetAddress string, -) *human.AddedEvent { - return &human.AddedEvent{ +) *HumanAddedEvent { + return &HumanAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1AddedType, @@ -112,7 +104,7 @@ func NewUserV1RegisteredEvent( nickName, displayName string, preferredLanguage language.Tag, - gender int32, + gender domain.Gender, emailAddress, phoneNumber, country, @@ -120,8 +112,8 @@ func NewUserV1RegisteredEvent( postalCode, region, streetAddress string, -) *human.RegisteredEvent { - return &human.RegisteredEvent{ +) *HumanRegisteredEvent { + return &HumanRegisteredEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1RegisteredType, @@ -147,8 +139,8 @@ func NewUserV1InitialCodeAddedEvent( ctx context.Context, code *crypto.CryptoValue, expiry time.Duration, -) *human.InitialCodeAddedEvent { - return &human.InitialCodeAddedEvent{ +) *HumanInitialCodeAddedEvent { + return &HumanInitialCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1InitialCodeAddedType, @@ -158,8 +150,8 @@ func NewUserV1InitialCodeAddedEvent( } } -func NewUserV1InitialCodeSentEvent(ctx context.Context) *human.InitialCodeSentEvent { - return &human.InitialCodeSentEvent{ +func NewUserV1InitialCodeSentEvent(ctx context.Context) *HumanInitialCodeSentEvent { + return &HumanInitialCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1InitialCodeSentType, @@ -167,8 +159,8 @@ func NewUserV1InitialCodeSentEvent(ctx context.Context) *human.InitialCodeSentEv } } -func NewUserV1InitializedCheckSucceededEvent(ctx context.Context) *human.InitializedCheckSucceededEvent { - return &human.InitializedCheckSucceededEvent{ +func NewUserV1InitializedCheckSucceededEvent(ctx context.Context) *HumanInitializedCheckSucceededEvent { + return &HumanInitializedCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1InitializedCheckSucceededType, @@ -176,8 +168,8 @@ func NewUserV1InitializedCheckSucceededEvent(ctx context.Context) *human.Initial } } -func NewUserV1InitializedCheckFailedEvent(ctx context.Context) *human.InitializedCheckFailedEvent { - return &human.InitializedCheckFailedEvent{ +func NewUserV1InitializedCheckFailedEvent(ctx context.Context) *HumanInitializedCheckFailedEvent { + return &HumanInitializedCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1InitializedCheckFailedType, @@ -185,8 +177,8 @@ func NewUserV1InitializedCheckFailedEvent(ctx context.Context) *human.Initialize } } -func NewUserV1SignedOutEvent(ctx context.Context) *human.SignedOutEvent { - return &human.SignedOutEvent{ +func NewUserV1SignedOutEvent(ctx context.Context) *HumanSignedOutEvent { + return &HumanSignedOutEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1SignedOutType, @@ -198,8 +190,8 @@ func NewUserV1PasswordChangedEvent( ctx context.Context, secret *crypto.CryptoValue, changeRequired bool, -) *password.ChangedEvent { - return &password.ChangedEvent{ +) *HumanPasswordChangedChangedEvent { + return &HumanPasswordChangedChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PasswordChangedType, @@ -213,9 +205,9 @@ func NewUserV1PasswordCodeAddedEvent( ctx context.Context, code *crypto.CryptoValue, expiry time.Duration, - notificationType human.NotificationType, -) *password.CodeAddedEvent { - return &password.CodeAddedEvent{ + notificationType domain.NotificationType, +) *HumanPasswordCodeAddedEvent { + return &HumanPasswordCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PasswordCodeAddedType, @@ -226,8 +218,8 @@ func NewUserV1PasswordCodeAddedEvent( } } -func NewUserV1PasswordCodeSentEvent(ctx context.Context) *password.CodeSentEvent { - return &password.CodeSentEvent{ +func NewUserV1PasswordCodeSentEvent(ctx context.Context) *HumanPasswordCodeSentEvent { + return &HumanPasswordCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PasswordCodeSentType, @@ -235,8 +227,8 @@ func NewUserV1PasswordCodeSentEvent(ctx context.Context) *password.CodeSentEvent } } -func NewUserV1PasswordCheckSucceededEvent(ctx context.Context) *password.CheckSucceededEvent { - return &password.CheckSucceededEvent{ +func NewUserV1PasswordCheckSucceededEvent(ctx context.Context) *HumanPasswordCheckSucceededEvent { + return &HumanPasswordCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PasswordCheckSucceededType, @@ -244,8 +236,8 @@ func NewUserV1PasswordCheckSucceededEvent(ctx context.Context) *password.CheckSu } } -func NewUserV1PasswordCheckFailedEvent(ctx context.Context) *password.CheckFailedEvent { - return &password.CheckFailedEvent{ +func NewUserV1PasswordCheckFailedEvent(ctx context.Context) *HumanPasswordCheckFailedEvent { + return &HumanPasswordCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PasswordCheckFailedType, @@ -253,8 +245,8 @@ func NewUserV1PasswordCheckFailedEvent(ctx context.Context) *password.CheckFaile } } -func NewUserV1EmailChangedEvent(ctx context.Context, emailAddress string) *email.ChangedEvent { - return &email.ChangedEvent{ +func NewUserV1EmailChangedEvent(ctx context.Context, emailAddress string) *HumanEmailChangedEvent { + return &HumanEmailChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1EmailChangedType, @@ -263,8 +255,8 @@ func NewUserV1EmailChangedEvent(ctx context.Context, emailAddress string) *email } } -func NewUserV1EmailVerifiedEvent(ctx context.Context) *email.VerifiedEvent { - return &email.VerifiedEvent{ +func NewUserV1EmailVerifiedEvent(ctx context.Context) *HumanEmailVerifiedEvent { + return &HumanEmailVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1EmailVerifiedType, @@ -272,8 +264,8 @@ func NewUserV1EmailVerifiedEvent(ctx context.Context) *email.VerifiedEvent { } } -func NewUserV1EmailVerificationFailedEvent(ctx context.Context) *email.VerificationFailedEvent { - return &email.VerificationFailedEvent{ +func NewUserV1EmailVerificationFailedEvent(ctx context.Context) *HumanEmailVerificationFailedEvent { + return &HumanEmailVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1EmailVerificationFailedType, @@ -285,8 +277,8 @@ func NewUserV1EmailCodeAddedEvent( ctx context.Context, code *crypto.CryptoValue, expiry time.Duration, -) *email.CodeAddedEvent { - return &email.CodeAddedEvent{ +) *HumanEmailCodeAddedEvent { + return &HumanEmailCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1EmailCodeAddedType, @@ -296,8 +288,8 @@ func NewUserV1EmailCodeAddedEvent( } } -func NewUserV1EmailCodeSentEvent(ctx context.Context) *email.CodeSentEvent { - return &email.CodeSentEvent{ +func NewUserV1EmailCodeSentEvent(ctx context.Context) *HumanEmailCodeSentEvent { + return &HumanEmailCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1EmailCodeSentType, @@ -305,8 +297,8 @@ func NewUserV1EmailCodeSentEvent(ctx context.Context) *email.CodeSentEvent { } } -func NewUserV1PhoneChangedEvent(ctx context.Context, phone string) *phone.ChangedEvent { - return phone.HumanPhoneChangedEvent{ +func NewUserV1PhoneChangedEvent(ctx context.Context, phone string) *HumanPhoneChangedEvent { + return &HumanPhoneChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PhoneChangedType, @@ -315,8 +307,8 @@ func NewUserV1PhoneChangedEvent(ctx context.Context, phone string) *phone.Change } } -func NewUserV1PhoneRemovedEvent(ctx context.Context) *phone.RemovedEvent { - return &phone.RemovedEvent{ +func NewUserV1PhoneRemovedEvent(ctx context.Context) *HumanPhoneRemovedEvent { + return &HumanPhoneRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PhoneRemovedType, @@ -324,8 +316,8 @@ func NewUserV1PhoneRemovedEvent(ctx context.Context) *phone.RemovedEvent { } } -func NewUserV1PhoneVerifiedEvent(ctx context.Context) *phone.VerifiedEvent { - return &phone.VerifiedEvent{ +func NewUserV1PhoneVerifiedEvent(ctx context.Context) *HumanPhoneVerifiedEvent { + return &HumanPhoneVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PhoneVerifiedType, @@ -333,8 +325,8 @@ func NewUserV1PhoneVerifiedEvent(ctx context.Context) *phone.VerifiedEvent { } } -func NewUserV1PhoneVerificationFailedEvent(ctx context.Context) *phone.VerificationFailedEvent { - return &phone.VerificationFailedEvent{ +func NewUserV1PhoneVerificationFailedEvent(ctx context.Context) *HumanPhoneVerificationFailedEvent { + return &HumanPhoneVerificationFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PhoneVerificationFailedType, @@ -346,8 +338,8 @@ func NewUserV1PhoneCodeAddedEvent( ctx context.Context, code *crypto.CryptoValue, expiry time.Duration, -) *phone.CodeAddedEvent { - return &phone.CodeAddedEvent{ +) *HumanPhoneCodeAddedEvent { + return &HumanPhoneCodeAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PhoneCodeAddedType, @@ -357,8 +349,8 @@ func NewUserV1PhoneCodeAddedEvent( } } -func NewUserV1PhoneCodeSentEvent(ctx context.Context) *phone.CodeSentEvent { - return &phone.CodeSentEvent{ +func NewUserV1PhoneCodeSentEvent(ctx context.Context) *HumanPhoneCodeSentEvent { + return &HumanPhoneCodeSentEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1PhoneCodeSentType, @@ -373,9 +365,9 @@ func NewUserV1ProfileChangedEvent( nickName, displayName string, preferredLanguage language.Tag, - gender human.Gender, -) *profile.ChangedEvent { - return &profile.ChangedEvent{ + gender domain.Gender, +) *HumanProfileChangedEvent { + return &HumanProfileChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1ProfileChangedType, @@ -396,8 +388,8 @@ func NewUserV1AddressChangedEvent( postalCode, region, streetAddress string, -) *address.HumanAddressChangedEvent { - return &address.HumanAddressChangedEvent{ +) *HumanAddressChangedEvent { + return &HumanAddressChangedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1AddressChangedType, @@ -410,8 +402,8 @@ func NewUserV1AddressChangedEvent( } } -func NewUserV1MFAInitSkippedEvent(ctx context.Context) *mfa.InitSkippedEvent { - return &mfa.InitSkippedEvent{ +func NewUserV1MFAInitSkippedEvent(ctx context.Context) *HumanMFAInitSkippedEvent { + return &HumanMFAInitSkippedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1MFAInitSkippedType, @@ -422,8 +414,8 @@ func NewUserV1MFAInitSkippedEvent(ctx context.Context) *mfa.InitSkippedEvent { func NewUserV1MFAOTPAddedEvent( ctx context.Context, secret *crypto.CryptoValue, -) *otp.AddedEvent { - return &otp.AddedEvent{ +) *HumanOTPAddedEvent { + return &HumanOTPAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1MFAOTPAddedType, @@ -432,8 +424,8 @@ func NewUserV1MFAOTPAddedEvent( } } -func NewUserV1MFAOTPVerifiedEvent(ctx context.Context) *otp.VerifiedEvent { - return &otp.VerifiedEvent{ +func NewUserV1MFAOTPVerifiedEvent(ctx context.Context) *HumanOTPVerifiedEvent { + return &HumanOTPVerifiedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1MFAOTPVerifiedType, @@ -441,8 +433,8 @@ func NewUserV1MFAOTPVerifiedEvent(ctx context.Context) *otp.VerifiedEvent { } } -func NewUserV1MFAOTPRemovedEvent(ctx context.Context) *otp.RemovedEvent { - return &otp.RemovedEvent{ +func NewUserV1MFAOTPRemovedEvent(ctx context.Context) *HumanOTPRemovedEvent { + return &HumanOTPRemovedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1MFAOTPRemovedType, @@ -450,8 +442,8 @@ func NewUserV1MFAOTPRemovedEvent(ctx context.Context) *otp.RemovedEvent { } } -func NewUserV1MFAOTPCheckSucceededEvent(ctx context.Context) *otp.CheckSucceededEvent { - return &otp.CheckSucceededEvent{ +func NewUserV1MFAOTPCheckSucceededEvent(ctx context.Context) *HumanOTPCheckSucceededEvent { + return &HumanOTPCheckSucceededEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1MFAOTPCheckSucceededType, @@ -459,8 +451,8 @@ func NewUserV1MFAOTPCheckSucceededEvent(ctx context.Context) *otp.CheckSucceeded } } -func NewUserV1MFAOTPCheckFailedEvent(ctx context.Context) *otp.CheckFailedEvent { - return &otp.CheckFailedEvent{ +func NewUserV1MFAOTPCheckFailedEvent(ctx context.Context) *HumanOTPCheckFailedEvent { + return &HumanOTPCheckFailedEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, UserV1MFAOTPCheckFailedType, diff --git a/internal/v2/view/iam.go b/internal/v2/view/iam.go index fa3e054708..5291166536 100644 --- a/internal/v2/view/iam.go +++ b/internal/v2/view/iam.go @@ -21,7 +21,7 @@ func (rm *IAM) AppendEvents(events ...eventstore.EventReader) { rm.ReadModel.AppendEvents(events...) } -//Reduce implements eventstore.ReadModel +//Reduce implements eventstore.IAMMemberReadModel // func (rm *IAM) Reduce() (err error) { for _, event := range rm.Events {