From 61d16e4621930ff60a42d30eb8d750e186f6693a Mon Sep 17 00:00:00 2001 From: Livio Amstutz Date: Wed, 6 Jan 2021 10:47:55 +0100 Subject: [PATCH] fix: refactor setup (#1152) * add setup steps * refactoring * omitempty * cleanup * fixes --- cmd/zitadel/main.go | 17 +- cmd/zitadel/setup.yaml | 12 +- .../api/grpc/admin/login_policy_converter.go | 2 +- internal/setup/config.go | 98 ++------ internal/setup/setup.go | 213 +++--------------- internal/setup/setup_v2.go | 104 --------- internal/setup/step.go | 21 -- internal/setup/step1.go | 93 ++++---- internal/setup/step2.go | 61 ----- internal/setup/step3.go | 57 ----- internal/setup/step4.go | 57 ----- internal/setup/step5.go | 57 ----- internal/setup/step6.go | 58 ----- internal/setup/step7.go | 54 ----- internal/setup/step8.go | 54 ----- internal/setup/step9.go | 74 ------ internal/v2/command/command.go | 2 +- internal/v2/command/iam.go | 16 ++ internal/v2/command/iam_converter.go | 5 +- internal/v2/command/iam_model.go | 2 +- internal/v2/command/iam_policy_label.go | 23 +- internal/v2/command/iam_policy_login.go | 110 ++++++--- internal/v2/command/iam_policy_org_iam.go | 21 +- .../v2/command/iam_policy_password_age.go | 23 +- .../command/iam_policy_password_complexity.go | 14 +- .../v2/command/iam_policy_password_lockout.go | 23 +- internal/v2/command/setup.go | 71 +++++- internal/v2/command/setup_step1.go | 18 +- internal/v2/command/setup_step2.go | 47 ++-- internal/v2/command/setup_step3.go | 36 +++ internal/v2/command/setup_step4.go | 36 +++ internal/v2/command/setup_step5.go | 35 +++ internal/v2/command/setup_step6.go | 36 +++ internal/v2/command/setup_step7.go | 37 +++ internal/v2/command/setup_step8.go | 37 +++ internal/v2/command/setup_step9.go | 50 ++++ internal/v2/domain/iam.go | 22 ++ internal/v2/domain/step.go | 1 + internal/v2/repository/policy/login.go | 18 +- .../repository/policy/policy_login_factors.go | 2 +- .../policy/policy_login_identity_provider.go | 4 +- .../v2/repository/policy/policy_org_iam.go | 4 +- .../repository/policy/policy_password_age.go | 4 +- .../policy/policy_password_complexity.go | 18 +- .../policy/policy_password_lockout.go | 2 +- 45 files changed, 708 insertions(+), 1041 deletions(-) delete mode 100644 internal/setup/setup_v2.go delete mode 100644 internal/setup/step.go delete mode 100644 internal/setup/step2.go delete mode 100644 internal/setup/step3.go delete mode 100644 internal/setup/step4.go delete mode 100644 internal/setup/step5.go delete mode 100644 internal/setup/step6.go delete mode 100644 internal/setup/step7.go delete mode 100644 internal/setup/step8.go delete mode 100644 internal/setup/step9.go create mode 100644 internal/v2/command/iam.go create mode 100644 internal/v2/command/setup_step3.go create mode 100644 internal/v2/command/setup_step4.go create mode 100644 internal/v2/command/setup_step5.go create mode 100644 internal/v2/command/setup_step6.go create mode 100644 internal/v2/command/setup_step7.go create mode 100644 internal/v2/command/setup_step8.go create mode 100644 internal/v2/command/setup_step9.go create mode 100644 internal/v2/domain/iam.go diff --git a/cmd/zitadel/main.go b/cmd/zitadel/main.go index 477dadc5ad..d20e89a6c9 100644 --- a/cmd/zitadel/main.go +++ b/cmd/zitadel/main.go @@ -3,11 +3,13 @@ package main import ( "context" "flag" + metrics "github.com/caos/zitadel/internal/telemetry/metrics/config" "github.com/caos/zitadel/internal/v2/command" "github.com/caos/zitadel/internal/v2/query" "github.com/caos/logging" + admin_es "github.com/caos/zitadel/internal/admin/repository/eventsourcing" "github.com/caos/zitadel/internal/api" internal_authz "github.com/caos/zitadel/internal/api/authz" @@ -176,8 +178,15 @@ func startSetup(configPaths []string, localDevMode bool) { ctx := context.Background() - setup, err := setup.StartSetupV2(conf.Eventstore, conf.SystemDefaults) - logging.Log("SERVE-fD252").OnError(err).Panic("failed to start setup") - err = setup.ExecuteV2(ctx, conf.SetUp) - logging.Log("SERVE-djs3R").OnError(err).Panic("failed to execute setup") + es, err := es_int.Start(conf.Eventstore) + logging.Log("MAIN-Ddt3").OnError(err).Fatal("cannot start eventstore") + + commands, err := command.StartCommandSide(&command.Config{ + Eventstore: es.V2(), + SystemDefaults: conf.SystemDefaults, + }) + logging.Log("MAIN-dsjrr").OnError(err).Fatal("cannot start command side") + + err = setup.Execute(ctx, conf.SetUp, conf.SystemDefaults.IamID, commands) + logging.Log("MAIN-djs3R").OnError(err).Panic("failed to execute setup steps") } diff --git a/cmd/zitadel/setup.yaml b/cmd/zitadel/setup.yaml index df2cc6c8fb..b2134f22e4 100644 --- a/cmd/zitadel/setup.yaml +++ b/cmd/zitadel/setup.yaml @@ -26,10 +26,10 @@ SetUp: Step1: GlobalOrg: 'Global' IAMProject: 'Zitadel' -# DefaultLoginPolicy: -# AllowUsernamePassword: true -# AllowRegister: true -# AllowExternalIdp: true + DefaultLoginPolicy: + AllowUsernamePassword: true + AllowRegister: true + AllowExternalIdp: true # Orgs: # - Name: 'Global' # Domain: 'global.caos.ch' @@ -96,8 +96,8 @@ SetUp: PrimaryColor: '#222324' SecondaryColor: '#ffffff' Step7: - DefaultSecondFactor: 1 #SecondFactorTypeOTP + OTP: true Step8: - DefaultSecondFactor: 2 #SecondFactorTypeU2F + U2F: true Step9: Passwordless: true \ No newline at end of file diff --git a/internal/api/grpc/admin/login_policy_converter.go b/internal/api/grpc/admin/login_policy_converter.go index 5fd57b57ba..4f146e1f93 100644 --- a/internal/api/grpc/admin/login_policy_converter.go +++ b/internal/api/grpc/admin/login_policy_converter.go @@ -48,7 +48,7 @@ func loginPolicyViewFromModel(policy *iam_model.LoginPolicyView) *admin.DefaultL AllowExternalIdp: policy.AllowExternalIDP, AllowRegister: policy.AllowRegister, ForceMfa: policy.ForceMFA, - PasswordlessType: passwordlessTypeFromDomain(policy.PasswordlessType), + PasswordlessType: admin.PasswordlessType(policy.PasswordlessType), CreationDate: creationDate, ChangeDate: changeDate, } diff --git a/internal/setup/config.go b/internal/setup/config.go index 01143e7af1..c0f19fb6d9 100644 --- a/internal/setup/config.go +++ b/internal/setup/config.go @@ -1,92 +1,40 @@ package setup import ( - "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/command" + "github.com/caos/zitadel/internal/v2/domain" ) type IAMSetUp struct { - Step1 *Step1 - //Step2 *Step2 - //Step3 *Step3 - //Step4 *Step4 - //Step5 *Step5 - //Step6 *Step6 - //Step7 *Step7 - //Step8 *Step8 - //Step9 *Step9 + Step1 *command.Step1 + Step2 *command.Step2 + Step3 *command.Step3 + Step4 *command.Step4 + Step5 *command.Step5 + Step6 *command.Step6 + Step7 *command.Step7 + Step8 *command.Step8 + Step9 *command.Step9 } -func (setup *IAMSetUp) steps(currentDone iam_model.Step) ([]stepV2, error) { - steps := make([]stepV2, 0) - missingSteps := make([]iam_model.Step, 0) +func (setup *IAMSetUp) Steps(currentDone domain.Step) ([]command.Step, error) { + steps := make([]command.Step, 0) - for _, step := range []stepV2{ + for _, step := range []command.Step{ setup.Step1, - //setup.Step2, - //setup.Step3, - //setup.Step4, - //setup.Step5, - //setup.Step6, - //setup.Step7, - //setup.Step8, - //setup.Step9, + setup.Step2, + setup.Step3, + setup.Step4, + setup.Step5, + setup.Step6, + setup.Step7, + setup.Step8, + setup.Step9, } { - if step.step() <= currentDone { - continue - } - - if step.isNil() { - missingSteps = append(missingSteps, step.step()) + if step.Step() <= currentDone { continue } steps = append(steps, step) } - - if len(missingSteps) > 0 { - return nil, errors.ThrowPreconditionFailedf(nil, "SETUP-1nk49", "steps %v not configured", missingSteps) - } - return steps, nil } - -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 -} diff --git a/internal/setup/setup.go b/internal/setup/setup.go index 1e854698d6..c28e98f719 100644 --- a/internal/setup/setup.go +++ b/internal/setup/setup.go @@ -3,24 +3,14 @@ package setup import ( "context" - "github.com/caos/zitadel/internal/api/authz" - iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing" - org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing" - proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing" - usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" + "github.com/caos/logging" + + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/v2/command" + "github.com/caos/zitadel/internal/v2/domain" ) -type Setup struct { - iamID string - IamEvents *iam_event.IAMEventstore - OrgEvents *org_event.OrgEventstore - UserEvents *usr_event.UserEventstore - ProjectEvents *proj_event.ProjectEventstore - - Commands *command.CommandSide -} - const ( OrgOwnerRole = "ORG_OWNER" SetupUser = "SETUP" @@ -38,169 +28,32 @@ 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 == 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}) +func Execute(ctx context.Context, setUpConfig IAMSetUp, iamID string, commands *command.CommandSide) error { + logging.Log("SETUP-JAK2q").Info("starting setup") + + iam, err := commands.GetIAM(ctx, 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 = &domain.IAM{ObjectRoot: models.ObjectRoot{AggregateID: iamID}} + } + + steps, err := setUpConfig.Steps(iam.SetUpDone) + if err != nil || len(steps) == 0 { + return err + } + + err = commands.ExecuteSetupSteps(ctx, steps) + if err != nil { + return err + } + + logging.Log("SETUP-ds31h").Info("setup done") + return nil } diff --git a/internal/setup/setup_v2.go b/internal/setup/setup_v2.go deleted file mode 100644 index a485029335..0000000000 --- a/internal/setup/setup_v2.go +++ /dev/null @@ -1,104 +0,0 @@ -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 deleted file mode 100644 index 821dbd2d4c..0000000000 --- a/internal/setup/step.go +++ /dev/null @@ -1,21 +0,0 @@ -package setup - -import ( - "context" - - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/v2/command" -) - -type step interface { - step() iam_model.Step - execute(context.Context) (*iam_model.IAM, error) - 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 5ba31b9b10..e74b575dda 100644 --- a/internal/setup/step1.go +++ b/internal/setup/step1.go @@ -1,52 +1,53 @@ package setup -import ( - "context" - - "github.com/caos/logging" - - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/v2/command" -) - -type Step1 struct { - //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 -} - -func (s *Step1) isNil() bool { - return s == nil -} - -func (s *Step1) step() iam_model.Step { - return iam_model.Step1 -} - -//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) +// TODO: implement +//import ( +// "context" +// +// "github.com/caos/logging" +// +// iam_model "github.com/caos/zitadel/internal/iam/model" +// "github.com/caos/zitadel/internal/v2/command" +//) +// +//type Step1 struct { +// //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 +//} +// +//func (s *Step1) isNil() bool { +// return s == nil +//} +// +//func (s *Step1) step() iam_model.Step { +// return iam_model.Step1 +//} +// +////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 (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-de342").WithField("step", s.step()).WithError(err).Error("unable to finish setup") +// return err +// } +// return nil //} - -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-de342").WithField("step", s.step()).WithError(err).Error("unable to finish setup") - return err - } - return nil -} // //func (step *Step1) loginPolicy(ctx context.Context, policy LoginPolicy) error { diff --git a/internal/setup/step2.go b/internal/setup/step2.go deleted file mode 100644 index bac8d0583f..0000000000 --- a/internal/setup/step2.go +++ /dev/null @@ -1,61 +0,0 @@ -package setup - -import ( - "context" - - "github.com/caos/logging" - - "github.com/caos/zitadel/internal/eventstore/models" - 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 { - DefaultPasswordComplexityPolicy iam_model.PasswordComplexityPolicy - - setup *Setup -} - -func (s *Step2) isNil() bool { - return s == nil -} - -func (step *Step2) step() iam_model.Step { - return iam_model.Step2 -} - -func (step *Step2) init(setup *Setup) { - step.setup = setup -} - -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) { - logging.Log("SETUP-Bs8id").Info("setting up password complexity policy") - policy.AggregateID = step.setup.iamID - iam, aggregate, err := step.setup.IamEvents.PrepareAddPasswordComplexityPolicy(ctx, policy) - if err != nil { - return nil, nil, err - } - return iam, aggregate, nil -} diff --git a/internal/setup/step3.go b/internal/setup/step3.go deleted file mode 100644 index 1ebfd9a0e6..0000000000 --- a/internal/setup/step3.go +++ /dev/null @@ -1,57 +0,0 @@ -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" -) - -type Step3 struct { - DefaultPasswordAgePolicy iam_model.PasswordAgePolicy - - setup *Setup -} - -func (s *Step3) isNil() bool { - return s == nil -} - -func (step *Step3) step() iam_model.Step { - return iam_model.Step3 -} - -func (step *Step3) init(setup *Setup) { - step.setup = setup -} - -func (step *Step3) execute(ctx context.Context) (*iam_model.IAM, error) { - iam, agg, err := step.passwordAgePolicy(ctx, &step.DefaultPasswordAgePolicy) - if err != nil { - logging.Log("SETUP-Mski9").WithField("step", step.step()).WithError(err).Error("unable to finish setup (pw age policy)") - return nil, err - } - iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) - if err != nil { - logging.Log("SETUP-4Gsny").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-Yc8ui").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (step *Step3) passwordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_es_model.IAM, *models.Aggregate, error) { - logging.Log("SETUP-bVs8i").Info("setting up password complexity policy") - policy.AggregateID = step.setup.iamID - iam, aggregate, err := step.setup.IamEvents.PrepareAddPasswordAgePolicy(ctx, policy) - if err != nil { - return nil, nil, err - } - return iam, aggregate, nil -} diff --git a/internal/setup/step4.go b/internal/setup/step4.go deleted file mode 100644 index fa50bc1511..0000000000 --- a/internal/setup/step4.go +++ /dev/null @@ -1,57 +0,0 @@ -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" -) - -type Step4 struct { - DefaultPasswordLockoutPolicy iam_model.PasswordLockoutPolicy - - setup *Setup -} - -func (s *Step4) isNil() bool { - return s == nil -} - -func (step *Step4) step() iam_model.Step { - return iam_model.Step4 -} - -func (step *Step4) init(setup *Setup) { - step.setup = setup -} - -func (step *Step4) execute(ctx context.Context) (*iam_model.IAM, error) { - iam, agg, err := step.passwordLockoutPolicy(ctx, &step.DefaultPasswordLockoutPolicy) - if err != nil { - logging.Log("SETUP-xCd9i").WithField("step", step.step()).WithError(err).Error("unable to finish setup (pw age policy)") - return nil, err - } - iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) - if err != nil { - logging.Log("SETUP-bVsm9").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-wCxko").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (step *Step4) passwordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_es_model.IAM, *models.Aggregate, error) { - logging.Log("SETUP-vSfr4").Info("setting up password complexity policy") - policy.AggregateID = step.setup.iamID - iam, aggregate, err := step.setup.IamEvents.PrepareAddPasswordLockoutPolicy(ctx, policy) - if err != nil { - return nil, nil, err - } - return iam, aggregate, nil -} diff --git a/internal/setup/step5.go b/internal/setup/step5.go deleted file mode 100644 index d45f9a11fd..0000000000 --- a/internal/setup/step5.go +++ /dev/null @@ -1,57 +0,0 @@ -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" -) - -type Step5 struct { - DefaultOrgIAMPolicy iam_model.OrgIAMPolicy - - setup *Setup -} - -func (s *Step5) isNil() bool { - return s == nil -} - -func (step *Step5) step() iam_model.Step { - return iam_model.Step5 -} - -func (step *Step5) init(setup *Setup) { - step.setup = setup -} - -func (step *Step5) execute(ctx context.Context) (*iam_model.IAM, error) { - iam, agg, err := step.orgIAMPolicy(ctx, &step.DefaultOrgIAMPolicy) - if err != nil { - logging.Log("SETUP-3nKd9").WithField("step", step.step()).WithError(err).Error("unable to finish setup (org iam policy)") - return nil, err - } - iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) - if err != nil { - logging.Log("SETUP-5h8Ds").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-3fGk0").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (step *Step5) orgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_es_model.IAM, *models.Aggregate, error) { - logging.Log("SETUP-5Gn8s").Info("setting up org iam policy") - policy.AggregateID = step.setup.iamID - iam, aggregate, err := step.setup.IamEvents.PrepareAddOrgIAMPolicy(ctx, policy) - if err != nil { - return nil, nil, err - } - return iam, aggregate, nil -} diff --git a/internal/setup/step6.go b/internal/setup/step6.go deleted file mode 100644 index 57d46ee31b..0000000000 --- a/internal/setup/step6.go +++ /dev/null @@ -1,58 +0,0 @@ -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" -) - -type Step6 struct { - DefaultLabelPolicy iam_model.LabelPolicy - - setup *Setup -} - -func (s *Step6) isNil() bool { - return s == nil -} - -func (step *Step6) step() iam_model.Step { - return iam_model.Step6 -} - -func (step *Step6) init(setup *Setup) { - step.setup = setup -} - -func (step *Step6) execute(ctx context.Context) (*iam_model.IAM, error) { - iam, agg, err := step.labelPolicy(ctx, &step.DefaultLabelPolicy) - if err != nil { - logging.Log("SETUP-ZTuS1").WithField("step", step.step()).WithError(err).Error("unable to finish setup (Label policy)") - return nil, err - } - iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) - if err != nil { - logging.Log("SETUP-OkF8o").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-YbQ6T").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (step *Step6) labelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_es_model.IAM, *models.Aggregate, error) { - logging.Log("SETUP-geMuZ").Info("setting up labelpolicy") - policy.AggregateID = step.setup.iamID - iam, aggregate, err := step.setup.IamEvents.PrepareAddLabelPolicy(ctx, policy) - if err != nil { - return nil, nil, err - } - return iam, aggregate, nil -} diff --git a/internal/setup/step7.go b/internal/setup/step7.go deleted file mode 100644 index 99d445911c..0000000000 --- a/internal/setup/step7.go +++ /dev/null @@ -1,54 +0,0 @@ -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" -) - -type Step7 struct { - DefaultSecondFactor iam_model.SecondFactorType - - setup *Setup -} - -func (step *Step7) isNil() bool { - return step == nil -} - -func (step *Step7) step() iam_model.Step { - return iam_model.Step7 -} - -func (step *Step7) init(setup *Setup) { - step.setup = setup -} - -func (step *Step7) execute(ctx context.Context) (*iam_model.IAM, error) { - iam, agg, err := step.add2FAToPolicy(ctx, step.DefaultSecondFactor) - if err != nil { - logging.Log("SETUP-GBD32").WithField("step", step.step()).WithError(err).Error("unable to finish setup (add default mfa to login policy)") - return nil, err - } - iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) - if err != nil { - logging.Log("SETUP-BHrth").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-k2fla").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (step *Step7) add2FAToPolicy(ctx context.Context, secondFactor iam_model.SecondFactorType) (*iam_es_model.IAM, *models.Aggregate, error) { - logging.Log("SETUP-Bew1a").Info("adding 2FA to loginPolicy") - return step.setup.IamEvents.PrepareAddSecondFactorToLoginPolicy(ctx, step.setup.iamID, secondFactor) -} diff --git a/internal/setup/step8.go b/internal/setup/step8.go deleted file mode 100644 index 30f70a41fb..0000000000 --- a/internal/setup/step8.go +++ /dev/null @@ -1,54 +0,0 @@ -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" -) - -type Step8 struct { - DefaultSecondFactor iam_model.SecondFactorType - - setup *Setup -} - -func (step *Step8) isNil() bool { - return step == nil -} - -func (step *Step8) step() iam_model.Step { - return iam_model.Step8 -} - -func (step *Step8) init(setup *Setup) { - step.setup = setup -} - -func (step *Step8) execute(ctx context.Context) (*iam_model.IAM, error) { - iam, agg, err := step.add2FAToPolicy(ctx, step.DefaultSecondFactor) - if err != nil { - logging.Log("SETUP-Gdbjq").WithField("step", step.step()).WithError(err).Error("unable to finish setup (add default mfa to login policy)") - return nil, err - } - iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) - if err != nil { - logging.Log("SETUP-Cnf21").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-NFq21").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (step *Step8) add2FAToPolicy(ctx context.Context, secondFactor iam_model.SecondFactorType) (*iam_es_model.IAM, *models.Aggregate, error) { - logging.Log("SETUP-Bfhb2").Info("adding 2FA to loginPolicy") - return step.setup.IamEvents.PrepareAddSecondFactorToLoginPolicy(ctx, step.setup.iamID, secondFactor) -} diff --git a/internal/setup/step9.go b/internal/setup/step9.go deleted file mode 100644 index 2733dbb51a..0000000000 --- a/internal/setup/step9.go +++ /dev/null @@ -1,74 +0,0 @@ -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" -) - -type Step9 struct { - Passwordless bool - - setup *Setup -} - -func (step *Step9) isNil() bool { - return step == nil -} - -func (step *Step9) step() iam_model.Step { - return iam_model.Step9 -} - -func (step *Step9) init(setup *Setup) { - step.setup = setup -} - -func (step *Step9) execute(ctx context.Context) (*iam_model.IAM, error) { - if !step.Passwordless { - return step.setup.IamEvents.IAMByID(ctx, step.setup.iamID) - } - iam, agg, err := step.setPasswordlessAllowedInPolicy(ctx) - if err != nil { - logging.Log("SETUP-Gdbjq").WithField("step", step.step()).WithError(err).Error("unable to finish setup (add default mfa to login policy)") - return nil, err - } - iam, agg2, err := step.addMFAToPolicy(ctx) - if err != nil { - logging.Log("SETUP-Gdbjq").WithField("step", step.step()).WithError(err).Error("unable to finish setup (add default mfa to login policy)") - return nil, err - } - agg.Events = append(agg.Events, agg2.Events...) - iam, agg, push, err := step.setup.IamEvents.PrepareSetupDone(ctx, iam, agg, step.step()) - if err != nil { - logging.Log("SETUP-Cnf21").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-NFq21").WithField("step", step.step()).WithError(err).Error("unable to finish setup") - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (step *Step9) setPasswordlessAllowedInPolicy(ctx context.Context) (*iam_es_model.IAM, *models.Aggregate, error) { - logging.Log("SETUP-DAd1h").Info("enabling passwordless in loginPolicy") - iam, err := step.setup.IamEvents.IAMByID(ctx, step.setup.iamID) - if err != nil { - return nil, nil, err - } - iam.DefaultLoginPolicy.AggregateID = step.setup.iamID - iam.DefaultLoginPolicy.PasswordlessType = iam_model.PasswordlessTypeAllowed - return step.setup.IamEvents.PrepareChangeLoginPolicy(ctx, iam.DefaultLoginPolicy) -} - -func (step *Step9) addMFAToPolicy(ctx context.Context) (*iam_es_model.IAM, *models.Aggregate, error) { - logging.Log("SETUP-DAd1h").Info("adding MFA to loginPolicy") - return step.setup.IamEvents.PrepareAddMultiFactorToLoginPolicy(ctx, step.setup.iamID, iam_model.MultiFactorTypeU2FWithPIN) -} diff --git a/internal/v2/command/command.go b/internal/v2/command/command.go index b73b24e2b8..d011502c5a 100644 --- a/internal/v2/command/command.go +++ b/internal/v2/command/command.go @@ -62,7 +62,7 @@ func (r *CommandSide) iamByID(ctx context.Context, id string) (_ *IAMWriteModel, ctx, span := tracing.NewSpan(ctx) defer func() { span.EndWithError(err) }() - writeModel := NewIAMriteModel(id) + writeModel := NewIAMWriteModel(id) err = r.eventstore.FilterToQueryReducer(ctx, writeModel) if err != nil { return nil, err diff --git a/internal/v2/command/iam.go b/internal/v2/command/iam.go new file mode 100644 index 0000000000..57f402b7f7 --- /dev/null +++ b/internal/v2/command/iam.go @@ -0,0 +1,16 @@ +package command + +import ( + "context" + + "github.com/caos/zitadel/internal/v2/domain" +) + +func (r *CommandSide) GetIAM(ctx context.Context, aggregateID string) (*domain.IAM, error) { + iamWriteModel := NewIAMWriteModel(aggregateID) + err := r.eventstore.FilterToQueryReducer(ctx, iamWriteModel) + if err != nil { + return nil, err + } + return writeModelToIAM(iamWriteModel), nil +} diff --git a/internal/v2/command/iam_converter.go b/internal/v2/command/iam_converter.go index 4b5dc289b4..155e2a1657 100644 --- a/internal/v2/command/iam_converter.go +++ b/internal/v2/command/iam_converter.go @@ -3,7 +3,6 @@ package command 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/domain" ) @@ -16,8 +15,8 @@ func writeModelToObjectRoot(writeModel eventstore.WriteModel) models.ObjectRoot } } -func writeModelToIAM(wm *IAMWriteModel) *model.IAM { - return &model.IAM{ +func writeModelToIAM(wm *IAMWriteModel) *domain.IAM { + return &domain.IAM{ ObjectRoot: writeModelToObjectRoot(wm.WriteModel), SetUpStarted: wm.SetUpStarted, SetUpDone: wm.SetUpDone, diff --git a/internal/v2/command/iam_model.go b/internal/v2/command/iam_model.go index 14bd79af6c..ade81654ce 100644 --- a/internal/v2/command/iam_model.go +++ b/internal/v2/command/iam_model.go @@ -16,7 +16,7 @@ type IAMWriteModel struct { ProjectID string } -func NewIAMriteModel(iamID string) *IAMWriteModel { +func NewIAMWriteModel(iamID string) *IAMWriteModel { return &IAMWriteModel{ WriteModel: eventstore.WriteModel{ AggregateID: iamID, diff --git a/internal/v2/command/iam_policy_label.go b/internal/v2/command/iam_policy_label.go index 50bb152105..2dd35c3b4f 100644 --- a/internal/v2/command/iam_policy_label.go +++ b/internal/v2/command/iam_policy_label.go @@ -11,16 +11,11 @@ import ( func (r *CommandSide) AddDefaultLabelPolicy(ctx context.Context, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) { policy.AggregateID = r.iamID addedPolicy := NewIAMLabelPolicyWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel) + err := r.addDefaultLabelPolicy(ctx, nil, addedPolicy, policy) 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 { @@ -30,6 +25,20 @@ func (r *CommandSide) AddDefaultLabelPolicy(ctx context.Context, policy *domain. return writeModelToLabelPolicy(addedPolicy), nil } +func (r *CommandSide) addDefaultLabelPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMLabelPolicyWriteModel, policy *domain.LabelPolicy) error { + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return err + } + if addedPolicy.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LabelPolicy.AlreadyExists") + } + + iamAgg.PushEvents(iam_repo.NewLabelPolicyAddedEvent(ctx, policy.PrimaryColor, policy.SecondaryColor)) + + return nil +} + func (r *CommandSide) ChangeDefaultLabelPolicy(ctx context.Context, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) { policy.AggregateID = r.iamID existingPolicy, err := r.defaultLabelPolicyWriteModelByID(ctx, policy.AggregateID) diff --git a/internal/v2/command/iam_policy_login.go b/internal/v2/command/iam_policy_login.go index 64f4c5f7ca..0d9e3fbbe8 100644 --- a/internal/v2/command/iam_policy_login.go +++ b/internal/v2/command/iam_policy_login.go @@ -2,6 +2,7 @@ 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" @@ -9,10 +10,22 @@ import ( iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" ) +func (r *CommandSide) GetDefaultLoginPolicy(ctx context.Context) (*domain.LoginPolicy, error) { + policyWriteModel := NewIAMLoginPolicyWriteModel(r.iamID) + err := r.eventstore.FilterToQueryReducer(ctx, policyWriteModel) + if err != nil { + return nil, err + } + policy := writeModelToLoginPolicy(policyWriteModel) + policy.Default = true + return policy, nil +} + func (r *CommandSide) AddDefaultLoginPolicy(ctx context.Context, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) { policy.AggregateID = r.iamID addedPolicy := NewIAMLoginPolicyWriteModel(policy.AggregateID) - iamAgg, err := r.addDefaultLoginPolicy(ctx, addedPolicy, policy) + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) + err := r.addDefaultLoginPolicy(ctx, nil, addedPolicy, policy) if err != nil { return nil, err } @@ -24,37 +37,28 @@ func (r *CommandSide) AddDefaultLoginPolicy(ctx context.Context, policy *domain. return writeModelToLoginPolicy(addedPolicy), nil } -func (r *CommandSide) addDefaultLoginPolicy(ctx context.Context, addedPolicy *IAMLoginPolicyWriteModel, policy *domain.LoginPolicy) (*iam_repo.Aggregate, error) { +func (r *CommandSide) addDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMLoginPolicyWriteModel, policy *domain.LoginPolicy) error { err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return nil, err + return err } if addedPolicy.IsActive { - return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.AlreadyExists") + return 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, policy.PasswordlessType)) - return iamAgg, nil + return nil } func (r *CommandSide) ChangeDefaultLoginPolicy(ctx context.Context, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) { policy.AggregateID = r.iamID - existingPolicy, err := r.defaultLoginPolicyWriteModelByID(ctx, policy.AggregateID) + existingPolicy := NewIAMLoginPolicyWriteModel(r.iamID) + iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel) + err := r.changeDefaultLoginPolicy(ctx, iamAgg, existingPolicy, policy) 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 @@ -63,6 +67,24 @@ func (r *CommandSide) ChangeDefaultLoginPolicy(ctx context.Context, policy *doma return writeModelToLoginPolicy(existingPolicy), nil } +func (r *CommandSide) changeDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, existingPolicy *IAMLoginPolicyWriteModel, policy *domain.LoginPolicy) error { + policy.AggregateID = r.iamID + err := r.defaultLoginPolicyWriteModelByID(ctx, existingPolicy) + if err != nil { + return err + } + if !existingPolicy.IsActive { + return 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 caos_errs.ThrowAlreadyExists(nil, "IAM-5M9vdd", "Errors.IAM.LoginPolicy.NotChanged") + } + iamAgg.PushEvents(changedEvent) + + return nil +} + func (r *CommandSide) AddIDPProviderToDefaultLoginPolicy(ctx context.Context, idpProvider *domain.IDPProvider) (*domain.IDPProvider, error) { idpProvider.AggregateID = r.iamID idpModel := NewIAMIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID) @@ -102,18 +124,12 @@ func (r *CommandSide) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Contex func (r *CommandSide) AddSecondFactorToDefaultLoginPolicy(ctx context.Context, secondFactor iam_model.SecondFactorType) (iam_model.SecondFactorType, error) { secondFactorModel := NewIAMSecondFactorWriteModel(r.iamID) - err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel) + iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) + err := r.addSecondFactorToDefaultLoginPolicy(ctx, nil, secondFactorModel, secondFactor) 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 } @@ -121,6 +137,21 @@ func (r *CommandSide) AddSecondFactorToDefaultLoginPolicy(ctx context.Context, s return iam_model.SecondFactorType(secondFactorModel.MFAType), nil } +func (r *CommandSide) addSecondFactorToDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, secondFactorModel *IAMSecondFactorWriteModel, secondFactor iam_model.SecondFactorType) error { + err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel) + if err != nil { + return err + } + + if secondFactorModel.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-2B0ps", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") + } + + iamAgg.PushEvents(iam_repo.NewLoginPolicySecondFactorAddedEvent(ctx, domain.SecondFactorType(secondFactor))) + + return nil +} + func (r *CommandSide) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Context, secondFactor iam_model.SecondFactorType) error { secondFactorModel := NewIAMSecondFactorWriteModel(r.iamID) err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel) @@ -138,15 +169,11 @@ func (r *CommandSide) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Conte func (r *CommandSide) AddMultiFactorToDefaultLoginPolicy(ctx context.Context, multiFactor iam_model.MultiFactorType) (iam_model.MultiFactorType, error) { multiFactorModel := NewIAMMultiFactorWriteModel(r.iamID) - err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel) + iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) + err := r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, multiFactor) 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 @@ -155,6 +182,20 @@ func (r *CommandSide) AddMultiFactorToDefaultLoginPolicy(ctx context.Context, mu return iam_model.MultiFactorType(multiFactorModel.MultiFactoryWriteModel.MFAType), nil } +func (r *CommandSide) addMultiFactorToDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, multiFactorModel *IAMMultiFactorWriteModel, multiFactor iam_model.MultiFactorType) error { + err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel) + if err != nil { + return err + } + if multiFactorModel.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-3M9od", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") + } + + iamAgg.PushEvents(iam_repo.NewLoginPolicyMultiFactorAddedEvent(ctx, domain.MultiFactorType(multiFactor))) + + return nil +} + func (r *CommandSide) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Context, multiFactor iam_model.MultiFactorType) error { multiFactorModel := NewIAMMultiFactorWriteModel(r.iamID) err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel) @@ -170,14 +211,13 @@ func (r *CommandSide) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Contex return r.eventstore.PushAggregate(ctx, multiFactorModel, iamAgg) } -func (r *CommandSide) defaultLoginPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMLoginPolicyWriteModel, err error) { +func (r *CommandSide) defaultLoginPolicyWriteModelByID(ctx context.Context, writeModel *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 err } - return writeModel, nil + return nil } diff --git a/internal/v2/command/iam_policy_org_iam.go b/internal/v2/command/iam_policy_org_iam.go index ed0894a26e..35012322c3 100644 --- a/internal/v2/command/iam_policy_org_iam.go +++ b/internal/v2/command/iam_policy_org_iam.go @@ -22,15 +22,11 @@ func (r *CommandSide) GetDefaultOrgIAMPolicy(ctx context.Context) (*domain.OrgIA func (r *CommandSide) AddDefaultOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { policy.AggregateID = r.iamID addedPolicy := NewIAMOrgIAMPolicyWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) + err := r.addDefaultOrgIAMPolicy(ctx, nil, addedPolicy, policy) 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 { @@ -40,6 +36,19 @@ func (r *CommandSide) AddDefaultOrgIAMPolicy(ctx context.Context, policy *domain return writeModelToOrgIAMPolicy(addedPolicy), nil } +func (r *CommandSide) addDefaultOrgIAMPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMOrgIAMPolicyWriteModel, policy *domain.OrgIAMPolicy) error { + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return err + } + if addedPolicy.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.OrgIAMPolicy.AlreadyExists") + } + iamAgg.PushEvents(iam_repo.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain)) + + return nil +} + func (r *CommandSide) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) { policy.AggregateID = r.iamID existingPolicy, err := r.defaultOrgIAMPolicyWriteModelByID(ctx, policy.AggregateID) diff --git a/internal/v2/command/iam_policy_password_age.go b/internal/v2/command/iam_policy_password_age.go index 80f07e0edd..cb2df774ff 100644 --- a/internal/v2/command/iam_policy_password_age.go +++ b/internal/v2/command/iam_policy_password_age.go @@ -11,16 +11,11 @@ import ( func (r *CommandSide) AddDefaultPasswordAgePolicy(ctx context.Context, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) { policy.AggregateID = r.iamID addedPolicy := NewIAMPasswordAgePolicyWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) + err := r.addDefaultPasswordAgePolicy(ctx, nil, addedPolicy, policy) 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 { @@ -30,6 +25,20 @@ func (r *CommandSide) AddDefaultPasswordAgePolicy(ctx context.Context, policy *d return writeModelToPasswordAgePolicy(addedPolicy), nil } +func (r *CommandSide) addDefaultPasswordAgePolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMPasswordAgePolicyWriteModel, policy *domain.PasswordAgePolicy) error { + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return err + } + if addedPolicy.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordAgePolicy.AlreadyExists") + } + + iamAgg.PushEvents(iam_repo.NewPasswordAgePolicyAddedEvent(ctx, policy.ExpireWarnDays, policy.MaxAgeDays)) + + return nil +} + func (r *CommandSide) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) { policy.AggregateID = r.iamID existingPolicy, err := r.defaultPasswordAgePolicyWriteModelByID(ctx, policy.AggregateID) diff --git a/internal/v2/command/iam_policy_password_complexity.go b/internal/v2/command/iam_policy_password_complexity.go index 450016175a..e72dac2667 100644 --- a/internal/v2/command/iam_policy_password_complexity.go +++ b/internal/v2/command/iam_policy_password_complexity.go @@ -22,7 +22,8 @@ func (r *CommandSide) GetDefaultPasswordComplexityPolicy(ctx context.Context) (* func (r *CommandSide) AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) { policy.AggregateID = r.iamID addedPolicy := NewIAMPasswordComplexityPolicyWriteModel(policy.AggregateID) - iamAgg, err := r.addDefaultPasswordComplexityPolicy(ctx, addedPolicy, policy) + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) + err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, addedPolicy, policy) if err != nil { return nil, err } @@ -35,23 +36,22 @@ func (r *CommandSide) AddDefaultPasswordComplexityPolicy(ctx context.Context, po return writeModelToPasswordComplexityPolicy(addedPolicy), nil } -func (r *CommandSide) addDefaultPasswordComplexityPolicy(ctx context.Context, addedPolicy *IAMPasswordComplexityPolicyWriteModel, policy *domain.PasswordComplexityPolicy) (*iam_repo.Aggregate, error) { +func (r *CommandSide) addDefaultPasswordComplexityPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMPasswordComplexityPolicyWriteModel, policy *domain.PasswordComplexityPolicy) error { if err := policy.IsValid(); err != nil { - return nil, err + return err } err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) if err != nil { - return nil, err + return err } if addedPolicy.IsActive { - return nil, caos_errs.ThrowAlreadyExists(nil, "IAM-Lk0dS", "Errors.IAM.PasswordComplexityPolicy.AlreadyExists") + return 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 + return nil } func (r *CommandSide) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) { diff --git a/internal/v2/command/iam_policy_password_lockout.go b/internal/v2/command/iam_policy_password_lockout.go index 2448e34c86..d19e87d551 100644 --- a/internal/v2/command/iam_policy_password_lockout.go +++ b/internal/v2/command/iam_policy_password_lockout.go @@ -11,16 +11,11 @@ import ( func (r *CommandSide) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) { policy.AggregateID = r.iamID addedPolicy := NewIAMPasswordLockoutPolicyWriteModel(policy.AggregateID) - err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel) + err := r.addDefaultPasswordLockoutPolicy(ctx, nil, addedPolicy, policy) 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 { @@ -30,6 +25,20 @@ func (r *CommandSide) AddDefaultPasswordLockoutPolicy(ctx context.Context, polic return writeModelToPasswordLockoutPolicy(addedPolicy), nil } +func (r *CommandSide) addDefaultPasswordLockoutPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, addedPolicy *IAMPasswordLockoutPolicyWriteModel, policy *domain.PasswordLockoutPolicy) error { + err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy) + if err != nil { + return err + } + if addedPolicy.IsActive { + return caos_errs.ThrowAlreadyExists(nil, "IAM-0olDf", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists") + } + + iamAgg.PushEvents(iam_repo.NewPasswordLockoutPolicyAddedEvent(ctx, policy.MaxAttempts, policy.ShowLockOutFailures)) + + return nil +} + func (r *CommandSide) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) { policy.AggregateID = r.iamID existingPolicy, err := r.defaultPasswordLockoutPolicyWriteModelByID(ctx, policy.AggregateID) diff --git a/internal/v2/command/setup.go b/internal/v2/command/setup.go index bf00dea788..625caef30c 100644 --- a/internal/v2/command/setup.go +++ b/internal/v2/command/setup.go @@ -3,13 +3,59 @@ package command import ( "context" + "github.com/caos/logging" + + "github.com/caos/zitadel/internal/api/authz" caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/eventstore/models" "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) { +type Step interface { + Step() domain.Step + execute(context.Context, *CommandSide) error +} + +const ( + SetupUser = "SETUP" +) + +func (r *CommandSide) ExecuteSetupSteps(ctx context.Context, steps []Step) error { + iam, err := r.GetIAM(ctx, r.iamID) + if err != nil && !caos_errs.IsNotFound(err) { + return err + } + if iam != nil && (iam.SetUpDone == domain.StepCount-1 || iam.SetUpStarted != iam.SetUpDone) { + logging.Log("COMMA-dgd2z").Info("all steps done") + return nil + } + + if iam == nil { + iam = &domain.IAM{ObjectRoot: models.ObjectRoot{AggregateID: r.iamID}} + } + + ctx = setSetUpContextData(ctx, r.iamID) + + for _, step := range steps { + iam, err = r.StartSetup(ctx, r.iamID, step.Step()) + if err != nil { + return err + } + + err = step.execute(ctx, r) + if err != nil { + return err + } + } + return nil +} + +func setSetUpContextData(ctx context.Context, orgID string) context.Context { + return authz.SetCtxData(ctx, authz.CtxData{UserID: SetupUser, OrgID: orgID}) +} + +func (r *CommandSide) StartSetup(ctx context.Context, iamID string, step domain.Step) (*domain.IAM, error) { iamWriteModel, err := r.iamByID(ctx, iamID) if err != nil && !caos_errs.IsNotFound(err) { return nil, err @@ -25,6 +71,27 @@ func (r *CommandSide) StartSetup(ctx context.Context, iamID string, step domain. return writeModelToIAM(iamWriteModel), nil } +func (r *CommandSide) setup(ctx context.Context, step Step, iamAggregateProvider func(*IAMWriteModel) (*iam_repo.Aggregate, error)) error { + iam, err := r.iamByID(ctx, r.iamID) + if err != nil && !caos_errs.IsNotFound(err) { + return err + } + if iam.SetUpStarted != step.Step() && iam.SetUpDone+1 != step.Step() { + return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Dge32", "wrong step") + } + iamAgg, err := iamAggregateProvider(iam) + if err != nil { + return err + } + iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, step.Step())) + + _, err = r.eventstore.PushAggregates(ctx, iamAgg) + if err != nil { + return caos_errs.ThrowPreconditionFailedf(nil, "EVENT-dbG31", "Setup %s failed", step.Step()) + } + return nil +} + //func (r *CommandSide) setupDone(ctx context.Context, iamAgg *iam_repo.Aggregate, event eventstore.EventPusher, aggregates ...eventstore.Aggregater) error { // aggregate := iamAgg.PushEvents(event) // diff --git a/internal/v2/command/setup_step1.go b/internal/v2/command/setup_step1.go index 67b740c5bb..26f71d2756 100644 --- a/internal/v2/command/setup_step1.go +++ b/internal/v2/command/setup_step1.go @@ -22,6 +22,14 @@ type Step1 struct { //pwComplexityPolicy *iam_model.PasswordComplexityPolicyView } +func (s *Step1) Step() domain.Step { + return domain.Step1 +} + +func (s *Step1) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep1(ctx, commandSide.iamID, s) +} + type LoginPolicy struct { AllowRegister bool AllowUsernamePassword bool @@ -63,14 +71,10 @@ type OIDCApp struct { 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 - } +func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 *Step1) error { + iamAgg := iam_repo.NewAggregate(r.iamID, "", 0) //create default login policy - iamAgg, err := r.addDefaultLoginPolicy(ctx, - NewIAMLoginPolicyWriteModel(iam.AggregateID), + err := r.addDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(iamAgg.ID()), &domain.LoginPolicy{ AllowUsernamePassword: step1.DefaultLoginPolicy.AllowUsernamePassword, AllowRegister: step1.DefaultLoginPolicy.AllowRegister, diff --git a/internal/v2/command/setup_step2.go b/internal/v2/command/setup_step2.go index 298a2076e5..aea175b6c9 100644 --- a/internal/v2/command/setup_step2.go +++ b/internal/v2/command/setup_step2.go @@ -3,7 +3,6 @@ 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" @@ -13,26 +12,28 @@ 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), &domain.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 +func (s *Step2) Step() domain.Step { + return domain.Step2 +} + +func (s *Step2) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep2(ctx, s) +} + +func (r *CommandSide) SetupStep2(ctx context.Context, step *Step2) error { + fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) + err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, NewIAMPasswordComplexityPolicyWriteModel(iam.AggregateID), &domain.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 nil, err + } + return iamAgg, err + } + return r.setup(ctx, step, fn) } diff --git a/internal/v2/command/setup_step3.go b/internal/v2/command/setup_step3.go new file mode 100644 index 0000000000..5707175af8 --- /dev/null +++ b/internal/v2/command/setup_step3.go @@ -0,0 +1,36 @@ +package command + +import ( + "context" + + 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 Step3 struct { + DefaultPasswordAgePolicy iam_model.PasswordAgePolicy +} + +func (s *Step3) Step() domain.Step { + return domain.Step3 +} + +func (s *Step3) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep3(ctx, s) +} + +func (r *CommandSide) SetupStep3(ctx context.Context, step *Step3) error { + fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) + err := r.addDefaultPasswordAgePolicy(ctx, iamAgg, NewIAMPasswordAgePolicyWriteModel(iam.AggregateID), &domain.PasswordAgePolicy{ + MaxAgeDays: step.DefaultPasswordAgePolicy.MaxAgeDays, + ExpireWarnDays: step.DefaultPasswordAgePolicy.ExpireWarnDays, + }) + if err != nil { + return nil, err + } + return iamAgg, nil + } + return r.setup(ctx, step, fn) +} diff --git a/internal/v2/command/setup_step4.go b/internal/v2/command/setup_step4.go new file mode 100644 index 0000000000..dba404cd87 --- /dev/null +++ b/internal/v2/command/setup_step4.go @@ -0,0 +1,36 @@ +package command + +import ( + "context" + + 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 Step4 struct { + DefaultPasswordLockoutPolicy iam_model.PasswordLockoutPolicy +} + +func (s *Step4) Step() domain.Step { + return domain.Step4 +} + +func (s *Step4) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep4(ctx, s) +} + +func (r *CommandSide) SetupStep4(ctx context.Context, step *Step4) error { + fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) + err := r.addDefaultPasswordLockoutPolicy(ctx, iamAgg, NewIAMPasswordLockoutPolicyWriteModel(iam.AggregateID), &domain.PasswordLockoutPolicy{ + MaxAttempts: step.DefaultPasswordLockoutPolicy.MaxAttempts, + ShowLockOutFailures: step.DefaultPasswordLockoutPolicy.ShowLockOutFailures, + }) + if err != nil { + return nil, err + } + return iamAgg, nil + } + return r.setup(ctx, step, fn) +} diff --git a/internal/v2/command/setup_step5.go b/internal/v2/command/setup_step5.go new file mode 100644 index 0000000000..0f647b8e67 --- /dev/null +++ b/internal/v2/command/setup_step5.go @@ -0,0 +1,35 @@ +package command + +import ( + "context" + + 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 Step5 struct { + DefaultOrgIAMPolicy iam_model.OrgIAMPolicy +} + +func (s *Step5) Step() domain.Step { + return domain.Step5 +} + +func (s *Step5) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep5(ctx, s) +} + +func (r *CommandSide) SetupStep5(ctx context.Context, step *Step5) error { + fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) + err := r.addDefaultOrgIAMPolicy(ctx, iamAgg, NewIAMOrgIAMPolicyWriteModel(iam.AggregateID), &domain.OrgIAMPolicy{ + UserLoginMustBeDomain: step.DefaultOrgIAMPolicy.UserLoginMustBeDomain, + }) + if err != nil { + return nil, err + } + return iamAgg, nil + } + return r.setup(ctx, step, fn) +} diff --git a/internal/v2/command/setup_step6.go b/internal/v2/command/setup_step6.go new file mode 100644 index 0000000000..282906a716 --- /dev/null +++ b/internal/v2/command/setup_step6.go @@ -0,0 +1,36 @@ +package command + +import ( + "context" + + 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 Step6 struct { + DefaultLabelPolicy iam_model.LabelPolicy +} + +func (s *Step6) Step() domain.Step { + return domain.Step6 +} + +func (s *Step6) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep6(ctx, s) +} + +func (r *CommandSide) SetupStep6(ctx context.Context, step *Step6) error { + fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel) + err := r.addDefaultLabelPolicy(ctx, iamAgg, NewIAMLabelPolicyWriteModel(iam.AggregateID), &domain.LabelPolicy{ + PrimaryColor: step.DefaultLabelPolicy.PrimaryColor, + SecondaryColor: step.DefaultLabelPolicy.SecondaryColor, + }) + if err != nil { + return nil, err + } + return iamAgg, nil + } + return r.setup(ctx, step, fn) +} diff --git a/internal/v2/command/setup_step7.go b/internal/v2/command/setup_step7.go new file mode 100644 index 0000000000..977c74efcc --- /dev/null +++ b/internal/v2/command/setup_step7.go @@ -0,0 +1,37 @@ +package command + +import ( + "context" + + 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 Step7 struct { + OTP bool +} + +func (s *Step7) Step() domain.Step { + return domain.Step7 +} + +func (s *Step7) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep7(ctx, s) +} + +func (r *CommandSide) SetupStep7(ctx context.Context, step *Step7) error { + fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + secondFactorModel := NewIAMSecondFactorWriteModel(iam.AggregateID) + iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) + if !step.OTP { + return iamAgg, nil + } + err := r.addSecondFactorToDefaultLoginPolicy(ctx, iamAgg, secondFactorModel, iam_model.SecondFactorTypeOTP) + if err != nil { + return nil, err + } + return iamAgg, nil + } + return r.setup(ctx, step, fn) +} diff --git a/internal/v2/command/setup_step8.go b/internal/v2/command/setup_step8.go new file mode 100644 index 0000000000..aa1fa4f99a --- /dev/null +++ b/internal/v2/command/setup_step8.go @@ -0,0 +1,37 @@ +package command + +import ( + "context" + + 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 Step8 struct { + U2F bool +} + +func (s *Step8) Step() domain.Step { + return domain.Step8 +} + +func (s *Step8) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep8(ctx, s) +} + +func (r *CommandSide) SetupStep8(ctx context.Context, step *Step8) error { + fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + secondFactorModel := NewIAMSecondFactorWriteModel(iam.AggregateID) + iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel) + if !step.U2F { + return iamAgg, nil + } + err := r.addSecondFactorToDefaultLoginPolicy(ctx, iamAgg, secondFactorModel, iam_model.SecondFactorTypeU2F) + if err != nil { + return nil, err + } + return iamAgg, nil + } + return r.setup(ctx, step, fn) +} diff --git a/internal/v2/command/setup_step9.go b/internal/v2/command/setup_step9.go new file mode 100644 index 0000000000..f8a445b4c6 --- /dev/null +++ b/internal/v2/command/setup_step9.go @@ -0,0 +1,50 @@ +package command + +import ( + "context" + + 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 Step9 struct { + Passwordless bool +} + +func (s *Step9) Step() domain.Step { + return domain.Step9 +} + +func (s *Step9) execute(ctx context.Context, commandSide *CommandSide) error { + return commandSide.SetupStep9(ctx, s) +} + +func (r *CommandSide) SetupStep9(ctx context.Context, step *Step9) error { + fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) { + multiFactorModel := NewIAMMultiFactorWriteModel(iam.AggregateID) + iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel) + if !step.Passwordless { + return iamAgg, nil + } + err := setPasswordlessAllowedInPolicy(ctx, r, iamAgg) + if err != nil { + return nil, err + } + err = r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, iam_model.MultiFactorTypeU2FWithPIN) + if err != nil { + return nil, err + } + return iamAgg, err + } + return r.setup(ctx, step, fn) +} + +func setPasswordlessAllowedInPolicy(ctx context.Context, c *CommandSide, iamAgg *iam_repo.Aggregate) error { + policy, err := c.GetDefaultLoginPolicy(ctx) + if err != nil { + return err + } + policy.PasswordlessType = domain.PasswordlessTypeAllowed + return c.changeDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(iamAgg.ID()), policy) +} diff --git a/internal/v2/domain/iam.go b/internal/v2/domain/iam.go new file mode 100644 index 0000000000..2f67273de7 --- /dev/null +++ b/internal/v2/domain/iam.go @@ -0,0 +1,22 @@ +package domain + +import ( + "github.com/caos/zitadel/internal/eventstore/models" +) + +type IAM struct { + models.ObjectRoot + + GlobalOrgID string + IAMProjectID string + SetUpDone Step + SetUpStarted Step + Members []*IAMMember + IDPs []*IDPConfig + DefaultLoginPolicy *LoginPolicy + DefaultLabelPolicy *LabelPolicy + DefaultOrgIAMPolicy *OrgIAMPolicy + DefaultPasswordComplexityPolicy *PasswordComplexityPolicy + DefaultPasswordAgePolicy *PasswordAgePolicy + DefaultPasswordLockoutPolicy *PasswordLockoutPolicy +} diff --git a/internal/v2/domain/step.go b/internal/v2/domain/step.go index 72aba2e86c..afd8300a8c 100644 --- a/internal/v2/domain/step.go +++ b/internal/v2/domain/step.go @@ -11,6 +11,7 @@ const ( Step6 Step7 Step8 + Step9 //StepCount marks the the length of possible steps (StepCount-1 == last possible step) StepCount ) diff --git a/internal/v2/repository/policy/login.go b/internal/v2/repository/policy/login.go index 21e3c35adb..c6321de0bc 100644 --- a/internal/v2/repository/policy/login.go +++ b/internal/v2/repository/policy/login.go @@ -18,11 +18,11 @@ const ( 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"` + AllowUserNamePassword bool `json:"allowUsernamePassword,omitempty"` + AllowRegister bool `json:"allowRegister,omitempty"` + AllowExternalIDP bool `json:"allowExternalIdp,omitempty"` + ForceMFA bool `json:"forceMFA,omitempty"` + PasswordlessType domain.PasswordlessType `json:"passwordlessType,omitempty"` } func (e *LoginPolicyAddedEvent) Data() interface{} { @@ -64,10 +64,10 @@ 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"` + AllowRegister bool `json:"allowRegister,omitempty"` + AllowExternalIDP bool `json:"allowExternalIdp,omitempty"` + ForceMFA bool `json:"forceMFA,omitempty"` + PasswordlessType domain.PasswordlessType `json:"passwordlessType,omitempty"` } type LoginPolicyEventData struct { diff --git a/internal/v2/repository/policy/policy_login_factors.go b/internal/v2/repository/policy/policy_login_factors.go index f1e5bd1106..0c85207f56 100644 --- a/internal/v2/repository/policy/policy_login_factors.go +++ b/internal/v2/repository/policy/policy_login_factors.go @@ -21,7 +21,7 @@ const ( type SecondFactorAddedEvent struct { eventstore.BaseEvent `json:"-"` - MFAType domain.SecondFactorType `json:"mfaType"` + MFAType domain.SecondFactorType `json:"mfaType,omitempty"` } func NewSecondFactorAddedEvent( diff --git a/internal/v2/repository/policy/policy_login_identity_provider.go b/internal/v2/repository/policy/policy_login_identity_provider.go index ecda6127ea..70c3197e54 100644 --- a/internal/v2/repository/policy/policy_login_identity_provider.go +++ b/internal/v2/repository/policy/policy_login_identity_provider.go @@ -17,8 +17,8 @@ const ( type IdentityProviderAddedEvent struct { eventstore.BaseEvent - IDPConfigID string `json:"idpConfigId"` - IDPProviderType domain.IdentityProviderType `json:"idpProviderType"` + IDPConfigID string `json:"idpConfigId,omitempty"` + IDPProviderType domain.IdentityProviderType `json:"idpProviderType,omitempty"` } func (e *IdentityProviderAddedEvent) Data() interface{} { diff --git a/internal/v2/repository/policy/policy_org_iam.go b/internal/v2/repository/policy/policy_org_iam.go index 2718c7e47d..2e5a3e5d22 100644 --- a/internal/v2/repository/policy/policy_org_iam.go +++ b/internal/v2/repository/policy/policy_org_iam.go @@ -15,7 +15,7 @@ const ( type OrgIAMPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` - UserLoginMustBeDomain bool `json:"userLoginMustBeDomain"` + UserLoginMustBeDomain bool `json:"userLoginMustBeDomain,omitempty"` } func (e *OrgIAMPolicyAddedEvent) Data() interface{} { @@ -49,7 +49,7 @@ func OrgIAMPolicyAddedEventMapper(event *repository.Event) (eventstore.EventRead type OrgIAMPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` - UserLoginMustBeDomain bool `json:"userLoginMustBeDomain"` + UserLoginMustBeDomain bool `json:"userLoginMustBeDomain,omitempty"` } func (e *OrgIAMPolicyChangedEvent) Data() interface{} { diff --git a/internal/v2/repository/policy/policy_password_age.go b/internal/v2/repository/policy/policy_password_age.go index da07913a7c..ef8353dd55 100644 --- a/internal/v2/repository/policy/policy_password_age.go +++ b/internal/v2/repository/policy/policy_password_age.go @@ -16,8 +16,8 @@ const ( type PasswordAgePolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` - ExpireWarnDays uint64 `json:"expireWarnDays"` - MaxAgeDays uint64 `json:"maxAgeDays"` + ExpireWarnDays uint64 `json:"expireWarnDays,omitempty"` + MaxAgeDays uint64 `json:"maxAgeDays,omitempty"` } func (e *PasswordAgePolicyAddedEvent) Data() interface{} { diff --git a/internal/v2/repository/policy/policy_password_complexity.go b/internal/v2/repository/policy/policy_password_complexity.go index 96a161f59f..4d5a50d112 100644 --- a/internal/v2/repository/policy/policy_password_complexity.go +++ b/internal/v2/repository/policy/policy_password_complexity.go @@ -17,10 +17,10 @@ type PasswordComplexityPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` MinLength uint64 `json:"minLength,omitempty"` - HasLowercase bool `json:"hasLowercase"` - HasUpperCase bool `json:"hasUppercase"` - HasNumber bool `json:"hasNumber"` - HasSymbol bool `json:"hasSymbol"` + HasLowercase bool `json:"hasLowercase,omitempty"` + HasUpperCase bool `json:"hasUppercase,omitempty"` + HasNumber bool `json:"hasNumber,omitempty"` + HasSymbol bool `json:"hasSymbol,omitempty"` } func (e *PasswordComplexityPolicyAddedEvent) Data() interface{} { @@ -61,11 +61,11 @@ func PasswordComplexityPolicyAddedEventMapper(event *repository.Event) (eventsto type PasswordComplexityPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` - MinLength uint64 `json:"minLength"` - HasLowercase bool `json:"hasLowercase"` - HasUpperCase bool `json:"hasUppercase"` - HasNumber bool `json:"hasNumber"` - HasSymbol bool `json:"hasSymbol"` + MinLength uint64 `json:"minLength,omitempty"` + HasLowercase bool `json:"hasLowercase,omitempty"` + HasUpperCase bool `json:"hasUppercase,omitempty"` + HasNumber bool `json:"hasNumber,omitempty"` + HasSymbol bool `json:"hasSymbol,omitempty"` } func (e *PasswordComplexityPolicyChangedEvent) Data() interface{} { diff --git a/internal/v2/repository/policy/policy_password_lockout.go b/internal/v2/repository/policy/policy_password_lockout.go index 00d80194cf..024c6adff4 100644 --- a/internal/v2/repository/policy/policy_password_lockout.go +++ b/internal/v2/repository/policy/policy_password_lockout.go @@ -17,7 +17,7 @@ type PasswordLockoutPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` MaxAttempts uint64 `json:"maxAttempts,omitempty"` - ShowLockOutFailures bool `json:"showLockOutFailures"` + ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"` } func (e *PasswordLockoutPolicyAddedEvent) Data() interface{} {