diff --git a/internal/admin/repository/eventsourcing/eventstore/iam.go b/internal/admin/repository/eventsourcing/eventstore/iam.go index 39551ad364..2be59c575d 100644 --- a/internal/admin/repository/eventsourcing/eventstore/iam.go +++ b/internal/admin/repository/eventsourcing/eventstore/iam.go @@ -10,8 +10,6 @@ import ( "github.com/caos/logging" admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view" "github.com/caos/zitadel/internal/config/systemdefaults" - es_models "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 "github.com/caos/zitadel/internal/iam/repository/eventsourcing" iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model" @@ -70,48 +68,6 @@ func (repo *IAMRepository) GetIAMMemberRoles() []string { return roles } -func (repo *IAMRepository) RemoveIDPConfig(ctx context.Context, idpConfigID string) error { - - aggregates := make([]*es_models.Aggregate, 0) - idp := iam_model.NewIDPConfig(repo.SystemDefaults.IamID, idpConfigID) - _, agg, err := repo.IAMEventstore.PrepareRemoveIDPConfig(ctx, idp) - if err != nil { - return err - } - aggregates = append(aggregates, agg) - - providers, err := repo.View.IDPProvidersByIdpConfigID(idpConfigID) - if err != nil { - return err - } - for _, p := range providers { - if p.AggregateID == repo.SystemDefaults.IamID { - continue - } - provider := &iam_model.IDPProvider{ObjectRoot: es_models.ObjectRoot{AggregateID: p.AggregateID}, IDPConfigID: p.IDPConfigID} - providerAgg := new(es_models.Aggregate) - _, providerAgg, err = repo.OrgEvents.PrepareRemoveIDPProviderFromLoginPolicy(ctx, provider, true) - if err != nil { - return err - } - aggregates = append(aggregates, providerAgg) - } - externalIDPs, err := repo.View.ExternalIDPsByIDPConfigID(idpConfigID) - if err != nil { - return err - } - for _, externalIDP := range externalIDPs { - idpRemove := &usr_model.ExternalIDP{ObjectRoot: es_models.ObjectRoot{AggregateID: externalIDP.UserID}, IDPConfigID: externalIDP.IDPConfigID, UserID: externalIDP.ExternalUserID} - idpAgg := make([]*es_models.Aggregate, 0) - _, idpAgg, err = repo.UserEvents.PrepareRemoveExternalIDP(ctx, idpRemove, true) - if err != nil { - return err - } - aggregates = append(aggregates, idpAgg...) - } - return es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, nil, aggregates...) -} - func (repo *IAMRepository) IDPProvidersByIDPConfigID(ctx context.Context, idpConfigID string) ([]*iam_model.IDPProviderView, error) { providers, err := repo.View.IDPProvidersByIdpConfigID(idpConfigID) if err != nil { @@ -213,31 +169,6 @@ func (repo *IAMRepository) SearchDefaultIDPProviders(ctx context.Context, reques return result, nil } -func (repo *IAMRepository) RemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) error { - aggregates := make([]*es_models.Aggregate, 0) - provider.AggregateID = repo.SystemDefaults.IamID - _, removeAgg, err := repo.IAMEventstore.PrepareRemoveIDPProviderFromLoginPolicy(ctx, provider) - if err != nil { - return err - } - aggregates = append(aggregates, removeAgg) - - externalIDPs, err := repo.View.ExternalIDPsByIDPConfigID(provider.IDPConfigID) - if err != nil { - return err - } - for _, externalIDP := range externalIDPs { - idpRemove := &usr_model.ExternalIDP{ObjectRoot: es_models.ObjectRoot{AggregateID: externalIDP.UserID}, IDPConfigID: externalIDP.IDPConfigID, UserID: externalIDP.ExternalUserID} - idpAgg := make([]*es_models.Aggregate, 0) - _, idpAgg, err = repo.UserEvents.PrepareRemoveExternalIDP(ctx, idpRemove, true) - if err != nil { - return err - } - aggregates = append(aggregates, idpAgg...) - } - return es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, nil, aggregates...) -} - func (repo *IAMRepository) SearchDefaultSecondFactors(ctx context.Context) (*iam_model.SecondFactorsSearchResponse, error) { policy, err := repo.GetDefaultLoginPolicy(ctx) if err != nil { @@ -360,16 +291,6 @@ func (repo *IAMRepository) GetOrgIAMPolicy(ctx context.Context) (*iam_model.OrgI return iam_es_model.OrgIAMViewToModel(policy), nil } -func (repo *IAMRepository) AddDefaultOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - policy.AggregateID = repo.SystemDefaults.IamID - 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 - return repo.IAMEventstore.ChangeOrgIAMPolicy(ctx, policy) -} - func (repo *IAMRepository) GetDefaultLabelPolicy(ctx context.Context) (*iam_model.LabelPolicyView, error) { policy, err := repo.View.LabelPolicyByAggregateID(repo.SystemDefaults.IamID) if err != nil { @@ -378,16 +299,6 @@ func (repo *IAMRepository) GetDefaultLabelPolicy(ctx context.Context) (*iam_mode return iam_es_model.LabelPolicyViewToModel(policy), err } -func (repo *IAMRepository) AddDefaultLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - policy.AggregateID = repo.SystemDefaults.IamID - 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 - return repo.IAMEventstore.ChangeLabelPolicy(ctx, policy) -} - func (repo *IAMRepository) GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) { template, err := repo.View.MailTemplateByAggregateID(repo.SystemDefaults.IamID) if err != nil { @@ -433,13 +344,3 @@ func (repo *IAMRepository) GetDefaultMailText(ctx context.Context, textType stri text.Default = true return iam_es_model.MailTextViewToModel(text), err } - -func (repo *IAMRepository) AddDefaultMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { - text.AggregateID = repo.SystemDefaults.IamID - return repo.IAMEventstore.AddMailText(ctx, text) -} - -func (repo *IAMRepository) ChangeDefaultMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { - text.AggregateID = repo.SystemDefaults.IamID - return repo.IAMEventstore.ChangeMailText(ctx, text) -} diff --git a/internal/admin/repository/eventsourcing/eventstore/org.go b/internal/admin/repository/eventsourcing/eventstore/org.go index 78400eae29..8cc6fffdbb 100644 --- a/internal/admin/repository/eventsourcing/eventstore/org.go +++ b/internal/admin/repository/eventsourcing/eventstore/org.go @@ -5,16 +5,12 @@ import ( "github.com/caos/zitadel/internal/errors" iam_model "github.com/caos/zitadel/internal/iam/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view/model" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/logging" - admin_model "github.com/caos/zitadel/internal/admin/model" admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/eventstore" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/eventstore/sdk" iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model" org_model "github.com/caos/zitadel/internal/org/model" org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing" @@ -22,10 +18,6 @@ import ( usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing" ) -const ( - orgOwnerRole = "ORG_OWNER" -) - type OrgRepo struct { Eventstore eventstore.Eventstore OrgEventstore *org_es.OrgEventstore @@ -37,50 +29,6 @@ type OrgRepo struct { SystemDefaults systemdefaults.SystemDefaults } -func (repo *OrgRepo) SetUpOrg(ctx context.Context, setUp *admin_model.SetupOrg) (*admin_model.SetupOrg, error) { - pwPolicy, err := repo.View.PasswordComplexityPolicyByAggregateID(repo.SystemDefaults.IamID) - if err != nil { - return nil, err - } - pwPolicyView := iam_view.PasswordComplexityViewToModel(pwPolicy) - orgPolicy, err := repo.GetDefaultOrgIAMPolicy(ctx) - if err != nil { - return nil, err - } - users := func(ctx context.Context, domain string) ([]*es_models.Aggregate, error) { - userIDs, err := repo.View.UserIDsByDomain(domain) - if err != nil { - return nil, err - } - return repo.UserEventstore.PrepareDomainClaimed(ctx, userIDs) - } - org, aggregates, err := repo.OrgEventstore.PrepareCreateOrg(ctx, setUp.Org, users) - if err != nil { - return nil, err - } - user, userAggregates, err := repo.UserEventstore.PrepareCreateUser(ctx, setUp.User, pwPolicyView, orgPolicy, org.AggregateID) - if err != nil { - return nil, err - } - - aggregates = append(aggregates, userAggregates...) - setupModel := &Setup{Org: org, User: user} - - member := org_model.NewOrgMemberWithRoles(org.AggregateID, user.AggregateID, orgOwnerRole) - _, memberAggregate, err := repo.OrgEventstore.PrepareAddOrgMember(ctx, member, org.AggregateID) - if err != nil { - return nil, err - } - aggregates = append(aggregates, memberAggregate) - - err = sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, setupModel.AppendEvents, aggregates...) - if err != nil { - return nil, err - } - - return SetupToModel(setupModel), nil -} - func (repo *OrgRepo) OrgByID(ctx context.Context, id string) (*org_model.Org, error) { return repo.OrgEventstore.OrgByID(ctx, org_model.NewOrg(id)) } @@ -129,15 +77,3 @@ func (repo *OrgRepo) GetDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.Org policy.Default = true return iam_es_model.OrgIAMViewToModel(policy), err } - -func (repo *OrgRepo) CreateOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - return repo.OrgEventstore.AddOrgIAMPolicy(ctx, policy) -} - -func (repo *OrgRepo) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - return repo.OrgEventstore.ChangeOrgIAMPolicy(ctx, policy) -} - -func (repo *OrgRepo) RemoveOrgIAMPolicy(ctx context.Context, id string) error { - return repo.OrgEventstore.RemoveOrgIAMPolicy(ctx, id) -} diff --git a/internal/admin/repository/iam.go b/internal/admin/repository/iam.go index dc1205e435..576b0420a7 100644 --- a/internal/admin/repository/iam.go +++ b/internal/admin/repository/iam.go @@ -29,8 +29,6 @@ type IAMRepository interface { GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) GetDefaultMailText(ctx context.Context, textType string, language string) (*iam_model.MailTextView, error) - AddDefaultMailText(ctx context.Context, mailText *iam_model.MailText) (*iam_model.MailText, error) - ChangeDefaultMailText(ctx context.Context, policy *iam_model.MailText) (*iam_model.MailText, error) GetDefaultPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) diff --git a/internal/auth/repository/eventsourcing/eventstore/user.go b/internal/auth/repository/eventsourcing/eventstore/user.go index dbb0bf903d..11a54cee90 100644 --- a/internal/auth/repository/eventsourcing/eventstore/user.go +++ b/internal/auth/repository/eventsourcing/eventstore/user.go @@ -4,7 +4,6 @@ import ( "context" "github.com/caos/zitadel/internal/config/systemdefaults" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model" key_model "github.com/caos/zitadel/internal/key/model" "github.com/caos/logging" @@ -13,15 +12,11 @@ import ( "github.com/caos/zitadel/internal/auth/repository/eventsourcing/view" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/eventstore/sdk" key_view_model "github.com/caos/zitadel/internal/key/repository/view/model" - org_model "github.com/caos/zitadel/internal/org/model" org_event "github.com/caos/zitadel/internal/org/repository/eventsourcing" "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/caos/zitadel/internal/user/model" user_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" - usr_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model" ) @@ -38,47 +33,6 @@ func (repo *UserRepo) Health(ctx context.Context) error { return repo.UserEvents.Health(ctx) } -func (repo *UserRepo) registerUser(ctx context.Context, registerUser *model.User, externalIDP *model.ExternalIDP, orgMember *org_model.OrgMember, resourceOwner string) (*model.User, error) { - policyResourceOwner := authz.GetCtxData(ctx).OrgID - if resourceOwner != "" { - policyResourceOwner = resourceOwner - } - pwPolicy, err := repo.View.PasswordComplexityPolicyByAggregateID(policyResourceOwner) - if errors.IsNotFound(err) { - pwPolicy, err = repo.View.PasswordComplexityPolicyByAggregateID(repo.SystemDefaults.IamID) - } - if err != nil { - return nil, err - } - pwPolicyView := iam_es_model.PasswordComplexityViewToModel(pwPolicy) - orgPolicy, err := repo.View.OrgIAMPolicyByAggregateID(policyResourceOwner) - if errors.IsNotFound(err) { - orgPolicy, err = repo.View.OrgIAMPolicyByAggregateID(repo.SystemDefaults.IamID) - } - if err != nil { - return nil, err - } - orgPolicyView := iam_es_model.OrgIAMViewToModel(orgPolicy) - user, aggregates, err := repo.UserEvents.PrepareRegisterUser(ctx, registerUser, externalIDP, pwPolicyView, orgPolicyView, resourceOwner) - if err != nil { - return nil, err - } - if orgMember != nil { - orgMember.UserID = user.AggregateID - _, memberAggregate, err := repo.OrgEvents.PrepareAddOrgMember(ctx, orgMember, policyResourceOwner) - if err != nil { - return nil, err - } - aggregates = append(aggregates, memberAggregate) - } - - err = sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, user.AppendEvents, aggregates...) - if err != nil { - return nil, err - } - return usr_model.UserToModel(user), nil -} - func (repo *UserRepo) MyUser(ctx context.Context) (*model.UserView, error) { return repo.UserByID(ctx, authz.GetCtxData(ctx).UserID) } @@ -247,13 +201,6 @@ func (repo *UserRepo) MyUserChanges(ctx context.Context, lastSequence uint64, li return changes, nil } -func checkIDs(ctx context.Context, obj es_models.ObjectRoot) error { - if obj.AggregateID != authz.GetCtxData(ctx).UserID { - return errors.ThrowPermissionDenied(nil, "EVENT-kFi9w", "object does not belong to user") - } - return nil -} - func (repo *UserRepo) MachineKeyByID(ctx context.Context, keyID string) (*key_model.AuthNKeyView, error) { key, err := repo.View.AuthNKeyByID(keyID) if err != nil { diff --git a/internal/iam/repository/eventsourcing/eventstore.go b/internal/iam/repository/eventsourcing/eventstore.go index 4184336421..40e4d4b604 100644 --- a/internal/iam/repository/eventsourcing/eventstore.go +++ b/internal/iam/repository/eventsourcing/eventstore.go @@ -5,23 +5,18 @@ import ( "github.com/caos/zitadel/internal/cache/config" sd "github.com/caos/zitadel/internal/config/systemdefaults" - "github.com/caos/zitadel/internal/crypto" caos_errs "github.com/caos/zitadel/internal/errors" es_int "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" es_models "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" "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/id" "github.com/caos/zitadel/internal/telemetry/tracing" ) type IAMEventstore struct { es_int.Eventstore - iamCache *IAMCache - idGenerator id.Generator - secretCrypto crypto.Crypto + iamCache *IAMCache } type IAMConfig struct { @@ -35,15 +30,9 @@ func StartIAM(conf IAMConfig, systemDefaults sd.SystemDefaults) (*IAMEventstore, return nil, err } - aesCrypto, err := crypto.NewAESCrypto(systemDefaults.IDPConfigVerificationKey) - if err != nil { - return nil, err - } return &IAMEventstore{ - Eventstore: conf.Eventstore, - iamCache: iamCache, - idGenerator: id.SonyFlakeGenerator, - secretCrypto: aesCrypto, + Eventstore: conf.Eventstore, + iamCache: iamCache, }, nil } @@ -73,162 +62,6 @@ 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) 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) - agg, err := IAMSetupDoneEvent(ctx, aggregate, iam) - if err != nil { - return nil, nil, nil, err - } - return iam, agg, es.PushAggregates, nil -} - -func (es *IAMEventstore) SetGlobalOrg(ctx context.Context, iamID, globalOrg string) (*iam_model.IAM, error) { - iam, err := es.IAMByID(ctx, iamID) - if err != nil { - return nil, err - } - repoIam := model.IAMFromModel(iam) - createAggregate := IAMSetGlobalOrgAggregate(es.AggregateCreator(), repoIam, globalOrg) - 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) SetIAMProject(ctx context.Context, iamID, iamProjectID string) (*iam_model.IAM, error) { - iam, err := es.IAMByID(ctx, iamID) - if err != nil { - return nil, err - } - repoIam := model.IAMFromModel(iam) - createAggregate := IAMSetIamProjectAggregate(es.AggregateCreator(), repoIam, iamProjectID) - 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) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { - if !member.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-89osr", "Errors.IAM.MemberInvalid") - } - existing, err := es.IAMByID(ctx, member.AggregateID) - if err != nil { - return nil, err - } - if _, m := existing.GetMember(member.UserID); m != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-idke6", "Errors.IAM.MemberAlreadyExisting") - } - repoIam := model.IAMFromModel(existing) - repoMember := model.IAMMemberFromModel(member) - - addAggregate := IAMMemberAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - - if _, m := model.GetIAMMember(repoIam.Members, member.UserID); m != nil { - return model.IAMMemberToModel(m), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-s90pw", "Errors.Internal") -} - -func (es *IAMEventstore) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { - if !member.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-s9ipe", "Errors.IAM.MemberInvalid") - } - existing, err := es.IAMByID(ctx, member.AggregateID) - if err != nil { - return nil, err - } - if _, m := existing.GetMember(member.UserID); m == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-s7ucs", "Errors.IAM.MemberNotExisting") - } - repoIam := model.IAMFromModel(existing) - repoMember := model.IAMMemberFromModel(member) - - projectAggregate := IAMMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, projectAggregate) - es.iamCache.cacheIAM(repoIam) - - if _, m := model.GetIAMMember(repoIam.Members, member.UserID); m != nil { - return model.IAMMemberToModel(m), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-29cws", "Errors.Internal") -} - -func (es *IAMEventstore) RemoveIAMMember(ctx context.Context, member *iam_model.IAMMember) error { - if member.UserID == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-0pors", "Errors.IAM.MemberInvalid") - } - existing, err := es.IAMByID(ctx, member.AggregateID) - if err != nil { - return err - } - if _, m := existing.GetMember(member.UserID); m == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-29skr", "Errors.IAM.MemberNotExisting") - } - repoIAM := model.IAMFromModel(existing) - repoMember := model.IAMMemberFromModel(member) - - projectAggregate := IAMMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoIAM, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoIAM.AppendEvents, projectAggregate) - es.iamCache.cacheIAM(repoIAM) - return err -} - func (es *IAMEventstore) GetIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) { existing, err := es.IAMByID(ctx, aggregateID) if err != nil { @@ -240,667 +73,6 @@ func (es *IAMEventstore) GetIDPConfig(ctx context.Context, aggregateID, idpConfi return nil, caos_errs.ThrowNotFound(nil, "EVENT-Scj8s", "Errors.IAM.IdpNotExisting") } -func (es *IAMEventstore) AddIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { - if idp == nil || !idp.IsValid(true) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Ms89d", "Errors.IAM.IdpInvalid") - } - existing, err := es.IAMByID(ctx, idp.AggregateID) - if err != nil { - return nil, err - } - id, err := es.idGenerator.Next() - if err != nil { - return nil, err - } - idp.IDPConfigID = id - - if idp.OIDCConfig != nil { - idp.OIDCConfig.IDPConfigID = id - err = idp.OIDCConfig.CryptSecret(es.secretCrypto) - if err != nil { - return nil, err - } - } - repoIam := model.IAMFromModel(existing) - repoIdp := model.IDPConfigFromModel(idp) - - addAggregate := IDPConfigAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoIdp) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - if _, idpConfig := model.GetIDPConfig(repoIam.IDPs, idp.IDPConfigID); idpConfig != nil { - return model.IDPConfigToModel(idpConfig), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-Scj8s", "Errors.Internal") -} - -func (es *IAMEventstore) ChangeIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { - if idp == nil || !idp.IsValid(false) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Cms8o", "Errors.IAM.IdpInvalid") - } - existing, err := es.IAMByID(ctx, idp.AggregateID) - if err != nil { - return nil, err - } - if _, existingIDP := existing.GetIDP(idp.IDPConfigID); existingIDP == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Cmlos", "Errors.IAM.IdpNotExisting") - } - repoIam := model.IAMFromModel(existing) - repoIdp := model.IDPConfigFromModel(idp) - - iamAggregate := IDPConfigChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoIdp) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, iamAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - if _, idpConfig := model.GetIDPConfig(repoIam.IDPs, idp.IDPConfigID); idpConfig != nil { - return model.IDPConfigToModel(idpConfig), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-Xmlo0", "Errors.Internal") -} - -func (es *IAMEventstore) PrepareRemoveIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*model.IAM, *models.Aggregate, error) { - if idp == nil || idp.IDPConfigID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Wz7sD", "Errors.IAM.IDMissing") - } - existing, err := es.IAMByID(ctx, idp.AggregateID) - if err != nil { - return nil, nil, err - } - if _, existingIDP := existing.GetIDP(idp.IDPConfigID); existingIDP == nil { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Smiu8", "Errors.IAM.IdpNotExisting") - } - repoIam := model.IAMFromModel(existing) - repoIdp := model.IDPConfigFromModel(idp) - provider := new(model.IDPProvider) - if repoIam.DefaultLoginPolicy != nil { - _, provider = model.GetIDPProvider(repoIam.DefaultLoginPolicy.IDPProviders, idp.IDPConfigID) - } - agg, err := IDPConfigRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoIam, repoIdp, provider) - if err != nil { - return nil, nil, err - } - return repoIam, agg, nil -} - -func (es *IAMEventstore) RemoveIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) error { - repoIam, agg, err := es.PrepareRemoveIDPConfig(ctx, idp) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, agg) - if err != nil { - return err - } - es.iamCache.cacheIAM(repoIam) - return nil -} - -func (es *IAMEventstore) DeactivateIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) { - if idpID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Fbs8o", "Errors.IAM.IDMissing") - } - existing, err := es.IAMByID(ctx, iamID) - if err != nil { - return nil, err - } - idp := &iam_model.IDPConfig{IDPConfigID: idpID} - if _, existingIDP := existing.GetIDP(idp.IDPConfigID); existingIDP == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Mci32", "Errors.IAM.IdpNotExisting") - } - repoIam := model.IAMFromModel(existing) - repoIdp := model.IDPConfigFromModel(idp) - - iamAggregate := IDPConfigDeactivatedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoIdp) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, iamAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - if _, idpConfig := model.GetIDPConfig(repoIam.IDPs, idp.IDPConfigID); idpConfig != nil { - return model.IDPConfigToModel(idpConfig), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-Xnc8d", "Errors.Internal") -} - -func (es *IAMEventstore) ReactivateIDPConfig(ctx context.Context, iamID, idpID string) (*iam_model.IDPConfig, error) { - if idpID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Wkjsf", "Errors.IAM.IDMissing") - } - iam, err := es.IAMByID(ctx, iamID) - if err != nil { - return nil, err - } - idp := &iam_model.IDPConfig{IDPConfigID: idpID} - if _, existingIDP := iam.GetIDP(idp.IDPConfigID); existingIDP == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Sjc78", "Errors.IAM.IdpNotExisting") - } - repoIam := model.IAMFromModel(iam) - repoIdp := model.IDPConfigFromModel(idp) - - iamAggregate := IDPConfigReactivatedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoIdp) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, iamAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - if _, idpConfig := model.GetIDPConfig(repoIam.IDPs, idp.IDPConfigID); idpConfig != nil { - return model.IDPConfigToModel(idpConfig), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-Snd4f", "Errors.Internal") -} - -func (es *IAMEventstore) ChangeIDPOIDCConfig(ctx context.Context, config *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) { - if config == nil || !config.IsValid(false) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-*5ki8", "Errors.IAM.OIDCConfigInvalid") - } - iam, err := es.IAMByID(ctx, config.AggregateID) - if err != nil { - return nil, err - } - var idp *iam_model.IDPConfig - if _, idp = iam.GetIDP(config.IDPConfigID); idp == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-pso0s", "Errors.IAM.IdpNoExisting") - } - if idp.Type != iam_model.IDPConfigTypeOIDC { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Fms8w", "Errors.IAM.IdpIsNotOIDC") - } - if config.ClientSecretString != "" { - err = config.CryptSecret(es.secretCrypto) - if err != nil { - return nil, err - } - } else { - config.ClientSecret = nil - } - repoIam := model.IAMFromModel(iam) - repoConfig := model.OIDCIDPConfigFromModel(config) - - iamAggregate := OIDCIDPConfigChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoConfig) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, iamAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - if _, idpConfig := model.GetIDPConfig(repoIam.IDPs, idp.IDPConfigID); idpConfig != nil { - return model.OIDCIDPConfigToModel(idpConfig.OIDCIDPConfig), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-Sldk8", "Errors.Internal") -} - -func (es *IAMEventstore) PrepareAddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*model.IAM, *models.Aggregate, error) { - if policy == nil || policy.AggregateID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-VwlDv", "Errors.IAM.LabelPolicy.Empty") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - labelPolicy := model.LabelPolicyFromModel(policy) - - addAggregate := LabelPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, labelPolicy) - aggregate, err := addAggregate(ctx) - if err != nil { - return nil, nil, err - } - return repoIam, aggregate, nil -} - -func (es *IAMEventstore) AddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - if policy == nil || !policy.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-aAPWI", "Errors.IAM.LabelPolicyInvalid") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - repoIam := model.IAMFromModel(iam) - repoLabelPolicy := model.LabelPolicyFromModel(policy) - - addAggregate := LabelPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoLabelPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.LabelPolicyToModel(repoIam.DefaultLabelPolicy), nil -} - -func (es *IAMEventstore) ChangeLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - if policy == nil || !policy.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-vRqjg", "Errors.IAM.LabelPolicyInvalid") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - repoIam := model.IAMFromModel(iam) - repoLabelPolicy := model.LabelPolicyFromModel(policy) - - addAggregate := LabelPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoLabelPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.LabelPolicyToModel(repoIam.DefaultLabelPolicy), nil -} - -func (es *IAMEventstore) PrepareAddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*model.IAM, *models.Aggregate, error) { - if policy == nil || !policy.IsValid() { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-3mP0s", "Errors.IAM.LoginPolicyInvalid") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - repoLoginPolicy := model.LoginPolicyFromModel(policy) - - addAggregate, err := LoginPolicyAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoIam, repoLoginPolicy) - if err != nil { - return nil, nil, err - } - return repoIam, addAggregate, nil -} - -func (es *IAMEventstore) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - repoIam, addAggregate, err := es.PrepareAddLoginPolicy(ctx, policy) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.LoginPolicyToModel(repoIam.DefaultLoginPolicy), nil -} - -func (es *IAMEventstore) PrepareChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*model.IAM, *models.Aggregate, error) { - if policy == nil || !policy.IsValid() { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-3M0so", "Errors.IAM.LoginPolicyInvalid") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - repoLoginPolicy := model.LoginPolicyFromModel(policy) - - changeAgg, err := LoginPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoLoginPolicy)(ctx) - if err != nil { - return nil, nil, err - } - return repoIam, changeAgg, nil -} - -func (es *IAMEventstore) ChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - repoIam, changeAggregate, err := es.PrepareChangeLoginPolicy(ctx, policy) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, changeAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.LoginPolicyToModel(repoIam.DefaultLoginPolicy), nil -} - -func (es *IAMEventstore) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) { - if provider == nil || !provider.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-bMS8i", "Errors.IdpProviderInvalid") - } - iam, err := es.IAMByID(ctx, provider.AggregateID) - if err != nil { - return nil, err - } - if _, m := iam.DefaultLoginPolicy.GetIdpProvider(provider.IDPConfigID); m != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-idke6", "Errors.IAM.LoginPolicy.IdpProviderAlreadyExisting") - } - repoIam := model.IAMFromModel(iam) - repoProvider := model.IDPProviderFromModel(provider) - - addAggregate := LoginPolicyIDPProviderAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoProvider) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - if _, m := model.GetIDPProvider(repoIam.DefaultLoginPolicy.IDPProviders, provider.IDPConfigID); m != nil { - return model.IDPProviderToModel(m), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-Slf9s", "Errors.Internal") -} - -func (es *IAMEventstore) PrepareRemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*model.IAM, *models.Aggregate, error) { - if provider == nil || !provider.IsValid() { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Esi8c", "Errors.IdpProviderInvalid") - } - iam, err := es.IAMByID(ctx, provider.AggregateID) - if err != nil { - return nil, nil, err - } - if _, m := iam.DefaultLoginPolicy.GetIdpProvider(provider.IDPConfigID); m == nil { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-29skr", "Errors.IAM.LoginPolicy.IdpProviderNotExisting") - } - repoIam := model.IAMFromModel(iam) - removeAgg, err := LoginPolicyIDPProviderRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoIam, &model.IDPProviderID{provider.IDPConfigID}) - if err != nil { - return nil, nil, err - } - return repoIam, removeAgg, nil -} - -func (es *IAMEventstore) RemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) error { - repoIam, removeAgg, err := es.PrepareRemoveIDPProviderFromLoginPolicy(ctx, provider) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, removeAgg) - if err != nil { - return err - } - es.iamCache.cacheIAM(repoIam) - return nil -} - -func (es *IAMEventstore) AddSecondFactorToLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.SecondFactorType) (iam_model.SecondFactorType, error) { - repoIAM, addAggregate, err := es.PrepareAddSecondFactorToLoginPolicy(ctx, aggregateID, mfa) - if err != nil { - return 0, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIAM.AppendEvents, addAggregate) - if err != nil { - return 0, err - } - es.iamCache.cacheIAM(repoIAM) - if _, m := model.GetMFA(repoIAM.DefaultLoginPolicy.SecondFactors, int32(mfa)); m != 0 { - return iam_model.SecondFactorType(m), nil - } - return 0, caos_errs.ThrowInternal(nil, "EVENT-5N9so", "Errors.Internal") -} - -func (es *IAMEventstore) PrepareAddSecondFactorToLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.SecondFactorType) (*model.IAM, *models.Aggregate, error) { - if mfa == iam_model.SecondFactorTypeUnspecified { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-1M8Js", "Errors.IAM.LoginPolicy.MFA.Unspecified") - } - iam, err := es.IAMByID(ctx, aggregateID) - if err != nil { - return nil, nil, err - } - if _, m := iam.DefaultLoginPolicy.GetSecondFactor(mfa); m != 0 { - return nil, nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-4Rk09", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") - } - repoIAM := model.IAMFromModel(iam) - repoMFA := model.SecondFactorFromModel(mfa) - - addAggregate := LoginPolicySecondFactorAddedAggregate(es.Eventstore.AggregateCreator(), repoIAM, repoMFA) - aggregate, err := addAggregate(ctx) - if err != nil { - return nil, nil, err - } - return repoIAM, aggregate, nil -} - -func (es *IAMEventstore) RemoveSecondFactorFromLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.SecondFactorType) error { - if mfa == iam_model.SecondFactorTypeUnspecified { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-4gJ9s", "Errors.IAM.LoginPolicy.MFA.Unspecified") - } - iam, err := es.IAMByID(ctx, aggregateID) - if err != nil { - return err - } - if _, m := iam.DefaultLoginPolicy.GetSecondFactor(mfa); m == 0 { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-gBm9s", "Errors.IAM.LoginPolicy.MFA.NotExisting") - } - repoIam := model.IAMFromModel(iam) - repoMFA := model.SecondFactorFromModel(mfa) - - removeAgg := LoginPolicySecondFactorRemovedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMFA) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, removeAgg) - if err != nil { - return err - } - es.iamCache.cacheIAM(repoIam) - return nil -} - -func (es *IAMEventstore) PrepareAddMultiFactorToLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.MultiFactorType) (*model.IAM, *models.Aggregate, error) { - if mfa == iam_model.MultiFactorTypeUnspecified { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-2Dh7J", "Errors.IAM.LoginPolicy.MFA.Unspecified") - } - iam, err := es.IAMByID(ctx, aggregateID) - if err != nil { - return nil, nil, err - } - if _, m := iam.DefaultLoginPolicy.GetMultiFactor(mfa); m != 0 { - return nil, nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-4Rk09", "Errors.IAM.LoginPolicy.MFA.AlreadyExists") - } - repoIam := model.IAMFromModel(iam) - repoMFA := model.MultiFactorFromModel(mfa) - - addAggregate, err := LoginPolicyMultiFactorAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMFA)(ctx) - if err != nil { - return nil, nil, err - } - return repoIam, addAggregate, nil -} - -func (es *IAMEventstore) AddMultiFactorToLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.MultiFactorType) (iam_model.MultiFactorType, error) { - repoIAM, addAggregate, err := es.PrepareAddMultiFactorToLoginPolicy(ctx, aggregateID, mfa) - if err != nil { - return 0, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIAM.AppendEvents, addAggregate) - if err != nil { - return 0, err - } - es.iamCache.cacheIAM(repoIAM) - if _, m := model.GetMFA(repoIAM.DefaultLoginPolicy.MultiFactors, int32(mfa)); m != 0 { - return iam_model.MultiFactorType(m), nil - } - return 0, caos_errs.ThrowInternal(nil, "EVENT-5N9so", "Errors.Internal") -} - -func (es *IAMEventstore) RemoveMultiFactorFromLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.MultiFactorType) error { - if mfa == iam_model.MultiFactorTypeUnspecified { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-4gJ9s", "Errors.IAM.LoginPolicy.MFA.Unspecified") - } - iam, err := es.IAMByID(ctx, aggregateID) - if err != nil { - return err - } - if _, m := iam.DefaultLoginPolicy.GetMultiFactor(mfa); m == 0 { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-gBm9s", "Errors.IAM.LoginPolicy.MFA.NotExisting") - } - repoIam := model.IAMFromModel(iam) - repoMFA := model.MultiFactorFromModel(mfa) - - removeAgg := LoginPolicyMultiFactorRemovedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMFA) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, removeAgg) - if err != nil { - return err - } - es.iamCache.cacheIAM(repoIam) - return nil -} - -func (es *IAMEventstore) PrepareAddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*model.IAM, *models.Aggregate, error) { - if policy == nil { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Ks8Fs", "Errors.IAM.PasswordComplexityPolicy.Empty") - } - if err := policy.IsValid(); err != nil { - return nil, nil, err - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - repoPasswordComplexityPolicy := model.PasswordComplexityPolicyFromModel(policy) - - addAggregate, err := PasswordComplexityPolicyAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoIam, repoPasswordComplexityPolicy) - if err != nil { - return nil, nil, err - } - return repoIam, addAggregate, nil -} - -func (es *IAMEventstore) AddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - repoIam, addAggregate, err := es.PrepareAddPasswordComplexityPolicy(ctx, policy) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.PasswordComplexityPolicyToModel(repoIam.DefaultPasswordComplexityPolicy), nil -} - -func (es *IAMEventstore) ChangePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - if policy == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Lso02", "Errors.IAM.PasswordComplexityPolicy.Empty") - } - if err := policy.IsValid(); err != nil { - return nil, err - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - repoIam := model.IAMFromModel(iam) - repoPasswordComplexityPolicy := model.PasswordComplexityPolicyFromModel(policy) - - addAggregate := PasswordComplexityPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoPasswordComplexityPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.PasswordComplexityPolicyToModel(repoIam.DefaultPasswordComplexityPolicy), nil -} - -func (es *IAMEventstore) PrepareAddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*model.IAM, *models.Aggregate, error) { - if policy == nil || policy.AggregateID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-2dGt6", "Errors.IAM.PasswordAgePolicy.Empty") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - repoPasswordAgePolicy := model.PasswordAgePolicyFromModel(policy) - - addAggregate, err := PasswordAgePolicyAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoIam, repoPasswordAgePolicy) - if err != nil { - return nil, nil, err - } - return repoIam, addAggregate, nil -} - -func (es *IAMEventstore) AddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - repoIam, addAggregate, err := es.PrepareAddPasswordAgePolicy(ctx, policy) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.PasswordAgePolicyToModel(repoIam.DefaultPasswordAgePolicy), nil -} - -func (es *IAMEventstore) ChangePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - if policy == nil || policy.AggregateID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-2Fgt6", "Errors.IAM.PasswordAgePolicy.Empty") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - repoIam := model.IAMFromModel(iam) - repoPasswordAgePolicy := model.PasswordAgePolicyFromModel(policy) - - addAggregate := PasswordAgePolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoPasswordAgePolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.PasswordAgePolicyToModel(repoIam.DefaultPasswordAgePolicy), nil -} - -func (es *IAMEventstore) PrepareAddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*model.IAM, *models.Aggregate, error) { - if policy == nil || policy.AggregateID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-3R56z", "Errors.IAM.PasswordLockoutPolicy.Empty") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - repoPasswordLockoutPolicy := model.PasswordLockoutPolicyFromModel(policy) - - addAggregate, err := PasswordLockoutPolicyAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoIam, repoPasswordLockoutPolicy) - if err != nil { - return nil, nil, err - } - return repoIam, addAggregate, nil -} - -func (es *IAMEventstore) AddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - repoIam, addAggregate, err := es.PrepareAddPasswordLockoutPolicy(ctx, policy) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.PasswordLockoutPolicyToModel(repoIam.DefaultPasswordLockoutPolicy), nil -} - -func (es *IAMEventstore) ChangePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - if policy == nil || policy.AggregateID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-6Zsj9", "Errors.IAM.PasswordLockoutPolicy.Empty") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - repoIam := model.IAMFromModel(iam) - repoPasswordLockoutPolicy := model.PasswordLockoutPolicyFromModel(policy) - - addAggregate := PasswordLockoutPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoPasswordLockoutPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.PasswordLockoutPolicyToModel(repoIam.DefaultPasswordLockoutPolicy), nil -} - func (es *IAMEventstore) GetOrgIAMPolicy(ctx context.Context, iamID string) (*iam_model.OrgIAMPolicy, error) { existingIAM, err := es.IAMByID(ctx, iamID) if err != nil { @@ -911,171 +83,3 @@ func (es *IAMEventstore) GetOrgIAMPolicy(ctx context.Context, iamID string) (*ia } return existingIAM.DefaultOrgIAMPolicy, nil } - -func (es *IAMEventstore) PrepareAddOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*model.IAM, *models.Aggregate, error) { - if policy == nil || policy.AggregateID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-3R56z", "Errors.IAM.OrgIAMPolicy.Empty") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - repoOrgIAMPolicy := model.OrgIAMPolicyFromModel(policy) - - addAggregate, err := OrgIAMPolicyAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoIam, repoOrgIAMPolicy) - if err != nil { - return nil, nil, err - } - return repoIam, addAggregate, nil -} - -func (es *IAMEventstore) AddOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - repoIam, addAggregate, err := es.PrepareAddOrgIAMPolicy(ctx, policy) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.OrgIAMPolicyToModel(repoIam.DefaultOrgIAMPolicy), nil -} - -func (es *IAMEventstore) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - if policy == nil || policy.AggregateID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-6Zsj9", "Errors.IAM.OrgIAMPolicy.Empty") - } - iam, err := es.IAMByID(ctx, policy.AggregateID) - if err != nil { - return nil, err - } - - repoIam := model.IAMFromModel(iam) - repoOrgIAMPolicy := model.OrgIAMPolicyFromModel(policy) - - addAggregate := OrgIAMPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoOrgIAMPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.OrgIAMPolicyToModel(repoIam.DefaultOrgIAMPolicy), nil -} - -func (es *IAMEventstore) PrepareAddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*model.IAM, *models.Aggregate, error) { - if template == nil || !template.IsValid() { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-j9l18", "Errors.IAM.MailTemplate.Empty") - } - iam, err := es.IAMByID(ctx, template.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - mailTemplate := model.MailTemplateFromModel(template) - - addAggregate := MailTemplateAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, mailTemplate) - aggregate, err := addAggregate(ctx) - if err != nil { - return nil, nil, err - } - return repoIam, aggregate, nil -} - -func (es *IAMEventstore) AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { - repoIam, addAggregate, err := es.PrepareAddMailTemplate(ctx, template) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.MailTemplateToModel(repoIam.DefaultMailTemplate), nil -} - -func (es *IAMEventstore) ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { - if template == nil || !template.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-gCnCs", "Errors.IAM.MailTemplateInvalid") - } - iam, err := es.IAMByID(ctx, template.AggregateID) - if err != nil { - return nil, err - } - - repoIam := model.IAMFromModel(iam) - repoMailTemplate := model.MailTemplateFromModel(template) - - addAggregate := MailTemplateChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMailTemplate) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - return model.MailTemplateToModel(repoIam.DefaultMailTemplate), nil -} - -func (es *IAMEventstore) PrepareAddMailText(ctx context.Context, text *iam_model.MailText) (*model.IAM, *models.Aggregate, error) { - if text == nil || !text.IsValid() { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-j9l18", "Errors.IAM.MailText.Empty") - } - iam, err := es.IAMByID(ctx, text.AggregateID) - if err != nil { - return nil, nil, err - } - - repoIam := model.IAMFromModel(iam) - mailText := model.MailTextFromModel(text) - - addAggregate := MailTextAddedAggregate(es.Eventstore.AggregateCreator(), repoIam, mailText) - aggregate, err := addAggregate(ctx) - if err != nil { - return nil, nil, err - } - return repoIam, aggregate, nil -} - -func (es *IAMEventstore) AddMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { - repoIam, addAggregate, err := es.PrepareAddMailText(ctx, text) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoIam.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.iamCache.cacheIAM(repoIam) - - if _, m := model.GetMailText(repoIam.DefaultMailTexts, text.MailTextType, text.Language); m != nil { - return model.MailTextToModel(m), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-9AwUm", "Errors.Internal") -} - -func (es *IAMEventstore) ChangeMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { - if !text.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-J5xbB", "Errors.IAM.MailTextInvalid") - } - existing, err := es.IAMByID(ctx, text.AggregateID) - if err != nil { - return nil, err - } - if _, m := existing.GetDefaultMailText(text.MailTextType, text.Language); m == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0CTV3", "Errors.IAM.MailTextNotExisting") - } - repoIam := model.IAMFromModel(existing) - repoMember := model.MailTextFromModel(text) - - projectAggregate := MailTextChangedAggregate(es.Eventstore.AggregateCreator(), repoIam, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoIam.AppendEvents, projectAggregate) - es.iamCache.cacheIAM(repoIam) - - if _, m := model.GetMailText(repoIam.DefaultMailTexts, text.MailTextType, text.Language); m != nil { - return model.MailTextToModel(m), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-HawVx", "Errors.Internal") -} diff --git a/internal/iam/repository/eventsourcing/eventstore_mock_test.go b/internal/iam/repository/eventsourcing/eventstore_mock_test.go deleted file mode 100644 index 18aff306bc..0000000000 --- a/internal/iam/repository/eventsourcing/eventstore_mock_test.go +++ /dev/null @@ -1,244 +0,0 @@ -package eventsourcing - -import ( - "encoding/json" - model2 "github.com/caos/zitadel/internal/iam/model" - - "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/id" - - mock_cache "github.com/caos/zitadel/internal/cache/mock" - "github.com/caos/zitadel/internal/eventstore/mock" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/golang/mock/gomock" -) - -func GetMockedEventstore(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *IAMEventstore { - return &IAMEventstore{ - Eventstore: mockEs, - iamCache: GetMockCache(ctrl), - idGenerator: GetSonyFlacke(), - } -} - -func GetMockedEventstoreWithCrypto(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *IAMEventstore { - return &IAMEventstore{ - Eventstore: mockEs, - iamCache: GetMockCache(ctrl), - idGenerator: GetSonyFlacke(), - secretCrypto: crypto.NewBCrypt(10), - } -} -func GetMockCache(ctrl *gomock.Controller) *IAMCache { - mockCache := mock_cache.NewMockCache(ctrl) - mockCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - mockCache.EXPECT().Set(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - return &IAMCache{iamCache: mockCache} -} - -func GetSonyFlacke() id.Generator { - return id.SonyFlakeGenerator -} - -func GetMockIAMByIDOK(ctrl *gomock.Controller) *IAMEventstore { - data, _ := json.Marshal(model.IAM{GlobalOrgID: "GlobalOrgID"}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.GlobalOrgSet, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockIamByIDNoEvents(ctrl *gomock.Controller) *IAMEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAM(ctrl *gomock.Controller) *IAMEventstore { - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithCrypto(ctrl *gomock.Controller) *IAMEventstore { - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithCrypto(ctrl, mockEs) -} - -func GetMockManipulateIAMWithMember(ctrl *gomock.Controller) *IAMEventstore { - memberData, _ := json.Marshal(model.IAMMember{UserID: "UserID", Roles: []string{"Role"}}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMMemberAdded, Data: memberData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithOIDCIdp(ctrl *gomock.Controller) *IAMEventstore { - idpData, _ := json.Marshal(model.IDPConfig{IDPConfigID: "IDPConfigID", Name: "Name"}) - oidcData, _ := json.Marshal(model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.IDPConfigAdded, Data: idpData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.OIDCIDPConfigAdded, Data: oidcData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithLoginPolicy(ctrl *gomock.Controller) *IAMEventstore { - policyData, _ := json.Marshal(model.LoginPolicy{AllowRegister: true, AllowUsernamePassword: true, AllowExternalIdp: true}) - idpProviderData, _ := json.Marshal(model.IDPProvider{IDPConfigID: "IDPConfigID", Type: 1}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyAdded, Data: policyData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyIDPProviderAdded, Data: idpProviderData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl *gomock.Controller) *IAMEventstore { - policyData, _ := json.Marshal(model.LoginPolicy{AllowRegister: true, AllowUsernamePassword: true, AllowExternalIdp: true}) - idpProviderData, _ := json.Marshal(model.IDPProvider{IDPConfigID: "IDPConfigID", Type: 1}) - secondFactor, _ := json.Marshal(model.MFA{MFAType: int32(model2.SecondFactorTypeOTP)}) - multiFactor, _ := json.Marshal(model.MFA{MFAType: int32(model2.MultiFactorTypeU2FWithPIN)}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyAdded, Data: policyData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyIDPProviderAdded, Data: idpProviderData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicySecondFactorAdded, Data: secondFactor}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyMultiFactorAdded, Data: multiFactor}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithPasswodComplexityPolicy(ctrl *gomock.Controller) *IAMEventstore { - policyData, _ := json.Marshal(model.PasswordComplexityPolicy{MinLength: 10}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.PasswordComplexityPolicyAdded, Data: policyData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithPasswordAgePolicy(ctrl *gomock.Controller) *IAMEventstore { - policyData, _ := json.Marshal(model.PasswordAgePolicy{MaxAgeDays: 10, ExpireWarnDays: 10}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.PasswordAgePolicyAdded, Data: policyData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithPasswordLockoutPolicy(ctrl *gomock.Controller) *IAMEventstore { - policyData, _ := json.Marshal(model.PasswordLockoutPolicy{MaxAttempts: 10, ShowLockOutFailures: true}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.PasswordLockoutPolicyAdded, Data: policyData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithOrgIAMPolicy(ctrl *gomock.Controller) *IAMEventstore { - policyData, _ := json.Marshal(model.OrgIAMPolicy{UserLoginMustBeDomain: true}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.OrgIAMPolicyAdded, Data: policyData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMNotExisting(ctrl *gomock.Controller) *IAMEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithLabelPolicy(ctrl *gomock.Controller) *IAMEventstore { - policyData, _ := json.Marshal(model.LabelPolicy{PrimaryColor: "000001", SecondaryColor: "FFFFF1"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.LabelPolicyAdded, Data: policyData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithMailTemplate(ctrl *gomock.Controller) *IAMEventstore { - mailTemplate, _ := json.Marshal(model.MailTemplate{Template: []byte("")}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTemplateAdded, Data: mailTemplate}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateIAMWithMailText(ctrl *gomock.Controller) *IAMEventstore { - mailText, _ := json.Marshal(model.MailText{MailTextType: "Type", Language: "DE"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.IAMSetupStarted}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTextAdded, Data: mailText}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} diff --git a/internal/iam/repository/eventsourcing/eventstore_test.go b/internal/iam/repository/eventsourcing/eventstore_test.go deleted file mode 100644 index a32efc0767..0000000000 --- a/internal/iam/repository/eventsourcing/eventstore_test.go +++ /dev/null @@ -1,3381 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - - "github.com/golang/mock/gomock" - - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" -) - -func TestIamByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - iam *model.IAM - } - type res struct { - iam *model.IAM - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "iam from events, ok", - args: args{ - es: GetMockIAMByIDOK(ctrl), - iam: &model.IAM{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - iam: &model.IAM{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - }, - { - name: "iam from events, no events", - args: args{ - es: GetMockIamByIDNoEvents(ctrl), - iam: &model.IAM{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "iam from events, no id", - args: args{ - es: GetMockIamByIDNoEvents(ctrl), - iam: &model.IAM{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.IAMByID(nil, tt.args.iam.AggregateID) - if (tt.res.errFunc != nil && !tt.res.errFunc(err)) || (err != nil && tt.res.errFunc == nil) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.errFunc != nil && tt.res.errFunc(err) { - return - } - if result.AggregateID != tt.res.iam.AggregateID { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.iam.AggregateID, result.AggregateID) - } - }) - } -} - -// -//func TestSetUpStarted(t *testing.T) { -// ctrl := gomock.NewController(t) -// type args struct { -// es *IAMEventstore -// ctx context.Context -// iamID string -// step iam_model.Step -// } -// type res struct { -// iam *iam_model.IAM -// errFunc func(err error) bool -// } -// tests := []struct { -// name string -// args args -// res res -// }{ -// { -// name: "setup started iam, ok", -// args: args{ -// es: GetMockManipulateIAMNotExisting(ctrl), -// ctx: authz.NewMockContext("orgID", "userID"), -// iamID: "iamID", -// step: iam_model.Step1, -// }, -// res: res{ -// iam: &iam_model.IAM{ObjectRoot: es_models.ObjectRoot{AggregateID: "iamID", Sequence: 1}, SetUpStarted: iam_model.Step1}, -// }, -// }, -// { -// name: "setup already started", -// args: args{ -// es: GetMockManipulateIAM(ctrl), -// ctx: authz.NewMockContext("orgID", "userID"), -// iamID: "iamID", -// step: iam_model.Step1, -// }, -// res: res{ -// errFunc: caos_errs.IsPreconditionFailed, -// }, -// }, -// { -// name: "setup iam no id", -// args: args{ -// es: GetMockManipulateIAM(ctrl), -// ctx: authz.NewMockContext("orgID", "userID"), -// step: iam_model.Step1, -// }, -// res: res{ -// errFunc: caos_errs.IsPreconditionFailed, -// }, -// }, -// } -// for _, tt := range tests { -// t.Run(tt.name, func(t *testing.T) { -// result, err := tt.args.es.StartSetup(tt.args.ctx, tt.args.iamID, tt.args.step) -// if (tt.res.errFunc != nil && !tt.res.errFunc(err)) || (err != nil && tt.res.errFunc == nil) { -// t.Errorf("got wrong err: %v ", err) -// return -// } -// if tt.res.errFunc != nil && tt.res.errFunc(err) { -// return -// } -// if result.AggregateID == "" { -// t.Errorf("result has no id") -// } -// if result.SetUpStarted != tt.res.iam.SetUpStarted { -// t.Errorf("got wrong result setupStarted: expected: %v, actual: %v ", tt.res.iam.SetUpStarted, result.SetUpStarted) -// } -// }) -// } -//} - -func TestSetGlobalOrg(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - iamID string - globalOrg string - } - type res struct { - iam *model.IAM - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "global org set, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - iamID: "iamID", - globalOrg: "globalOrg", - }, - res: res{ - iam: &model.IAM{ObjectRoot: es_models.ObjectRoot{AggregateID: "iamID", Sequence: 1}, SetUpStarted: model.Step1, GlobalOrgID: "globalOrg"}, - }, - }, - { - name: "no iam id", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - globalOrg: "", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no global org", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - iamID: "iamID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - iamID: "iamID", - globalOrg: "globalOrg", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.SetGlobalOrg(tt.args.ctx, tt.args.iamID, tt.args.globalOrg) - if (tt.res.errFunc != nil && !tt.res.errFunc(err)) || (err != nil && tt.res.errFunc == nil) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.errFunc != nil && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.GlobalOrgID != tt.res.iam.GlobalOrgID { - t.Errorf("got wrong result GlobalOrgID: expected: %v, actual: %v ", tt.res.iam.GlobalOrgID, result.GlobalOrgID) - } - }) - } -} - -func TestSetIamProjectID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - iamID string - iamProjectID string - } - type res struct { - iam *model.IAM - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "iam project set, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - iamID: "iamID", - iamProjectID: "iamProjectID", - }, - res: res{ - iam: &model.IAM{ObjectRoot: es_models.ObjectRoot{AggregateID: "iamID", Sequence: 1}, SetUpStarted: model.Step1, IAMProjectID: "iamProjectID"}, - }, - }, - { - name: "no iam id", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - iamProjectID: "", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no global org", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - iamID: "iamID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - iamID: "iamID", - iamProjectID: "iamProjectID", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.SetIAMProject(tt.args.ctx, tt.args.iamID, tt.args.iamProjectID) - if (tt.res.errFunc != nil && !tt.res.errFunc(err)) || (err != nil && tt.res.errFunc == nil) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.errFunc != nil && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IAMProjectID != tt.res.iam.IAMProjectID { - t.Errorf("got wrong result IAMProjectID: expected: %v, actual: %v ", tt.res.iam.IAMProjectID, result.IAMProjectID) - } - }) - } -} - -func TestAddIamMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - member *iam_model.IAMMember - } - type res struct { - result *iam_model.IAMMember - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add iam member, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - result: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - { - name: "no userid", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Roles: []string{"Roles"}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no roles", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member already existing", - args: args{ - es: GetMockManipulateIAMWithMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddIAMMember(tt.args.ctx, tt.args.member) - if (tt.res.errFunc != nil && !tt.res.errFunc(err)) || (err != nil && tt.res.errFunc == nil) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.errFunc != nil && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.UserID != tt.res.result.UserID { - t.Errorf("got wrong result userid: expected: %v, actual: %v ", tt.res.result.UserID, result.UserID) - } - if len(result.Roles) != len(tt.res.result.Roles) { - t.Errorf("got wrong result roles: expected: %v, actual: %v ", tt.res.result.Roles, result.Roles) - } - }) - } -} - -func TestChangeIamMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - member *iam_model.IAMMember - } - type res struct { - result *iam_model.IAMMember - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add iam member, ok", - args: args{ - es: GetMockManipulateIAMWithMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"ChangeRoles"}}, - }, - res: res{ - result: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - { - name: "no userid", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Roles: []string{"ChangeRoles"}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no roles", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member not existing", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"ChangeRoles"}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeIAMMember(tt.args.ctx, tt.args.member) - if (tt.res.errFunc != nil && !tt.res.errFunc(err)) || (err != nil && tt.res.errFunc == nil) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.errFunc != nil && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.UserID != tt.res.result.UserID { - t.Errorf("got wrong result userid: expected: %v, actual: %v ", tt.res.result.UserID, result.UserID) - } - if len(result.Roles) != len(tt.res.result.Roles) { - t.Errorf("got wrong result roles: expected: %v, actual: %v ", tt.res.result.Roles, result.Roles) - } - }) - } -} - -func TestRemoveIamMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - existingIAM *model.IAM - member *iam_model.IAMMember - } - type res struct { - result *iam_model.IAMMember - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove iam member, ok", - args: args{ - es: GetMockManipulateIAMWithMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Members: []*model.IAMMember{{UserID: "UserID", Roles: []string{"Roles"}}}, - }, - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"}, - }, - res: res{ - result: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - { - name: "no userid", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Members: []*model.IAMMember{{UserID: "UserID", Roles: []string{"Roles"}}}, - }, - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Roles: []string{"ChangeRoles"}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member not existing", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - }, - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &iam_model.IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"ChangeRoles"}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveIAMMember(tt.args.ctx, tt.args.member) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - result *iam_model.IDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add idp, ok", - args: args{ - es: GetMockManipulateIAMWithCrypto(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - Type: iam_model.IDPConfigTypeOIDC, - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - ClientSecretString: "ClientSecret", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - }, - res: res{ - result: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Name: "Name", - Type: iam_model.IDPConfigTypeOIDC, - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - }, - }, - { - name: "invalid idp config", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - ClientSecretString: "ClientSecret", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddIDPConfig(tt.args.ctx, tt.args.idp) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.IDPConfigID == "" { - t.Errorf("result has no id") - } - if result.OIDCConfig.IDPConfigID == "" { - t.Errorf("result has no id") - } - if result.OIDCConfig == nil && result.OIDCConfig.ClientSecret == nil { - t.Errorf("result has no client secret") - } - if result.Name != tt.res.result.Name { - t.Errorf("got wrong result key: expected: %v, actual: %v ", tt.res.result.Name, result.Name) - } - if result.OIDCConfig.ClientID != tt.res.result.OIDCConfig.ClientID { - t.Errorf("got wrong result key: expected: %v, actual: %v ", tt.res.result.OIDCConfig.ClientID, result.OIDCConfig.ClientID) - } - }) - } -} - -func TestChangeIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - result *iam_model.IDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change idp, ok", - args: args{ - es: GetMockManipulateIAMWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "NameChanged", - }, - }, - res: res{ - result: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "NameChanged", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - }, - { - name: "invalid idp", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeIDPConfig(tt.args.ctx, tt.args.idp) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) - } - if result.Name != tt.res.result.Name { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.result.Name, result.Name) - } - }) - } -} - -func TestRemoveIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove idp, ok", - args: args{ - es: GetMockManipulateIAMWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - }, - }, - }, - { - name: "no IDPConfigID", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing idp not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveIDPConfig(tt.args.ctx, tt.args.idp) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} -func TestDeactivateIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - result *iam_model.IDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate, ok", - args: args{ - es: GetMockManipulateIAMWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - }, - res: res{ - result: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - State: iam_model.IDPConfigStateInactive, - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - }, - { - name: "no idp id", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.DeactivateIDPConfig(tt.args.ctx, tt.args.idp.AggregateID, tt.args.idp.IDPConfigID) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) - } - if result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - }) - } -} - -func TestReactivateIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - result *iam_model.IDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate, ok", - args: args{ - es: GetMockManipulateIAMWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - }, - res: res{ - result: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - State: iam_model.IDPConfigStateActive, - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - }, - { - name: "no idp id", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ReactivateIDPConfig(tt.args.ctx, tt.args.idp.AggregateID, tt.args.idp.IDPConfigID) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) - } - if result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - }) - } -} - -func TestChangeOIDCIDPConfig(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - config *iam_model.OIDCIDPConfig - } - type res struct { - result *iam_model.OIDCIDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change oidc config, ok", - args: args{ - es: GetMockManipulateIAMWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientIDChange", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - res: res{ - result: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientIDChange", - }, - }, - }, - { - name: "invalid config", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientID", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientID", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeIDPOIDCConfig(tt.args.ctx, tt.args.config) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) - } - if result.ClientID != tt.res.result.ClientID { - t.Errorf("got wrong result responsetype: expected: %v, actual: %v ", tt.res.result.ClientID, result.ClientID) - } - }) - } -} - -func TestAddLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.LoginPolicy - } - type res struct { - result *iam_model.LoginPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add login policy, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - }, - }, - res: res{ - result: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddLoginPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.AllowRegister != tt.res.result.AllowRegister { - t.Errorf("got wrong result AllowRegister: expected: %v, actual: %v ", tt.res.result.AllowRegister, result.AllowRegister) - } - }) - } -} - -func TestChangeLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.LoginPolicy - } - type res struct { - result *iam_model.LoginPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add login policy, ok", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - AllowExternalIdp: false, - AllowUsernamePassword: false, - }, - }, - res: res{ - result: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - AllowExternalIdp: false, - AllowUsernamePassword: false, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeLoginPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.AllowRegister != tt.res.result.AllowRegister { - t.Errorf("got wrong result AllowRegister: expected: %v, actual: %v ", tt.res.result.AllowRegister, result.AllowRegister) - } - if result.AllowUsernamePassword != tt.res.result.AllowUsernamePassword { - t.Errorf("got wrong result AllowUsernamePassword: expected: %v, actual: %v ", tt.res.result.AllowUsernamePassword, result.AllowUsernamePassword) - } - if result.AllowExternalIdp != tt.res.result.AllowExternalIdp { - t.Errorf("got wrong result AllowExternalIDP: expected: %v, actual: %v ", tt.res.result.AllowExternalIdp, result.AllowExternalIdp) - } - }) - } -} - -func TestAddIdpProviderToLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - provider *iam_model.IDPProvider - } - type res struct { - result *iam_model.IDPProvider - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add idp to login policy, ok", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IdpConfigID2", - Type: iam_model.IDPProviderTypeSystem, - }, - }, - res: res{ - result: &iam_model.IDPProvider{IDPConfigID: "IdpConfigID2"}, - }, - }, - { - name: "add idp to login policy, already existing", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - Type: iam_model.IDPProviderTypeSystem, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "invalid provider", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IdpConfigID2", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddIDPProviderToLoginPolicy(tt.args.ctx, tt.args.provider) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - 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 KeyType: expected: %v, actual: %v ", tt.res.result.Type, result.Type) - } - }) - } -} - -func TestRemoveIdpProviderFromLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - provider *iam_model.IDPProvider - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove idp to login policy, ok", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - Type: iam_model.IDPProviderTypeSystem, - }, - }, - res: res{}, - }, - { - name: "remove idp to login policy, not existing", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IdpConfigID2", - Type: iam_model.IDPProviderTypeSystem, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "invalid provider", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IdpConfigID2", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveIDPProviderFromLoginPolicy(tt.args.ctx, tt.args.provider) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err: %v ", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddSecondFactorToLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - aggreageID string - mfa iam_model.SecondFactorType - } - type res struct { - result iam_model.SecondFactorType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add second factor to login policy, ok", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggreageID: "AggregateID", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - result: iam_model.SecondFactorTypeOTP, - }, - }, - { - name: "add second factor to login policy, already existing", - args: args{ - es: GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggreageID: "AggregateID", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "invalid mfa", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - mfa: iam_model.SecondFactorTypeUnspecified, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggreageID: "Test", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddSecondFactorToLoginPolicy(tt.args.ctx, tt.args.aggreageID, tt.args.mfa) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result != tt.res.result { - t.Errorf("got wrong result: expected: %v, actual: %v ", tt.res.result, result) - } - }) - } -} - -func TestRemoveSecondFactorFromLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - aggregateID string - mfa iam_model.SecondFactorType - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove second factor from login policy, ok", - args: args{ - es: GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{}, - }, - { - name: "remove second factor to login policy, not existing", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "invalid provider", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeUnspecified, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "Test", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveSecondFactorFromLoginPolicy(tt.args.ctx, tt.args.aggregateID, tt.args.mfa) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err: %v ", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddMultiFactorToLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - aggreageID string - mfa iam_model.MultiFactorType - } - type res struct { - result iam_model.MultiFactorType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add second factor to login policy, ok", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggreageID: "AggregateID", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - result: iam_model.MultiFactorTypeU2FWithPIN, - }, - }, - { - name: "add second factor to login policy, already existing", - args: args{ - es: GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggreageID: "AggregateID", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "invalid mfa", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - mfa: iam_model.MultiFactorTypeUnspecified, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggreageID: "Test", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddMultiFactorToLoginPolicy(tt.args.ctx, tt.args.aggreageID, tt.args.mfa) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result != tt.res.result { - t.Errorf("got wrong result: expected: %v, actual: %v ", tt.res.result, result) - } - }) - } -} - -func TestRemoveMultiFactorFromLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - aggregateID string - mfa iam_model.MultiFactorType - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove second factor from login policy, ok", - args: args{ - es: GetMockManipulateIAMWithLoginPolicyWithMFAs(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{}, - }, - { - name: "remove second factor to login policy, not existing", - args: args{ - es: GetMockManipulateIAMWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "invalid provider", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeUnspecified, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "Test", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveMultiFactorFromLoginPolicy(tt.args.ctx, tt.args.aggregateID, tt.args.mfa) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err: %v ", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddLabelPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.LabelPolicy - } - type res struct { - result *iam_model.LabelPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add label policy, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - PrimaryColor: "000000", - }, - }, - res: res{ - result: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - PrimaryColor: "000000", - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddLabelPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.PrimaryColor != tt.res.result.PrimaryColor { - t.Errorf("got wrong result PrimaryColor: expected: %v, actual: %v ", tt.res.result.PrimaryColor, result.PrimaryColor) - } - }) - } -} - -func TestChangeLabelPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.LabelPolicy - } - type res struct { - result *iam_model.LabelPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change label policy, ok", - args: args{ - es: GetMockManipulateIAMWithLabelPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - PrimaryColor: "000000", - SecondaryColor: "FFFFFF", - }, - }, - res: res{ - result: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - PrimaryColor: "000000", - SecondaryColor: "FFFFFF", - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeLabelPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.PrimaryColor != tt.res.result.PrimaryColor { - t.Errorf("got wrong result PrimaryColor: expected: %v, actual: %v ", tt.res.result.PrimaryColor, result.PrimaryColor) - } - if result.SecondaryColor != tt.res.result.SecondaryColor { - t.Errorf("got wrong result SecondaryColor: expected: %v, actual: %v ", tt.res.result.SecondaryColor, result.SecondaryColor) - } - }) - } -} -func TestAddPasswordComplexityPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicy - } - type res struct { - result *iam_model.PasswordComplexityPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password complexity policy, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 10, - }, - }, - res: res{ - result: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 10, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddPasswordComplexityPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MinLength != tt.res.result.MinLength { - t.Errorf("got wrong result MinLength: expected: %v, actual: %v ", tt.res.result.MinLength, result.MinLength) - } - }) - } -} - -func TestChangePasswordComplexityPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicy - } - type res struct { - result *iam_model.PasswordComplexityPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password complexity policy, ok", - args: args{ - es: GetMockManipulateIAMWithPasswodComplexityPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 5, - }, - }, - res: res{ - result: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 5, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangePasswordComplexityPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MinLength != tt.res.result.MinLength { - t.Errorf("got wrong result MinLength: expected: %v, actual: %v ", tt.res.result.MinLength, result.MinLength) - } - }) - } -} - -func TestAddPasswordAgePolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.PasswordAgePolicy - } - type res struct { - result *iam_model.PasswordAgePolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password age policy, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 10, - ExpireWarnDays: 10, - }, - }, - res: res{ - result: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 10, - ExpireWarnDays: 10, - }, - }, - }, - { - name: "empty policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: nil, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 10, - ExpireWarnDays: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddPasswordAgePolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MaxAgeDays != tt.res.result.MaxAgeDays { - t.Errorf("got wrong result MaxAgeDays: expected: %v, actual: %v ", tt.res.result.MaxAgeDays, result.MaxAgeDays) - } - - if result.ExpireWarnDays != tt.res.result.ExpireWarnDays { - t.Errorf("got wrong result.ExpireWarnDays: expected: %v, actual: %v ", tt.res.result.ExpireWarnDays, result.ExpireWarnDays) - } - }) - } -} - -func TestChangePasswordAgePolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.PasswordAgePolicy - } - type res struct { - result *iam_model.PasswordAgePolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password age policy, ok", - args: args{ - es: GetMockManipulateIAMWithPasswordAgePolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 5, - }, - }, - res: res{ - result: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 5, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: nil, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangePasswordAgePolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MaxAgeDays != tt.res.result.MaxAgeDays { - t.Errorf("got wrong result MaxAgeDays: expected: %v, actual: %v ", tt.res.result.MaxAgeDays, result.MaxAgeDays) - } - - if result.ExpireWarnDays != tt.res.result.ExpireWarnDays { - t.Errorf("got wrong result.ExpireWarnDays: expected: %v, actual: %v ", tt.res.result.ExpireWarnDays, result.ExpireWarnDays) - } - }) - } -} - -func TestAddPasswordLockoutPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.PasswordLockoutPolicy - } - type res struct { - result *iam_model.PasswordLockoutPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password lockout policy, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 10, - ShowLockOutFailures: true, - }, - }, - res: res{ - result: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 10, - ShowLockOutFailures: true, - }, - }, - }, - { - name: "empty policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: nil, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 10, - ShowLockOutFailures: true, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddPasswordLockoutPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - - if result.MaxAttempts != tt.res.result.MaxAttempts { - t.Errorf("got wrong result MaxAttempts: expected: %v, actual: %v ", tt.res.result.MaxAttempts, result.MaxAttempts) - } - - if result.ShowLockOutFailures != tt.res.result.ShowLockOutFailures { - t.Errorf("got wrong result.ShowLockOutFailures: expected: %v, actual: %v ", tt.res.result.ShowLockOutFailures, result.ShowLockOutFailures) - } - }) - } -} - -func TestChangePasswordLockoutPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.PasswordLockoutPolicy - } - type res struct { - result *iam_model.PasswordLockoutPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password lockout policy, ok", - args: args{ - es: GetMockManipulateIAMWithPasswordLockoutPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 5, - }, - }, - res: res{ - result: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 5, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: nil, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangePasswordLockoutPolicy(tt.args.ctx, tt.args.policy) - - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MaxAttempts != tt.res.result.MaxAttempts { - t.Errorf("got wrong result MaxAttempts: expected: %v, actual: %v ", tt.res.result.MaxAttempts, result.MaxAttempts) - } - - if result.ShowLockOutFailures != tt.res.result.ShowLockOutFailures { - t.Errorf("got wrong result.ShowLockOutFailures: expected: %v, actual: %v ", tt.res.result.ShowLockOutFailures, result.ShowLockOutFailures) - } - }) - } -} - -func TestAddOrgIAMPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.OrgIAMPolicy - } - type res struct { - result *iam_model.OrgIAMPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add org iam policy, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.OrgIAMPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - UserLoginMustBeDomain: true, - }, - }, - res: res{ - result: &iam_model.OrgIAMPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - UserLoginMustBeDomain: true, - }, - }, - }, - { - name: "empty policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: nil, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.OrgIAMPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - UserLoginMustBeDomain: true, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddOrgIAMPolicy(tt.args.ctx, tt.args.policy) - - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.UserLoginMustBeDomain != tt.res.result.UserLoginMustBeDomain { - t.Errorf("got wrong result userLoginMustBeDomain: expected: %v, actual: %v ", tt.res.result.UserLoginMustBeDomain, result.UserLoginMustBeDomain) - } - }) - } -} - -func TestChangeOrgIAMPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.OrgIAMPolicy - } - type res struct { - result *iam_model.OrgIAMPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change org iam policy, ok", - args: args{ - es: GetMockManipulateIAMWithOrgIAMPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.OrgIAMPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - UserLoginMustBeDomain: false, - }, - }, - res: res{ - result: &iam_model.OrgIAMPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - UserLoginMustBeDomain: false, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: nil, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.OrgIAMPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - UserLoginMustBeDomain: true, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeOrgIAMPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.UserLoginMustBeDomain != tt.res.result.UserLoginMustBeDomain { - t.Errorf("got wrong result userLoginMustBeDomain: expected: %v, actual: %v ", tt.res.result.UserLoginMustBeDomain, result.UserLoginMustBeDomain) - } - }) - } -} -func TestAddMailTemplate(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.MailTemplate - } - type res struct { - result *iam_model.MailTemplate - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mailtemplate, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - res: res{ - result: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddMailTemplate(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.Template) != string(tt.res.result.Template) { - t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) - } - }) - } -} - -func TestChangeMailTemplate(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - template *iam_model.MailTemplate - } - type res struct { - result *iam_model.MailTemplate - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mail template, ok", - args: args{ - es: GetMockManipulateIAMWithMailTemplate(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - res: res{ - result: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - }, - { - name: "invalid mail template", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeMailTemplate(tt.args.ctx, tt.args.template) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.Template) != string(tt.res.result.Template) { - t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) - } - }) - } -} -func TestAddMailText(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.MailText - } - type res struct { - result *iam_model.MailText - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mailtemplate, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", Language: "DE", - }, - }, - res: res{ - result: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", Language: "DE", - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddMailText(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.MailTextType) != string(tt.res.result.MailTextType) { - t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) - } - }) - } -} - -func TestChangeMailText(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.MailText - } - type res struct { - result *iam_model.MailText - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change mailtemplate, ok", - args: args{ - es: GetMockManipulateIAMWithMailText(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", Language: "DE", - }, - }, - res: res{ - result: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", Language: "DE", - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeMailText(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.MailTextType) != string(tt.res.result.MailTextType) { - t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) - } - }) - } -} -func TestAddMailTemplate(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.MailTemplate - } - type res struct { - result *iam_model.MailTemplate - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mailtemplate, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - res: res{ - result: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddMailTemplate(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.Template) != string(tt.res.result.Template) { - t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) - } - }) - } -} - -func TestChangeMailTemplate(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - template *iam_model.MailTemplate - } - type res struct { - result *iam_model.MailTemplate - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mail template, ok", - args: args{ - es: GetMockManipulateIAMWithMailTemplate(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - res: res{ - result: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - }, - { - name: "invalid mail template", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeMailTemplate(tt.args.ctx, tt.args.template) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.Template) != string(tt.res.result.Template) { - t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) - } - }) - } -} -func TestAddMailText(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.MailText - } - type res struct { - result *iam_model.MailText - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mailtemplate, ok", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", Language: "DE", - }, - }, - res: res{ - result: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", Language: "DE", - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddMailText(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.MailTextType) != string(tt.res.result.MailTextType) { - t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) - } - }) - } -} - -func TestChangeMailText(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *IAMEventstore - ctx context.Context - policy *iam_model.MailText - } - type res struct { - result *iam_model.MailText - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change mailtemplate, ok", - args: args{ - es: GetMockManipulateIAMWithMailText(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", Language: "DE", - }, - }, - res: res{ - result: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", Language: "DE", - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockManipulateIAM(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockManipulateIAMNotExisting(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeMailText(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.MailTextType) != string(tt.res.result.MailTextType) { - t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) - } - }) - } -} diff --git a/internal/iam/repository/eventsourcing/iam.go b/internal/iam/repository/eventsourcing/iam.go index 39803be9b5..d8d99f1889 100644 --- a/internal/iam/repository/eventsourcing/iam.go +++ b/internal/iam/repository/eventsourcing/iam.go @@ -28,822 +28,3 @@ func IAMAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, i } return aggCreator.NewAggregate(ctx, iam.AggregateID, model.IAMAggregate, model.IAMVersion, iam.Sequence) } - -func IAMAggregateOverwriteContext(ctx context.Context, aggCreator *es_models.AggregateCreator, iam *model.IAM, resourceOwnerID string, userID string) (*es_models.Aggregate, error) { - if iam == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dis83", "Errors.Internal") - } - - return aggCreator.NewAggregate(ctx, iam.AggregateID, model.IAMAggregate, model.IAMVersion, iam.Sequence, es_models.OverwriteResourceOwner(resourceOwnerID), es_models.OverwriteEditorUser(userID)) -} - -func IAMSetupStartedAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := IAMAggregate(ctx, aggCreator, iam) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.IAMSetupStarted, &struct{ Step model.Step }{Step: iam.SetUpStarted}) - } -} - -func IAMSetupDoneAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := IAMAggregate(ctx, aggCreator, iam) - if err != nil { - return nil, err - } - - return agg.AppendEvent(model.IAMSetupDone, &struct{ Step model.Step }{Step: iam.SetUpDone}) - } -} - -func IAMSetupDoneEvent(ctx context.Context, agg *es_models.Aggregate, iam *model.IAM) (*es_models.Aggregate, error) { - return agg.AppendEvent(model.IAMSetupDone, &struct{ Step model.Step }{Step: iam.SetUpDone}) -} - -func IAMSetGlobalOrgAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM, globalOrg string) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if globalOrg == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-8siwa", "Errors.IAM.GlobalOrgMissing") - } - agg, err := IAMAggregate(ctx, aggCreator, iam) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.GlobalOrgSet, &model.IAM{GlobalOrgID: globalOrg}) - } -} - -func IAMSetIamProjectAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM, projectID string) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if projectID == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sjuw3", "Errors.IAM.IAMProjectIDMissing") - } - agg, err := IAMAggregate(ctx, aggCreator, iam) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.IAMProjectSet, &model.IAM{IAMProjectID: projectID}) - } -} - -func IAMMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9sope", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existingIAM) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.IAMMemberAdded, member) - } -} - -func IAMMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-38skf", "Errors.Internal") - } - - agg, err := IAMAggregate(ctx, aggCreator, existingIAM) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.IAMMemberChanged, member) - } -} - -func IAMMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, member *model.IAMMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-90lsw", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existingIAM) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.IAMMemberRemoved, member) - } -} - -func IDPConfigAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-MSn7d", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.IDPConfigAdded, idp) - if err != nil { - return nil, err - } - if idp.OIDCIDPConfig != nil { - return agg.AppendEvent(model.OIDCIDPConfigAdded, idp.OIDCIDPConfig) - } - return agg, nil - } -} - -func IDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Amc7s", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - var changes map[string]interface{} - for _, i := range existing.IDPs { - if i.IDPConfigID == idp.IDPConfigID { - changes = i.Changes(idp) - } - } - return agg.AppendEvent(model.IDPConfigChanged, changes) - } -} - -func IDPConfigRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig, provider *model.IDPProvider) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-se23g", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.IDPConfigRemoved, &model.IDPConfigID{IDPConfigID: idp.IDPConfigID}) - if err != nil { - return nil, err - } - if provider != nil { - return agg.AppendEvent(model.LoginPolicyIDPProviderCascadeRemoved, &model.IDPConfigID{IDPConfigID: idp.IDPConfigID}) - } - return agg, nil -} - -func IDPConfigDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slfi3", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.IDPConfigDeactivated, &model.IDPConfigID{IDPConfigID: idp.IDPConfigID}) - } -} - -func IDPConfigReactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, idp *model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.IDPConfigReactivated, &model.IDPConfigID{IDPConfigID: idp.IDPConfigID}) - } -} - -func OIDCIDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, config *model.OIDCIDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if config == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - var changes map[string]interface{} - for _, idp := range existing.IDPs { - if idp.IDPConfigID == config.IDPConfigID && idp.OIDCIDPConfig != nil { - changes = idp.OIDCIDPConfig.Changes(config) - } - } - if len(changes) <= 1 { - return nil, errors.ThrowPreconditionFailedf(nil, "EVENT-Cml9s", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.OIDCIDPConfigChanged, changes) - } -} - -func LabelPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LabelPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-e248Y", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - EventTypesFilter(model.LabelPolicyAdded). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingLabelPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LabelPolicyAdded, policy) - } -} - -func checkExistingLabelPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - for _, event := range events { - switch event.Type { - case model.LabelPolicyAdded: - return errors.ThrowPreconditionFailed(nil, "EVENT-KyLIK", "Errors.IAM.LabelPolicy.AlreadyExists") - } - } - return nil - } -} - -func LabelPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LabelPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-uP6HQ", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - changes := existing.DefaultLabelPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-hZE24", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.LabelPolicyChanged, changes) - } -} - -func LoginPolicyAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LoginPolicy) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smla8", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - EventTypesFilter(model.LoginPolicyAdded). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingLoginPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LoginPolicyAdded, policy) -} - -func LoginPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.LoginPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Mlco9", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - changes := existing.DefaultLoginPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smk8d", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.LoginPolicyChanged, changes) - } -} - -func LoginPolicyIDPProviderAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, provider *model.IDPProvider) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if provider == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sml9d", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingLoginPolicyIDPProviderValidation(provider.IDPConfigID) - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LoginPolicyIDPProviderAdded, provider) - } -} - -func LoginPolicyIDPProviderRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, provider *model.IDPProviderID) (*es_models.Aggregate, error) { - if provider == nil || existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sml9d", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.LoginPolicyIDPProviderRemoved, provider) -} - -func LoginPolicySecondFactorAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, mfa *model.MFA) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mfa == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4Gm9s", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingLoginPolicySecondFactorValidation(mfa.MFAType) - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LoginPolicySecondFactorAdded, mfa) - } -} - -func LoginPolicySecondFactorRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, mfa *model.MFA) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mfa == nil || existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-5Bm9s", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.LoginPolicySecondFactorRemoved, mfa) - } -} - -func LoginPolicyMultiFactorAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, mfa *model.MFA) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mfa == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4Gm9s", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingLoginPolicyMultiFactorValidation(mfa.MFAType) - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LoginPolicyMultiFactorAdded, mfa) - } -} - -func LoginPolicyMultiFactorRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, mfa *model.MFA) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mfa == nil || existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-6Mso9", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.LoginPolicyMultiFactorRemoved, mfa) - } -} - -func PasswordComplexityPolicyAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.PasswordComplexityPolicy) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smla8", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - EventTypesFilter(model.PasswordComplexityPolicyAdded). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingPasswordComplexityPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.PasswordComplexityPolicyAdded, policy) -} - -func PasswordComplexityPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.PasswordComplexityPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Mlco9", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - changes := existing.DefaultPasswordComplexityPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smk8d", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.PasswordComplexityPolicyChanged, changes) - } -} - -func PasswordAgePolicyAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.PasswordAgePolicy) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-T7sui", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - EventTypesFilter(model.PasswordAgePolicyAdded). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingPasswordAgePolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.PasswordAgePolicyAdded, policy) -} - -func PasswordAgePolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.PasswordAgePolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-3Gs0o", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - changes := existing.DefaultPasswordAgePolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-3Wdos", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.PasswordAgePolicyChanged, changes) - } -} - -func PasswordLockoutPolicyAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.PasswordLockoutPolicy) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-w5Tds", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - EventTypesFilter(model.PasswordLockoutPolicyAdded). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingPasswordLockoutPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.PasswordLockoutPolicyAdded, policy) -} - -func PasswordLockoutPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.PasswordLockoutPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-2D0fs", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - changes := existing.DefaultPasswordLockoutPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-7Hsk9", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.PasswordLockoutPolicyChanged, changes) - } -} - -func OrgIAMPolicyAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.OrgIAMPolicy) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-w5Tds", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - EventTypesFilter(model.OrgIAMPolicyAdded). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingOrgIAMPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.OrgIAMPolicyAdded, policy) -} - -func OrgIAMPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, policy *model.OrgIAMPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-2D0fs", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - changes := existing.DefaultOrgIAMPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-7Hsk9", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.OrgIAMPolicyChanged, changes) - } -} - -func checkExistingLoginPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - for _, event := range events { - switch event.Type { - case model.LoginPolicyAdded: - return errors.ThrowPreconditionFailed(nil, "EVENT-Ski9d", "Errors.IAM.LoginPolicy.AlreadyExists") - } - } - return nil - } -} - -func checkExistingPasswordComplexityPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - for _, event := range events { - switch event.Type { - case model.PasswordComplexityPolicyAdded: - return errors.ThrowPreconditionFailed(nil, "EVENT-Ski9d", "Errors.IAM.PasswordComplexityPolicy.AlreadyExists") - } - } - return nil - } -} - -func checkExistingPasswordAgePolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - for _, event := range events { - switch event.Type { - case model.PasswordAgePolicyAdded: - return errors.ThrowPreconditionFailed(nil, "EVENT-Ski9d", "Errors.IAM.PasswordAgePolicy.AlreadyExists") - } - } - return nil - } -} - -func checkExistingPasswordLockoutPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - for _, event := range events { - switch event.Type { - case model.PasswordLockoutPolicyAdded: - return errors.ThrowPreconditionFailed(nil, "EVENT-Ski9d", "Errors.IAM.PasswordLockoutPolicy.AlreadyExists") - } - } - return nil - } -} - -func checkExistingOrgIAMPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - for _, event := range events { - switch event.Type { - case model.OrgIAMPolicyAdded: - return errors.ThrowPreconditionFailed(nil, "EVENT-bSm8f", "Errors.IAM.OrgIAMPolicy.AlreadyExists") - } - } - return nil - } -} - -func checkExistingLoginPolicyIDPProviderValidation(idpConfigID string) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - idpConfigs := make([]*model.IDPConfig, 0) - idps := make([]*model.IDPProvider, 0) - for _, event := range events { - switch event.Type { - case model.IDPConfigAdded: - config := new(model.IDPConfig) - err := config.SetData(event) - if err != nil { - return err - } - idpConfigs = append(idpConfigs, config) - case model.IDPConfigRemoved: - config := new(model.IDPConfig) - err := config.SetData(event) - if err != nil { - return err - } - for i := len(idpConfigs) - 1; i >= 0; i-- { - if idpConfigs[i].IDPConfigID == config.IDPConfigID { - idpConfigs[i] = idpConfigs[len(idpConfigs)-1] - idpConfigs[len(idpConfigs)-1] = nil - idpConfigs = idpConfigs[:len(idpConfigs)-1] - break - } - } - case model.LoginPolicyIDPProviderAdded: - idp := new(model.IDPProvider) - err := idp.SetData(event) - if err != nil { - return err - } - idps = append(idps, idp) - case model.LoginPolicyIDPProviderRemoved: - idp := new(model.IDPProvider) - err := idp.SetData(event) - if err != nil { - return err - } - for i := len(idps) - 1; i >= 0; i-- { - if idps[i].IDPConfigID == idp.IDPConfigID { - idps[i] = idps[len(idps)-1] - idps[len(idps)-1] = nil - idps = idps[:len(idps)-1] - break - } - } - } - } - exists := false - for _, p := range idpConfigs { - if p.IDPConfigID == idpConfigID { - exists = true - } - } - if !exists { - return errors.ThrowPreconditionFailed(nil, "EVENT-Djlo9", "Errors.IAM.IdpNotExisting") - } - for _, p := range idps { - if p.IDPConfigID == idpConfigID { - return errors.ThrowPreconditionFailed(nil, "EVENT-us5Zw", "Errors.IAM.LoginPolicy.IdpProviderAlreadyExisting") - } - } - return nil - } -} - -func MailTemplateAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, template *model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if template == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ZCfDS", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - EventTypesFilter(model.MailTemplateAdded). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingMailTemplateValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.MailTemplateAdded, template) - } -} - -func checkExistingMailTemplateValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - for _, event := range events { - switch event.Type { - case model.MailTemplateAdded: - return errors.ThrowPreconditionFailed(nil, "EVENT-uKPiJ", "Errors.IAM.MailTemplate.AlreadyExists") - } - } - return nil - } -} - -func MailTemplateChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, template *model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if template == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-s4PVD", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - changes := existing.DefaultMailTemplate.Changes(template) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-hxxSm", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.MailTemplateChanged, changes) - } -} - -func MailTextAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.IAM, text *model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if text == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ZCfDS", "Errors.Internal") - } - agg, err := IAMAggregate(ctx, aggCreator, existing) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - EventTypesFilter(model.MailTextAdded). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingMailTextValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.MailTextAdded, text) - } -} - -func checkExistingMailTextValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - for _, event := range events { - switch event.Type { - case model.MailTextAdded: - return errors.ThrowPreconditionFailed(nil, "EVENT-ijzeq", "Errors.IAM.MailText.AlreadyExists") - } - } - return nil - } -} - -func MailTextChangedAggregate(aggCreator *es_models.AggregateCreator, existingIAM *model.IAM, text *model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if text == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-mgYpV", "Errors.Internal") - } - - agg, err := IAMAggregate(ctx, aggCreator, existingIAM) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.MailTextChanged, text) - } -} - -func checkExistingLoginPolicySecondFactorValidation(mfaType int32) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - mfas := make([]int32, 0) - for _, event := range events { - switch event.Type { - case model.LoginPolicySecondFactorAdded: - idp := new(model.MFA) - err := idp.SetData(event) - if err != nil { - return err - } - mfas = append(mfas, idp.MFAType) - case model.LoginPolicySecondFactorRemoved: - mfa := new(model.MFA) - err := mfa.SetData(event) - if err != nil { - return err - } - for i := len(mfas) - 1; i >= 0; i-- { - if mfas[i] == mfa.MFAType { - mfas[i] = mfas[len(mfas)-1] - mfas[len(mfas)-1] = 0 - mfas = mfas[:len(mfas)-1] - break - } - } - } - } - for _, m := range mfas { - if m == mfaType { - return errors.ThrowPreconditionFailed(nil, "EVENT-3vmHd", "Errors.IAM.LoginPolicy.MFA.AlreadyExisting") - } - } - return nil - } -} - -func checkExistingLoginPolicyMultiFactorValidation(mfaType int32) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - mfas := make([]int32, 0) - for _, event := range events { - switch event.Type { - case model.LoginPolicyMultiFactorAdded: - idp := new(model.MFA) - err := idp.SetData(event) - if err != nil { - return err - } - mfas = append(mfas, idp.MFAType) - case model.LoginPolicyMultiFactorRemoved: - mfa := new(model.MFA) - err := mfa.SetData(event) - if err != nil { - return err - } - for i := len(mfas) - 1; i >= 0; i-- { - if mfas[i] == mfa.MFAType { - mfas[i] = mfas[len(mfas)-1] - mfas[len(mfas)-1] = 0 - mfas = mfas[:len(mfas)-1] - break - } - } - } - } - for _, m := range mfas { - if m == mfaType { - return errors.ThrowPreconditionFailed(nil, "EVENT-6Hsj89", "Errors.IAM.LoginPolicy.MFA.AlreadyExisting") - } - } - return nil - } -} diff --git a/internal/iam/repository/eventsourcing/iam_test.go b/internal/iam/repository/eventsourcing/iam_test.go deleted file mode 100644 index bf3625dc8c..0000000000 --- a/internal/iam/repository/eventsourcing/iam_test.go +++ /dev/null @@ -1,2599 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - - "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" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" -) - -func TestSetUpStartedAggregate(t *testing.T) { - type args struct { - ctx context.Context - iam *model.IAM - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "setupstarted aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - iam: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMSetupStarted, - }, - }, - { - name: "iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - iam: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMSetupStarted, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IAMSetupStartedAggregate(tt.args.aggCreator, tt.args.iam)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestSetUpDoneAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "setup done aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMSetupDone, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMSetupDone, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IAMSetupDoneAggregate(tt.args.aggCreator, tt.args.existingIAM)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestGlobalOrgAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - orgID string - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "global org set aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - orgID: "orgID", - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.GlobalOrgSet, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - orgID: "orgID", - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "global org empty", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IAMSetGlobalOrgAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.orgID)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIamProjectAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - projectID string - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "iam project id set aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - projectID: "projectID", - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMProjectSet, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - projectID: "projectID", - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "project id empty", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IAMSetIamProjectAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.projectID)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIamMemberAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newMember *model.IAMMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "iammember added ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - newMember: &model.IAMMember{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, UserID: "UserID", Roles: []string{"Roles"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberAdded, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberAdded, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - newMember: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberAdded, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IAMMemberAddedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newMember)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc == nil && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIamMemberChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newMember *model.IAMMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "iammember changed ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - newMember: &model.IAMMember{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, UserID: "UserID", Roles: []string{"Roles"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberChanged, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - newMember: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IAMMemberChangedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newMember)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIamMemberRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newMember *model.IAMMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "iammember removed ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - newMember: &model.IAMMember{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, UserID: "UserID", Roles: []string{"Roles"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberRemoved, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberRemoved, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - newMember: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.IAMMemberRemoved, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IAMMemberRemovedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newMember)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.IAM - newConfig *model.IDPConfig - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add oidc idp configuration", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newConfig: &model.IDPConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCIDPConfig: &model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.IDPConfigAdded, model.OIDCIDPConfigAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newConfig: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.newConfig)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigurationChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newConfig *model.IDPConfig - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change idp configuration", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - IDPs: []*model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "IDPName"}, - }}, - newConfig: &model.IDPConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "NameChanged", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.IDPConfigChanged}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newConfig: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigChangedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newConfig)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigurationRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newConfig *model.IDPConfig - provider *model.IDPProvider - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove idp config", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - IDPs: []*model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name"}, - }}, - newConfig: &model.IDPConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.IDPConfigRemoved}, - }, - }, - { - name: "remove idp config with provider", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - IDPs: []*model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name"}, - }}, - newConfig: &model.IDPConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - provider: &model.IDPProvider{ - IDPConfigID: "IDPConfigID", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.IDPConfigRemoved, model.LoginPolicyIDPProviderCascadeRemoved}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newConfig: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingIAM, tt.args.newConfig, tt.args.provider) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigurationDeactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newConfig *model.IDPConfig - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate idp config", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - IDPs: []*model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name"}, - }}, - newConfig: &model.IDPConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.IDPConfigDeactivated}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newConfig: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigDeactivatedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newConfig)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigurationReactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newConfig *model.IDPConfig - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - IDPs: []*model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name"}, - }}, - newConfig: &model.IDPConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.IDPConfigReactivated}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newConfig: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigReactivatedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newConfig)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOIDCConfigChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newConfig *model.OIDCIDPConfig - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change oidc config", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - IDPs: []*model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name", OIDCIDPConfig: &model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}}, - }}, - newConfig: &model.OIDCIDPConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientIDChanged", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.OIDCIDPConfigChanged}, - }, - }, - { - name: "no changes", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - IDPs: []*model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name", OIDCIDPConfig: &model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}}, - }}, - newConfig: &model.OIDCIDPConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientID", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "oidc config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newConfig: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := OIDCIDPConfigChangedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newConfig)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLoginPolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.LoginPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add login polciy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - IDPs: []*model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name", OIDCIDPConfig: &model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}}, - }}, - newPolicy: &model.LoginPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AllowUsernamePassword: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "login policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLoginPolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.LoginPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultLoginPolicy: &model.LoginPolicy{ - AllowUsernamePassword: true, - }}, - newPolicy: &model.LoginPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AllowUsernamePassword: true, - AllowRegister: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyChanged}, - }, - }, - { - name: "no changes", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultLoginPolicy: &model.LoginPolicy{ - AllowUsernamePassword: true, - }}, - newPolicy: &model.LoginPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AllowUsernamePassword: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "login policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyChangedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLoginPolicyIdpProviderAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newProvider *model.IDPProvider - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add idp provider to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultLoginPolicy: &model.LoginPolicy{ - AllowUsernamePassword: true, - }}, - newProvider: &model.IDPProvider{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Type: int32(iam_model.IDPProviderTypeSystem), - IDPConfigID: "IDPConfigID", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyIDPProviderAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newProvider: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyIDPProviderAddedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newProvider)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLoginPolicyIdpProviderRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newProviderID *model.IDPProviderID - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove idp provider to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultLoginPolicy: &model.LoginPolicy{ - AllowUsernamePassword: true, - IDPProviders: []*model.IDPProvider{ - {IDPConfigID: "IDPConfigID", Type: int32(iam_model.IDPProviderTypeSystem)}, - }, - }}, - newProviderID: &model.IDPProviderID{ - IDPConfigID: "IDPConfigID", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyIDPProviderRemoved}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newProviderID: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyIDPProviderRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingIAM, tt.args.newProviderID) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLoginPolicySecondFactorAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newMFA *model.MFA - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add second factor to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultLoginPolicy: &model.LoginPolicy{ - AllowUsernamePassword: true, - }}, - newMFA: &model.MFA{ - MFAType: int32(iam_model.SecondFactorTypeOTP), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicySecondFactorAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mfa config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newMFA: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicySecondFactorAddedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newMFA)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLoginPolicySecondFactorRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - mfa *model.MFA - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove second factor to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultLoginPolicy: &model.LoginPolicy{ - AllowUsernamePassword: true, - SecondFactors: []int32{ - int32(iam_model.SecondFactorTypeOTP), - }, - }}, - mfa: &model.MFA{ - MFAType: int32(iam_model.SecondFactorTypeOTP), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicySecondFactorRemoved}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - mfa: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicySecondFactorRemovedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.mfa)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLoginPolicyMultiFactorAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newMFA *model.MFA - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mfa to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultLoginPolicy: &model.LoginPolicy{ - AllowUsernamePassword: true, - }}, - newMFA: &model.MFA{ - MFAType: int32(iam_model.MultiFactorTypeU2FWithPIN), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyMultiFactorAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mfa config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newMFA: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyMultiFactorAddedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newMFA)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLoginPolicyMultiFactorRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - mfa *model.MFA - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove mfa to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultLoginPolicy: &model.LoginPolicy{ - AllowUsernamePassword: true, - SecondFactors: []int32{ - int32(iam_model.SecondFactorTypeOTP), - }, - }}, - mfa: &model.MFA{ - MFAType: int32(iam_model.SecondFactorTypeOTP), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyMultiFactorRemoved}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - mfa: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyMultiFactorRemovedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.mfa)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPasswordComplexityPolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.PasswordComplexityPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password complexity policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID"}, - newPolicy: &model.PasswordComplexityPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MinLength: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordComplexityPolicyAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "complexity policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordComplexityPolicyAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPasswordComplexityPolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.PasswordComplexityPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password complexity policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultPasswordComplexityPolicy: &model.PasswordComplexityPolicy{ - MinLength: 10, - }}, - newPolicy: &model.PasswordComplexityPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MinLength: 5, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordComplexityPolicyChanged}, - }, - }, - { - name: "no changes", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultPasswordComplexityPolicy: &model.PasswordComplexityPolicy{ - MinLength: 10, - }}, - newPolicy: &model.PasswordComplexityPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MinLength: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "complexity policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordComplexityPolicyChangedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPasswordAgePolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.PasswordAgePolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password age policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID"}, - newPolicy: &model.PasswordAgePolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAgeDays: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordAgePolicyAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "age policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordAgePolicyAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPasswordAgePolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.PasswordAgePolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password age policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultPasswordAgePolicy: &model.PasswordAgePolicy{ - MaxAgeDays: 10, - }}, - newPolicy: &model.PasswordAgePolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAgeDays: 5, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordAgePolicyChanged}, - }, - }, - { - name: "no changes", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultPasswordAgePolicy: &model.PasswordAgePolicy{ - MaxAgeDays: 10, - }}, - newPolicy: &model.PasswordAgePolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAgeDays: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "age policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordAgePolicyChangedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPasswordLockoutPolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.PasswordLockoutPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password lockout policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID"}, - newPolicy: &model.PasswordLockoutPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAttempts: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordLockoutPolicyAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "lockout policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordLockoutPolicyAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPasswordLockoutPolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.PasswordLockoutPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password lockout policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultPasswordLockoutPolicy: &model.PasswordLockoutPolicy{ - MaxAttempts: 10, - }}, - newPolicy: &model.PasswordLockoutPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAttempts: 5, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordLockoutPolicyChanged}, - }, - }, - { - name: "no changes", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultPasswordLockoutPolicy: &model.PasswordLockoutPolicy{ - MaxAttempts: 10, - }}, - newPolicy: &model.PasswordLockoutPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAttempts: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "lockout policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordLockoutPolicyChangedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOrgIAMPolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.OrgIAMPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add org iam policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID"}, - newPolicy: &model.OrgIAMPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - UserLoginMustBeDomain: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.OrgIAMPolicyAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "lockout policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := OrgIAMPolicyAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOrgIAMPolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingIAM *model.IAM - newPolicy *model.OrgIAMPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change org iam policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultOrgIAMPolicy: &model.OrgIAMPolicy{ - UserLoginMustBeDomain: true, - }}, - newPolicy: &model.OrgIAMPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - UserLoginMustBeDomain: false, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.OrgIAMPolicyChanged}, - }, - }, - { - name: "no changes", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - IAMProjectID: "IAMProjectID", - DefaultOrgIAMPolicy: &model.OrgIAMPolicy{ - UserLoginMustBeDomain: true, - }}, - newPolicy: &model.OrgIAMPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - UserLoginMustBeDomain: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "org iam policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingIAM: &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, IAMProjectID: "IAMProjectID"}, - newPolicy: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := OrgIAMPolicyChangedAggregate(tt.args.aggCreator, tt.args.existingIAM, tt.args.newPolicy)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/management/repository/eventsourcing/eventstore/org.go b/internal/management/repository/eventsourcing/eventstore/org.go index 0bb7fca8c7..2729d8f398 100644 --- a/internal/management/repository/eventsourcing/eventstore/org.go +++ b/internal/management/repository/eventsourcing/eventstore/org.go @@ -11,9 +11,6 @@ import ( "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "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/view/model" iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" @@ -21,10 +18,8 @@ import ( global_model "github.com/caos/zitadel/internal/model" org_model "github.com/caos/zitadel/internal/org/model" org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" "github.com/caos/zitadel/internal/org/repository/view/model" "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" ) @@ -58,39 +53,6 @@ func (repo *OrgRepository) OrgByDomainGlobal(ctx context.Context, domain string) return repo.OrgByID(ctx, verifiedDomain.OrgID) } -func (repo *OrgRepository) CreateOrg(ctx context.Context, name string) (*org_model.Org, error) { - org, aggregates, err := repo.OrgEventstore.PrepareCreateOrg(ctx, &org_model.Org{Name: name}, nil) - if err != nil { - return nil, err - } - - member := org_model.NewOrgMemberWithRoles(org.AggregateID, authz.GetCtxData(ctx).UserID, orgOwnerRole) - _, memberAggregate, err := repo.OrgEventstore.PrepareAddOrgMember(ctx, member, org.AggregateID) - if err != nil { - return nil, err - } - aggregates = append(aggregates, memberAggregate) - - err = sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, org.AppendEvents, aggregates...) - if err != nil { - return nil, err - } - - return org_es_model.OrgToModel(org), nil -} - -func (repo *OrgRepository) UpdateOrg(ctx context.Context, org *org_model.Org) (*org_model.Org, error) { - return nil, errors.ThrowUnimplemented(nil, "EVENT-RkurR", "not implemented") -} - -func (repo *OrgRepository) DeactivateOrg(ctx context.Context, id string) (*org_model.Org, error) { - return repo.OrgEventstore.DeactivateOrg(ctx, id) -} - -func (repo *OrgRepository) ReactivateOrg(ctx context.Context, id string) (*org_model.Org, error) { - return repo.OrgEventstore.ReactivateOrg(ctx, id) -} - func (repo *OrgRepository) GetMyOrgIamPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) { policy, err := repo.View.OrgIAMPolicyByAggregateID(authz.GetCtxData(ctx).OrgID) if errors.IsNotFound(err) { @@ -128,38 +90,6 @@ func (repo *OrgRepository) SearchMyOrgDomains(ctx context.Context, request *org_ return result, nil } -func (repo *OrgRepository) AddMyOrgDomain(ctx context.Context, domain *org_model.OrgDomain) (*org_model.OrgDomain, error) { - domain.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddOrgDomain(ctx, domain) -} - -func (repo *OrgRepository) GenerateMyOrgDomainValidation(ctx context.Context, domain *org_model.OrgDomain) (string, string, error) { - domain.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.GenerateOrgDomainValidation(ctx, domain) -} - -func (repo *OrgRepository) ValidateMyOrgDomain(ctx context.Context, domain *org_model.OrgDomain) error { - domain.AggregateID = authz.GetCtxData(ctx).OrgID - users := func(ctx context.Context, domain string) ([]*es_models.Aggregate, error) { - userIDs, err := repo.View.UserIDsByDomain(domain) - if err != nil { - return nil, err - } - return repo.UserEvents.PrepareDomainClaimed(ctx, userIDs) - } - return repo.OrgEventstore.ValidateOrgDomain(ctx, domain, users) -} - -func (repo *OrgRepository) SetMyPrimaryOrgDomain(ctx context.Context, domain *org_model.OrgDomain) error { - domain.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.SetPrimaryOrgDomain(ctx, domain) -} - -func (repo *OrgRepository) RemoveMyOrgDomain(ctx context.Context, domain string) error { - d := org_model.NewOrgDomain(authz.GetCtxData(ctx).OrgID, domain) - return repo.OrgEventstore.RemoveOrgDomain(ctx, d) -} - func (repo *OrgRepository) OrgChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*org_model.OrgChanges, error) { changes, err := repo.OrgEventstore.OrgChanges(ctx, id, lastSequence, limit, sortAscending) if err != nil { @@ -188,21 +118,6 @@ func (repo *OrgRepository) OrgMemberByID(ctx context.Context, orgID, userID stri return model.OrgMemberToModel(member), nil } -func (repo *OrgRepository) AddMyOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) { - member.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddOrgMember(ctx, member) -} - -func (repo *OrgRepository) ChangeMyOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) { - member.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangeOrgMember(ctx, member) -} - -func (repo *OrgRepository) RemoveMyOrgMember(ctx context.Context, userID string) error { - member := org_model.NewOrgMember(authz.GetCtxData(ctx).OrgID, userID) - return repo.OrgEventstore.RemoveOrgMember(ctx, member) -} - func (repo *OrgRepository) SearchMyOrgMembers(ctx context.Context, request *org_model.OrgMemberSearchRequest) (*org_model.OrgMemberSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) request.Queries[len(request.Queries)-1] = &org_model.OrgMemberSearchQuery{Key: org_model.OrgMemberSearchKeyOrgID, Method: global_model.SearchMethodEquals, Value: authz.GetCtxData(ctx).OrgID} @@ -242,52 +157,6 @@ func (repo *OrgRepository) IDPConfigByID(ctx context.Context, idpConfigID string } return iam_view_model.IDPConfigViewToModel(idp), nil } -func (repo *OrgRepository) AddOIDCIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { - idp.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddIDPConfig(ctx, idp) -} - -func (repo *OrgRepository) ChangeIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { - idp.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangeIDPConfig(ctx, idp) -} - -func (repo *OrgRepository) DeactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) { - return repo.OrgEventstore.DeactivateIDPConfig(ctx, authz.GetCtxData(ctx).OrgID, idpConfigID) -} - -func (repo *OrgRepository) ReactivateIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) { - return repo.OrgEventstore.ReactivateIDPConfig(ctx, authz.GetCtxData(ctx).OrgID, idpConfigID) -} - -func (repo *OrgRepository) RemoveIDPConfig(ctx context.Context, idpConfigID string) error { - aggregates := make([]*es_models.Aggregate, 0) - idp := iam_model.NewIDPConfig(authz.GetCtxData(ctx).OrgID, idpConfigID) - _, agg, err := repo.OrgEventstore.PrepareRemoveIDPConfig(ctx, idp) - if err != nil { - - } - aggregates = append(aggregates, agg) - externalIDPs, err := repo.View.ExternalIDPsByIDPConfigID(idpConfigID) - if err != nil { - return err - } - for _, externalIDP := range externalIDPs { - idpRemove := &usr_model.ExternalIDP{ObjectRoot: es_models.ObjectRoot{AggregateID: externalIDP.UserID}, IDPConfigID: externalIDP.IDPConfigID, UserID: externalIDP.ExternalUserID} - idpAgg := make([]*es_models.Aggregate, 0) - _, idpAgg, err = repo.UserEvents.PrepareRemoveExternalIDP(ctx, idpRemove, true) - if err != nil { - return err - } - aggregates = append(aggregates, idpAgg...) - } - return sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, nil, aggregates...) -} - -func (repo *OrgRepository) ChangeOIDCIDPConfig(ctx context.Context, oidcConfig *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) { - oidcConfig.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangeIDPOIDCConfig(ctx, oidcConfig) -} func (repo *OrgRepository) SearchIDPConfigs(ctx context.Context, request *iam_model.IDPConfigSearchRequest) (*iam_model.IDPConfigSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) @@ -327,16 +196,6 @@ func (repo *OrgRepository) GetLabelPolicy(ctx context.Context) (*iam_model.Label return iam_es_model.LabelPolicyViewToModel(policy), err } -func (repo *OrgRepository) AddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddLabelPolicy(ctx, policy) -} - -func (repo *OrgRepository) ChangeLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangeLabelPolicy(ctx, policy) -} - func (repo *OrgRepository) GetLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) { policy, viewErr := repo.View.LoginPolicyByAggregateID(authz.GetCtxData(ctx).OrgID) if viewErr != nil && !errors.IsNotFound(viewErr) { @@ -396,23 +255,6 @@ func (repo *OrgRepository) GetDefaultLoginPolicy(ctx context.Context) (*iam_mode return iam_es_model.LoginPolicyViewToModel(policy), nil } -func (repo *OrgRepository) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddLoginPolicy(ctx, policy) -} - -func (repo *OrgRepository) ChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangeLoginPolicy(ctx, policy) -} - -func (repo *OrgRepository) RemoveLoginPolicy(ctx context.Context) error { - policy := &iam_model.LoginPolicy{ObjectRoot: models.ObjectRoot{ - AggregateID: authz.GetCtxData(ctx).OrgID, - }} - return repo.OrgEventstore.RemoveLoginPolicy(ctx, policy) -} - func (repo *OrgRepository) SearchIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) { policy, err := repo.View.LoginPolicyByAggregateID(authz.GetCtxData(ctx).OrgID) if err != nil { @@ -443,35 +285,6 @@ func (repo *OrgRepository) SearchIDPProviders(ctx context.Context, request *iam_ return result, nil } -func (repo *OrgRepository) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) { - provider.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddIDPProviderToLoginPolicy(ctx, provider) -} - -func (repo *OrgRepository) RemoveIDPProviderFromIdpProvider(ctx context.Context, provider *iam_model.IDPProvider) error { - aggregates := make([]*es_models.Aggregate, 0) - provider.AggregateID = authz.GetCtxData(ctx).OrgID - _, agg, err := repo.OrgEventstore.PrepareRemoveIDPProviderFromLoginPolicy(ctx, provider, false) - if err != nil { - return err - } - aggregates = append(aggregates, agg) - externalIDPs, err := repo.View.ExternalIDPsByIDPConfigID(provider.IDPConfigID) - if err != nil { - return err - } - for _, externalIDP := range externalIDPs { - idpRemove := &usr_model.ExternalIDP{ObjectRoot: es_models.ObjectRoot{AggregateID: externalIDP.UserID}, IDPConfigID: externalIDP.IDPConfigID, UserID: externalIDP.ExternalUserID} - idpAgg := make([]*es_models.Aggregate, 0) - _, idpAgg, err = repo.UserEvents.PrepareRemoveExternalIDP(ctx, idpRemove, true) - if err != nil { - return err - } - aggregates = append(aggregates, idpAgg...) - } - return sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, nil, aggregates...) -} - func (repo *OrgRepository) SearchSecondFactors(ctx context.Context) (*iam_model.SecondFactorsSearchResponse, error) { policy, err := repo.GetLoginPolicy(ctx) if err != nil { @@ -483,14 +296,6 @@ func (repo *OrgRepository) SearchSecondFactors(ctx context.Context) (*iam_model. }, nil } -func (repo *OrgRepository) AddSecondFactorToLoginPolicy(ctx context.Context, mfa iam_model.SecondFactorType) (iam_model.SecondFactorType, error) { - return repo.OrgEventstore.AddSecondFactorToLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, mfa) -} - -func (repo *OrgRepository) RemoveSecondFactorFromLoginPolicy(ctx context.Context, mfa iam_model.SecondFactorType) error { - return repo.OrgEventstore.RemoveSecondFactorFromLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, mfa) -} - func (repo *OrgRepository) SearchMultiFactors(ctx context.Context) (*iam_model.MultiFactorsSearchResponse, error) { policy, err := repo.GetLoginPolicy(ctx) if err != nil { @@ -502,14 +307,6 @@ func (repo *OrgRepository) SearchMultiFactors(ctx context.Context) (*iam_model.M }, nil } -func (repo *OrgRepository) AddMultiFactorToLoginPolicy(ctx context.Context, mfa iam_model.MultiFactorType) (iam_model.MultiFactorType, error) { - return repo.OrgEventstore.AddMultiFactorToLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, mfa) -} - -func (repo *OrgRepository) RemoveMultiFactorFromLoginPolicy(ctx context.Context, mfa iam_model.MultiFactorType) error { - return repo.OrgEventstore.RemoveMultiFactorFromLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, mfa) -} - func (repo *OrgRepository) GetPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) { policy, viewErr := repo.View.PasswordComplexityPolicyByAggregateID(authz.GetCtxData(ctx).OrgID) if viewErr != nil && !errors.IsNotFound(viewErr) { @@ -561,23 +358,6 @@ func (repo *OrgRepository) GetDefaultPasswordComplexityPolicy(ctx context.Contex return iam_es_model.PasswordComplexityViewToModel(policy), nil } -func (repo *OrgRepository) AddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddPasswordComplexityPolicy(ctx, policy) -} - -func (repo *OrgRepository) ChangePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangePasswordComplexityPolicy(ctx, policy) -} - -func (repo *OrgRepository) RemovePasswordComplexityPolicy(ctx context.Context) error { - policy := &iam_model.PasswordComplexityPolicy{ObjectRoot: models.ObjectRoot{ - AggregateID: authz.GetCtxData(ctx).OrgID, - }} - return repo.OrgEventstore.RemovePasswordComplexityPolicy(ctx, policy) -} - func (repo *OrgRepository) GetPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error) { policy, viewErr := repo.View.PasswordAgePolicyByAggregateID(authz.GetCtxData(ctx).OrgID) if viewErr != nil && !errors.IsNotFound(viewErr) { @@ -629,23 +409,6 @@ func (repo *OrgRepository) GetDefaultPasswordAgePolicy(ctx context.Context) (*ia return iam_es_model.PasswordAgeViewToModel(policy), nil } -func (repo *OrgRepository) AddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddPasswordAgePolicy(ctx, policy) -} - -func (repo *OrgRepository) ChangePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangePasswordAgePolicy(ctx, policy) -} - -func (repo *OrgRepository) RemovePasswordAgePolicy(ctx context.Context) error { - policy := &iam_model.PasswordAgePolicy{ObjectRoot: models.ObjectRoot{ - AggregateID: authz.GetCtxData(ctx).OrgID, - }} - return repo.OrgEventstore.RemovePasswordAgePolicy(ctx, policy) -} - func (repo *OrgRepository) GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) { policy, viewErr := repo.View.PasswordLockoutPolicyByAggregateID(authz.GetCtxData(ctx).OrgID) if viewErr != nil && !errors.IsNotFound(viewErr) { @@ -697,23 +460,6 @@ func (repo *OrgRepository) GetDefaultPasswordLockoutPolicy(ctx context.Context) return iam_es_model.PasswordLockoutViewToModel(policy), nil } -func (repo *OrgRepository) AddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddPasswordLockoutPolicy(ctx, policy) -} - -func (repo *OrgRepository) ChangePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - policy.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangePasswordLockoutPolicy(ctx, policy) -} - -func (repo *OrgRepository) RemovePasswordLockoutPolicy(ctx context.Context) error { - policy := &iam_model.PasswordLockoutPolicy{ObjectRoot: models.ObjectRoot{ - AggregateID: authz.GetCtxData(ctx).OrgID, - }} - return repo.OrgEventstore.RemovePasswordLockoutPolicy(ctx, policy) -} - func (repo *OrgRepository) GetDefaultMailTemplate(ctx context.Context) (*iam_model.MailTemplateView, error) { template, err := repo.View.MailTemplateByAggregateID(repo.SystemDefaults.IamID) if err != nil { @@ -761,18 +507,3 @@ func (repo *OrgRepository) GetMailTexts(ctx context.Context) (*iam_model.MailTex } return iam_es_model.MailTextsViewToModel(texts, defaultIn), err } - -func (repo *OrgRepository) AddMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { - text.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.AddMailText(ctx, text) -} - -func (repo *OrgRepository) ChangeMailText(ctx context.Context, text *iam_model.MailText) (*iam_model.MailText, error) { - text.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.ChangeMailText(ctx, text) -} - -func (repo *OrgRepository) RemoveMailText(ctx context.Context, text *iam_model.MailText) error { - text.AggregateID = authz.GetCtxData(ctx).OrgID - return repo.OrgEventstore.RemoveMailText(ctx, text) -} diff --git a/internal/management/repository/eventsourcing/eventstore/project.go b/internal/management/repository/eventsourcing/eventstore/project.go index 0324efdbb5..feed5543ea 100644 --- a/internal/management/repository/eventsourcing/eventstore/project.go +++ b/internal/management/repository/eventsourcing/eventstore/project.go @@ -18,19 +18,17 @@ import ( proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing" "github.com/caos/zitadel/internal/project/repository/view/model" usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" - usr_grant_event "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing" ) type ProjectRepo struct { es_int.Eventstore - SearchLimit uint64 - ProjectEvents *proj_event.ProjectEventstore - UserGrantEvents *usr_grant_event.UserGrantEventStore - UserEvents *usr_event.UserEventstore - IAMEvents *iam_event.IAMEventstore - View *view.View - Roles []string - IAMID string + SearchLimit uint64 + ProjectEvents *proj_event.ProjectEventstore + UserEvents *usr_event.UserEventstore + IAMEvents *iam_event.IAMEventstore + View *view.View + Roles []string + IAMID string } func (repo *ProjectRepo) ProjectByID(ctx context.Context, id string) (*proj_model.ProjectView, error) { @@ -332,18 +330,10 @@ func (repo *ProjectRepo) RemoveClientKey(ctx context.Context, projectID, applica return repo.ProjectEvents.RemoveApplicationKey(ctx, projectID, applicationID, keyID) } -func (repo *ProjectRepo) ChangeOIDCConfig(ctx context.Context, config *proj_model.OIDCConfig) (*proj_model.OIDCConfig, error) { - return repo.ProjectEvents.ChangeOIDCConfig(ctx, config) -} - func (repo *ProjectRepo) ChangeAPIConfig(ctx context.Context, config *proj_model.APIConfig) (*proj_model.APIConfig, error) { return repo.ProjectEvents.ChangeAPIConfig(ctx, config) } -func (repo *ProjectRepo) ChangeOIDConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.OIDCConfig, error) { - return repo.ProjectEvents.ChangeOIDCConfigSecret(ctx, projectID, appID) -} - func (repo *ProjectRepo) ChangeAPIConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.APIConfig, error) { return repo.ProjectEvents.ChangeAPIConfigSecret(ctx, projectID, appID) } diff --git a/internal/management/repository/eventsourcing/eventstore/user.go b/internal/management/repository/eventsourcing/eventstore/user.go index 7588e23f89..b9d51e3796 100644 --- a/internal/management/repository/eventsourcing/eventstore/user.go +++ b/internal/management/repository/eventsourcing/eventstore/user.go @@ -18,18 +18,16 @@ import ( usr_model "github.com/caos/zitadel/internal/user/model" usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" "github.com/caos/zitadel/internal/user/repository/view/model" - usr_grant_event "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing" "github.com/caos/zitadel/internal/view/repository" ) type UserRepo struct { es_int.Eventstore - SearchLimit uint64 - UserEvents *usr_event.UserEventstore - OrgEvents *org_event.OrgEventstore - UserGrantEvents *usr_grant_event.UserGrantEventStore - View *view.View - SystemDefaults systemdefaults.SystemDefaults + SearchLimit uint64 + UserEvents *usr_event.UserEventstore + OrgEvents *org_event.OrgEventstore + View *view.View + SystemDefaults systemdefaults.SystemDefaults } func (repo *UserRepo) UserByID(ctx context.Context, id string) (*usr_model.UserView, error) { diff --git a/internal/management/repository/eventsourcing/eventstore/user_grant.go b/internal/management/repository/eventsourcing/eventstore/user_grant.go index 0642587167..23059845bb 100644 --- a/internal/management/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/management/repository/eventsourcing/eventstore/user_grant.go @@ -8,15 +8,13 @@ import ( "github.com/caos/zitadel/internal/management/repository/eventsourcing/view" global_model "github.com/caos/zitadel/internal/model" grant_model "github.com/caos/zitadel/internal/usergrant/model" - grant_event "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing" "github.com/caos/zitadel/internal/usergrant/repository/view/model" "github.com/caos/zitadel/internal/view/repository" ) type UserGrantRepo struct { - SearchLimit uint64 - UserGrantEvents *grant_event.UserGrantEventStore - View *view.View + SearchLimit uint64 + View *view.View } func (repo *UserGrantRepo) UserGrantByID(ctx context.Context, grantID string) (*grant_model.UserGrantView, error) { diff --git a/internal/management/repository/eventsourcing/repository.go b/internal/management/repository/eventsourcing/repository.go index d82df93f6a..d20a01fb3d 100644 --- a/internal/management/repository/eventsourcing/repository.go +++ b/internal/management/repository/eventsourcing/repository.go @@ -17,7 +17,6 @@ import ( es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing" 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" ) type Config struct { @@ -68,10 +67,6 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe if err != nil { return nil, err } - usergrant, err := es_grant.StartUserGrant(es_grant.UserGrantConfig{ - Eventstore: es, - Cache: conf.Eventstore.Cache, - }) if err != nil { return nil, err } @@ -94,9 +89,9 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe return &EsRepository{ spooler: spool, OrgRepository: eventstore.OrgRepository{conf.SearchLimit, org, user, iam, view, roles, systemDefaults}, - ProjectRepo: eventstore.ProjectRepo{es, conf.SearchLimit, project, usergrant, user, iam, view, roles, systemDefaults.IamID}, - UserRepo: eventstore.UserRepo{es, conf.SearchLimit, user, org, usergrant, view, systemDefaults}, - UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, usergrant, view}, + ProjectRepo: eventstore.ProjectRepo{es, conf.SearchLimit, project, user, iam, view, roles, systemDefaults.IamID}, + UserRepo: eventstore.UserRepo{es, conf.SearchLimit, user, org, view, systemDefaults}, + UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, view}, IAMRepository: eventstore.IAMRepository{ IAMV2Query: iamV2Query, }, diff --git a/internal/management/repository/org.go b/internal/management/repository/org.go index f53b69443b..1707db76bd 100644 --- a/internal/management/repository/org.go +++ b/internal/management/repository/org.go @@ -45,7 +45,4 @@ type OrgRepository interface { GetDefaultMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) GetMailTexts(ctx context.Context) (*iam_model.MailTextsView, error) - AddMailText(ctx context.Context, mailText *iam_model.MailText) (*iam_model.MailText, error) - ChangeMailText(ctx context.Context, mailText *iam_model.MailText) (*iam_model.MailText, error) - RemoveMailText(ctx context.Context, mailText *iam_model.MailText) error } diff --git a/internal/management/repository/project.go b/internal/management/repository/project.go index da72adeb7d..0fbed94ba3 100644 --- a/internal/management/repository/project.go +++ b/internal/management/repository/project.go @@ -26,7 +26,6 @@ type ProjectRepository interface { ApplicationByID(ctx context.Context, projectID, appID string) (*model.ApplicationView, error) AddApplication(ctx context.Context, app *model.Application) (*model.Application, error) ChangeAPIConfig(ctx context.Context, config *model.APIConfig) (*model.APIConfig, error) - ChangeOIDConfigSecret(ctx context.Context, projectID, appID string) (*model.OIDCConfig, error) ChangeAPIConfigSecret(ctx context.Context, projectID, appID string) (*model.APIConfig, error) SearchApplications(ctx context.Context, request *model.ApplicationSearchRequest) (*model.ApplicationSearchResponse, error) ApplicationChanges(ctx context.Context, id string, secId string, lastSequence uint64, limit uint64, sortAscending bool) (*model.ApplicationChanges, error) diff --git a/internal/org/repository/eventsourcing/eventstore.go b/internal/org/repository/eventsourcing/eventstore.go index 8266c27a0b..575a5beee2 100644 --- a/internal/org/repository/eventsourcing/eventstore.go +++ b/internal/org/repository/eventsourcing/eventstore.go @@ -13,7 +13,6 @@ import ( es_models "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/id" org_model "github.com/caos/zitadel/internal/org/model" "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" @@ -57,34 +56,6 @@ func StartOrg(conf OrgConfig, defaults systemdefaults.SystemDefaults) *OrgEvents } } -func (es *OrgEventstore) PrepareCreateOrg(ctx context.Context, orgModel *org_model.Org, users func(context.Context, string) ([]*es_models.Aggregate, error)) (*model.Org, []*es_models.Aggregate, error) { - if orgModel == nil || !orgModel.IsValid() { - return nil, nil, errors.ThrowInvalidArgument(nil, "EVENT-OeLSk", "Errors.Org.Invalid") - } - orgModel.AddIAMDomain(es.IAMDomain) - - id, err := es.idGenerator.Next() - if err != nil { - return nil, nil, errors.ThrowInternal(err, "EVENT-OwciI", "Errors.Internal") - } - orgModel.AggregateID = id - org := model.OrgFromModel(orgModel) - - aggregates, err := orgCreatedAggregates(ctx, es.AggregateCreator(), org, users) - - return org, aggregates, err -} - -func (es *OrgEventstore) CreateOrg(ctx context.Context, orgModel *org_model.Org, users func(context.Context, string) ([]*es_models.Aggregate, error)) (*org_model.Org, error) { - org, aggregates, err := es.PrepareCreateOrg(ctx, orgModel, users) - err = es_sdk.PushAggregates(ctx, es.PushAggregates, org.AppendEvents, aggregates...) - if err != nil { - return nil, err - } - - return model.OrgToModel(org), nil -} - func (es *OrgEventstore) OrgByID(ctx context.Context, org *org_model.Org) (*org_model.Org, error) { if org == nil { return nil, errors.ThrowInvalidArgument(nil, "EVENT-gQTYP", "Errors.Org.Empty") @@ -140,190 +111,6 @@ func isUniqueValidation(unique *bool) func(events ...*es_models.Event) error { } } -func (es *OrgEventstore) DeactivateOrg(ctx context.Context, orgID string) (*org_model.Org, error) { - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID)) - if err != nil { - return nil, errors.ThrowInvalidArgument(nil, "EVENT-oL9nT", "Errors.Org.NotFound") - } - org := model.OrgFromModel(existingOrg) - - aggregate := orgDeactivateAggregate(es.AggregateCreator(), org) - err = es_sdk.Push(ctx, es.PushAggregates, org.AppendEvents, aggregate) - if err != nil { - return nil, err - } - - return model.OrgToModel(org), nil -} - -func (es *OrgEventstore) ReactivateOrg(ctx context.Context, orgID string) (*org_model.Org, error) { - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID)) - if err != nil { - return nil, errors.ThrowInvalidArgument(nil, "EVENT-oL9nT", "Errors.Org.Empty") - } - org := model.OrgFromModel(existingOrg) - - aggregate := orgReactivateAggregate(es.AggregateCreator(), org) - err = es_sdk.Push(ctx, es.PushAggregates, org.AppendEvents, aggregate) - if err != nil { - return nil, err - - } - return model.OrgToModel(org), nil -} - -func (es *OrgEventstore) AddOrgDomain(ctx context.Context, domain *org_model.OrgDomain) (*org_model.OrgDomain, error) { - if domain == nil || !domain.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-8sFJW", "Errors.Org.InvalidDomain") - } - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID)) - if err != nil { - return nil, err - } - repoOrg := model.OrgFromModel(existingOrg) - repoDomain := model.OrgDomainFromModel(domain) - aggregate := OrgDomainAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoDomain) - - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, aggregate) - if err != nil { - return nil, err - } - - if _, d := model.GetDomain(repoOrg.Domains, domain.Domain); d != nil { - return model.OrgDomainToModel(d), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-ISOP0", "Errors.Internal") -} - -func (es *OrgEventstore) GenerateOrgDomainValidation(ctx context.Context, domain *org_model.OrgDomain) (string, string, error) { - if domain == nil || !domain.IsValid() { - return "", "", errors.ThrowPreconditionFailed(nil, "EVENT-R24hb", "Errors.Org.InvalidDomain") - } - checkType, ok := domain.ValidationType.CheckType() - if !ok { - return "", "", errors.ThrowPreconditionFailed(nil, "EVENT-Gsw31", "Errors.Org.DomainVerificationTypeInvalid") - } - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID)) - if err != nil { - return "", "", err - } - _, d := existingOrg.GetDomain(domain) - if d == nil { - return "", "", errors.ThrowPreconditionFailed(nil, "EVENT-AGD31", "Errors.Org.DomainNotOnOrg") - } - if d.Verified { - return "", "", errors.ThrowPreconditionFailed(nil, "EVENT-HGw21", "Errors.Org.DomainAlreadyVerified") - } - token, err := domain.GenerateVerificationCode(es.verificationGenerator) - if err != nil { - return "", "", err - } - url, err := http_utils.TokenUrl(domain.Domain, token, checkType) - if err != nil { - return "", "", errors.ThrowPreconditionFailed(err, "EVENT-Bae21", "Errors.Org.DomainVerificationTypeInvalid") - } - - repoOrg := model.OrgFromModel(existingOrg) - repoDomain := model.OrgDomainFromModel(domain) - aggregate := OrgDomainValidationGeneratedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoDomain) - - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, aggregate) - if err != nil { - return "", "", err - } - return token, url, err -} - -func (es *OrgEventstore) ValidateOrgDomain(ctx context.Context, domain *org_model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) error { - if domain == nil || !domain.IsValid() { - return errors.ThrowPreconditionFailed(nil, "EVENT-R24hb", "Errors.Org.InvalidDomain") - } - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID)) - if err != nil { - return err - } - _, existingDomain := existingOrg.GetDomain(domain) - if existingDomain == nil { - return errors.ThrowPreconditionFailed(nil, "EVENT-Sjdi3", "Errors.Org.DomainNotOnOrg") - } - if existingDomain.Verified { - return errors.ThrowPreconditionFailed(nil, "EVENT-4gT342", "Errors.Org.DomainAlreadyVerified") - } - if existingDomain.ValidationCode == nil || existingDomain.ValidationType == org_model.OrgDomainValidationTypeUnspecified { - return errors.ThrowPreconditionFailed(nil, "EVENT-SFBB3", "Errors.Org.DomainVerificationMissing") - } - validationCode, err := crypto.DecryptString(existingDomain.ValidationCode, es.verificationAlgorithm) - if err != nil { - return err - } - repoOrg := model.OrgFromModel(existingOrg) - repoDomain := model.OrgDomainFromModel(domain) - checkType, _ := existingDomain.ValidationType.CheckType() - err = es.verificationValidator(existingDomain.Domain, validationCode, validationCode, checkType) - if err == nil { - orgAggregates, err := OrgDomainVerifiedAggregate(ctx, es.Eventstore.AggregateCreator(), repoOrg, repoDomain, users) - if err != nil { - return err - } - return es_sdk.PushAggregates(ctx, es.PushAggregates, repoOrg.AppendEvents, orgAggregates...) - } - if err := es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, OrgDomainValidationFailedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoDomain)); err != nil { - return err - } - return errors.ThrowInvalidArgument(err, "EVENT-GH3s", "Errors.Org.DomainVerificationFailed") -} - -func (es *OrgEventstore) SetPrimaryOrgDomain(ctx context.Context, domain *org_model.OrgDomain) error { - if domain == nil || !domain.IsValid() { - return errors.ThrowPreconditionFailed(nil, "EVENT-SsDG2", "Errors.Org.InvalidDomain") - } - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID)) - if err != nil { - return err - } - _, existingDomain := existingOrg.GetDomain(domain) - if existingDomain == nil { - return errors.ThrowPreconditionFailed(nil, "EVENT-GDfA3", "Errors.Org.DomainNotOnOrg") - } - if !existingDomain.Verified { - return errors.ThrowPreconditionFailed(nil, "EVENT-Ggd32", "Errors.Org.DomainNotVerified") - } - repoOrg := model.OrgFromModel(existingOrg) - repoDomain := model.OrgDomainFromModel(domain) - if err := es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, OrgDomainSetPrimaryAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoDomain)); err != nil { - return err - } - return nil -} - -func (es *OrgEventstore) RemoveOrgDomain(ctx context.Context, domain *org_model.OrgDomain) error { - if domain.Domain == "" { - return errors.ThrowPreconditionFailed(nil, "EVENT-SJsK3", "Errors.Org.DomainMissing") - } - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(domain.AggregateID)) - if err != nil { - return err - } - _, existingDomain := existingOrg.GetDomain(domain) - if existingDomain == nil { - return errors.ThrowPreconditionFailed(nil, "EVENT-Sjdi3", "Errors.Org.DomainNotOnOrg") - } - if existingDomain.Primary { - return errors.ThrowPreconditionFailed(nil, "EVENT-Sjdi3", "Errors.Org.PrimaryDomainNotDeletable") - } - repoOrg := model.OrgFromModel(existingOrg) - repoDomain := model.OrgDomainFromModel(domain) - orgAggregates, err := OrgDomainRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoOrg, repoDomain) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoOrg.AppendEvents, orgAggregates...) - if err != nil { - return err - } - return nil -} - func (es *OrgEventstore) OrgChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*org_model.OrgChanges, error) { query := ChangesQuery(id, lastSequence, limit, sortAscending) @@ -381,97 +168,6 @@ func ChangesQuery(orgID string, latestSequence, limit uint64, sortAscending bool return query } -func (es *OrgEventstore) OrgMemberByIDs(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) { - if member == nil || member.UserID == "" || member.AggregateID == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ld93d", "Errors.Org.MemberIDMissing") - } - - org, err := es.OrgByID(ctx, &org_model.Org{ObjectRoot: member.ObjectRoot, Members: []*org_model.OrgMember{member}}) - if err != nil { - return nil, err - } - - for _, currentMember := range org.Members { - if currentMember.UserID == member.UserID { - return currentMember, nil - } - } - - return nil, errors.ThrowNotFound(nil, "EVENT-SXji6", "Errors.Org.MemberNotFound") -} - -func (es *OrgEventstore) PrepareAddOrgMember(ctx context.Context, member *org_model.OrgMember, resourceOwner string) (*model.OrgMember, *es_models.Aggregate, error) { - if member == nil || !member.IsValid() { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-jRFLz", "Errors.Org.InvalidMember") - } - - repoMember := model.OrgMemberFromModel(member) - addAggregate, err := orgMemberAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoMember, resourceOwner) - - return repoMember, addAggregate, err -} - -func (es *OrgEventstore) AddOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) { - repoMember, addAggregate, err := es.PrepareAddOrgMember(ctx, member, "") - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoMember.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - - return model.OrgMemberToModel(repoMember), nil -} - -func (es *OrgEventstore) ChangeOrgMember(ctx context.Context, member *org_model.OrgMember) (*org_model.OrgMember, error) { - if member == nil || !member.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ara6l", "Errors.Org.InvalidMember") - } - - org, err := es.OrgByID(ctx, &org_model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: member.AggregateID, Sequence: member.Sequence}}) - if err != nil { - return nil, err - } - existingMember, _ := org.MemeberByUserID(member.UserID) - if existingMember == nil { - return nil, errors.ThrowNotFound(nil, "EVENT-VB2Pn", "Errors.Org.MemberNotExisting") - } - - repoOrg := model.OrgFromModel(org) - repoMember := model.OrgMemberFromModel(member) - repoExistingMember := model.OrgMemberFromModel(existingMember) - - orgAggregate := orgMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoExistingMember, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoMember.AppendEvents, orgAggregate) - if err != nil { - return nil, err - } - - return model.OrgMemberToModel(repoMember), nil -} - -func (es *OrgEventstore) RemoveOrgMember(ctx context.Context, member *org_model.OrgMember) error { - if member == nil || member.UserID == "" { - return errors.ThrowInvalidArgument(nil, "EVENT-d43fs", "Errors.Org.UserIDMissing") - } - - org, err := es.OrgByID(ctx, &org_model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: member.AggregateID, Sequence: member.Sequence}}) - if err != nil { - return err - } - existingMember, _ := org.MemeberByUserID(member.UserID) - if existingMember == nil { - return nil - } - - repoOrg := model.OrgFromModel(org) - repoMember := model.OrgMemberFromModel(member) - - orgAggregate := orgMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMember) - return es_sdk.Push(ctx, es.PushAggregates, repoMember.AppendEvents, orgAggregate) -} - func (es *OrgEventstore) GetOrgIAMPolicy(ctx context.Context, orgID string) (*iam_model.OrgIAMPolicy, error) { existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID)) if err != nil { @@ -483,339 +179,6 @@ func (es *OrgEventstore) GetOrgIAMPolicy(ctx context.Context, orgID string) (*ia return existingOrg.OrgIamPolicy, nil } -func (es *OrgEventstore) AddOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - if existingOrg.OrgIamPolicy != nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-7Usj3", "Errors.Org.PolicyAlreadyExists") - } - repoOrg := model.OrgFromModel(existingOrg) - repoPolicy := iam_es_model.OrgIAMPolicyFromModel(policy) - orgAggregate := OrgIAMPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPolicy) - if err != nil { - return nil, err - } - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, orgAggregate) - if err != nil { - return nil, err - } - - return iam_es_model.OrgIAMPolicyToModel(repoOrg.OrgIAMPolicy), nil -} - -func (es *OrgEventstore) ChangeOrgIAMPolicy(ctx context.Context, policy *iam_model.OrgIAMPolicy) (*iam_model.OrgIAMPolicy, error) { - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - if existingOrg.OrgIamPolicy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-8juSd", "Errors.Org.PolicyNotExisting") - } - repoOrg := model.OrgFromModel(existingOrg) - repoPolicy := iam_es_model.OrgIAMPolicyFromModel(policy) - orgAggregate := OrgIAMPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPolicy) - if err != nil { - return nil, err - } - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, orgAggregate) - if err != nil { - return nil, err - } - - return iam_es_model.OrgIAMPolicyToModel(repoOrg.OrgIAMPolicy), nil -} - -func (es *OrgEventstore) RemoveOrgIAMPolicy(ctx context.Context, orgID string) error { - existingOrg, err := es.OrgByID(ctx, org_model.NewOrg(orgID)) - if err != nil { - return err - } - if existingOrg.OrgIamPolicy == nil { - return errors.ThrowPreconditionFailed(nil, "EVENT-z6Dse", "Errors.Org.PolicyNotExisting") - } - repoOrg := model.OrgFromModel(existingOrg) - orgAggregate := OrgIamPolicyRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg) - if err != nil { - return err - } - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, orgAggregate) -} - -func (es *OrgEventstore) AddIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { - if idp == nil || !idp.IsValid(true) { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Ms89d", "Errors.Org.IdpInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(idp.AggregateID)) - if err != nil { - return nil, err - } - id, err := es.idGenerator.Next() - if err != nil { - return nil, err - } - idp.IDPConfigID = id - - if idp.OIDCConfig != nil { - idp.OIDCConfig.IDPConfigID = id - err = idp.OIDCConfig.CryptSecret(es.secretCrypto) - } - repoOrg := model.OrgFromModel(org) - repoIdp := iam_es_model.IDPConfigFromModel(idp) - - addAggregate := IDPConfigAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoIdp) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - if _, idpConfig := iam_es_model.GetIDPConfig(repoOrg.IDPs, idp.IDPConfigID); idpConfig != nil { - return iam_es_model.IDPConfigToModel(idpConfig), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-Cmsj8d", "Errors.Internal") -} - -func (es *OrgEventstore) ChangeIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) { - if idp == nil || !idp.IsValid(false) { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Mslo9", "Errors.Org.IdpInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(idp.AggregateID)) - if err != nil { - return nil, err - } - if _, i := org.GetIDP(idp.IDPConfigID); i == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Aji8e", "Errors.Org.IdpNotExisting") - } - repoOrg := model.OrgFromModel(org) - repoIdp := iam_es_model.IDPConfigFromModel(idp) - - iamAggregate := IDPConfigChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoIdp) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, iamAggregate) - if err != nil { - return nil, err - } - if _, idpConfig := iam_es_model.GetIDPConfig(repoOrg.IDPs, idp.IDPConfigID); idpConfig != nil { - return iam_es_model.IDPConfigToModel(idpConfig), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-Ml9xs", "Errors.Internal") -} - -func (es *OrgEventstore) PrepareRemoveIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*model.Org, *es_models.Aggregate, error) { - if idp.IDPConfigID == "" { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-Wz7sD", "Errors.Org.IDMissing") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(idp.AggregateID)) - if err != nil { - return nil, nil, err - } - if _, i := org.GetIDP(idp.IDPConfigID); i == nil { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smiu8", "Errors.Org.IdpNotExisting") - } - repoOrg := model.OrgFromModel(org) - repoIdp := iam_es_model.IDPConfigFromModel(idp) - provider := new(iam_es_model.IDPProvider) - if repoOrg.LoginPolicy != nil { - _, provider = iam_es_model.GetIDPProvider(repoOrg.LoginPolicy.IDPProviders, idp.IDPConfigID) - } - agg, err := IDPConfigRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoOrg, repoIdp, provider) - if err != nil { - return nil, nil, err - } - return repoOrg, agg, nil -} - -func (es *OrgEventstore) RemoveIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) error { - repoOrg, agg, err := es.PrepareRemoveIDPConfig(ctx, idp) - if err != nil { - return err - } - return es_sdk.PushAggregates(ctx, es.PushAggregates, repoOrg.AppendEvents, agg) -} - -func (es *OrgEventstore) DeactivateIDPConfig(ctx context.Context, orgID, idpID string) (*iam_model.IDPConfig, error) { - if idpID == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smk8d", "Errors.Org.IDMissing") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(orgID)) - if err != nil { - return nil, err - } - idp := &iam_model.IDPConfig{IDPConfigID: idpID} - if _, app := org.GetIDP(idp.IDPConfigID); app == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Amk8d", "Errors.Org.IdpNotExisting") - } - repoOrg := model.OrgFromModel(org) - repoIdp := iam_es_model.IDPConfigFromModel(idp) - - iamAggregate := IDPConfigDeactivatedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoIdp) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, iamAggregate) - if err != nil { - return nil, err - } - if _, idpConfig := iam_es_model.GetIDPConfig(repoOrg.IDPs, idp.IDPConfigID); idpConfig != nil { - return iam_es_model.IDPConfigToModel(idpConfig), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-Amk9c", "Errors.Internal") -} - -func (es *OrgEventstore) ReactivateIDPConfig(ctx context.Context, orgID, idpID string) (*iam_model.IDPConfig, error) { - if idpID == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Xm8df", "Errors.Org.IDMissing") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(orgID)) - if err != nil { - return nil, err - } - idp := &iam_model.IDPConfig{IDPConfigID: idpID} - if _, i := org.GetIDP(idp.IDPConfigID); i == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Qls0f", "Errors.Org.IdpNotExisting") - } - repoOrg := model.OrgFromModel(org) - repoIdp := iam_es_model.IDPConfigFromModel(idp) - - iamAggregate := IDPConfigReactivatedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoIdp) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, iamAggregate) - if err != nil { - return nil, err - } - if _, idpConfig := iam_es_model.GetIDPConfig(repoOrg.IDPs, idp.IDPConfigID); idpConfig != nil { - return iam_es_model.IDPConfigToModel(idpConfig), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-Al90s", "Errors.Internal") -} - -func (es *OrgEventstore) ChangeIDPOIDCConfig(ctx context.Context, config *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) { - if config == nil || !config.IsValid(false) { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Qs789", "Errors.Org.OIDCConfigInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(config.AggregateID)) - if err != nil { - return nil, err - } - var idp *iam_model.IDPConfig - if _, idp = org.GetIDP(config.IDPConfigID); idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-pso0s", "Errors.Org.IdpNoExisting") - } - if idp.Type != iam_model.IDPConfigTypeOIDC { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Fms8w", "Errors.IAM.IdpIsNotOIDC") - } - if config.ClientSecretString != "" { - err = idp.OIDCConfig.CryptSecret(es.secretCrypto) - } else { - config.ClientSecret = nil - } - repoOrg := model.OrgFromModel(org) - repoConfig := iam_es_model.OIDCIDPConfigFromModel(config) - - iamAggregate := OIDCIDPConfigChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoConfig) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, iamAggregate) - if err != nil { - return nil, err - } - if _, idpConfig := iam_es_model.GetIDPConfig(repoOrg.IDPs, idp.IDPConfigID); idpConfig != nil { - return iam_es_model.OIDCIDPConfigToModel(idpConfig.OIDCIDPConfig), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-Sldk8", "Errors.Internal") -} - -func (es *OrgEventstore) AddLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - if policy == nil || !policy.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-37rSC", "Errors.Org.LabelPolicyInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoLabelPolicy := iam_es_model.LabelPolicyFromModel(policy) - - addAggregate := LabelPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoLabelPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.LabelPolicyToModel(repoOrg.LabelPolicy), nil -} - -func (es *OrgEventstore) ChangeLabelPolicy(ctx context.Context, policy *iam_model.LabelPolicy) (*iam_model.LabelPolicy, error) { - if policy == nil || !policy.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-0NBIw", "Errors.Org.LabelPolicyInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoLabelPolicy := iam_es_model.LabelPolicyFromModel(policy) - - addAggregate := LabelPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoLabelPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.LabelPolicyToModel(repoOrg.LabelPolicy), nil -} - -func (es *OrgEventstore) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - if policy == nil || !policy.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sjkl9", "Errors.Org.LoginPolicy.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoLoginPolicy := iam_es_model.LoginPolicyFromModel(policy) - - addAggregate := LoginPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoLoginPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.LoginPolicyToModel(repoOrg.LoginPolicy), nil -} - -func (es *OrgEventstore) ChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { - if policy == nil || !policy.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-mL0ps", "Errors.Org.LoginPolicy.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - if org.LoginPolicy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-3Mg9s", "Errors.Org.LoginPolicy.NotExisting") - } - - repoOrg := model.OrgFromModel(org) - repoLoginPolicy := iam_es_model.LoginPolicyFromModel(policy) - - addAggregate := LoginPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoLoginPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.LoginPolicyToModel(repoOrg.LoginPolicy), nil -} - -func (es *OrgEventstore) RemoveLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) error { - if policy == nil || !policy.IsValid() { - return errors.ThrowPreconditionFailed(nil, "EVENT-O0s9e", "Errors.Org.LoginPolicy.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return err - } - repoOrg := model.OrgFromModel(org) - - addAggregate := LoginPolicyRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg) - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) -} - func (es *OrgEventstore) GetIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) { existing, err := es.OrgByID(ctx, org_model.NewOrg(aggregateID)) if err != nil { @@ -826,448 +189,3 @@ func (es *OrgEventstore) GetIDPConfig(ctx context.Context, aggregateID, idpConfi } return nil, errors.ThrowNotFound(nil, "EVENT-Qlo0d", "Errors.Org.IdpNotExisting") } - -func (es *OrgEventstore) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) { - if provider == nil || !provider.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sjd8e", "Errors.Org.IdpProviderInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(provider.AggregateID)) - if err != nil { - return nil, err - } - if org.LoginPolicy == nil { - return nil, errors.ThrowAlreadyExists(nil, "EVENT-sk9fW", "Errors.Org.LoginPolicy.NotExisting") - } - if _, m := org.LoginPolicy.GetIdpProvider(provider.IDPConfigID); m != nil { - return nil, errors.ThrowAlreadyExists(nil, "EVENT-Lso9f", "Errors.Org.LoginPolicy.IdpProviderAlreadyExisting") - } - repoOrg := model.OrgFromModel(org) - repoProvider := iam_es_model.IDPProviderFromModel(provider) - - addAggregate := LoginPolicyIDPProviderAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoProvider, es.IamID) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - if _, m := iam_es_model.GetIDPProvider(repoOrg.LoginPolicy.IDPProviders, provider.IDPConfigID); m != nil { - return iam_es_model.IDPProviderToModel(m), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-Slf9s", "Errors.Internal") -} - -func (es *OrgEventstore) PrepareRemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider, cascade bool) (*model.Org, *es_models.Aggregate, error) { - if provider == nil || !provider.IsValid() { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-Esi8c", "Errors.IdpProviderInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(provider.AggregateID)) - if err != nil { - return nil, nil, err - } - if _, m := org.LoginPolicy.GetIdpProvider(provider.IDPConfigID); m == nil { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-29skr", "Errors.IAM.LoginPolicy.IdpProviderNotExisting") - } - repoOrg := model.OrgFromModel(org) - providerID := &iam_es_model.IDPProviderID{provider.IDPConfigID} - providerAggregates, err := LoginPolicyIDPProviderRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoOrg, providerID, cascade) - if err != nil { - return nil, nil, err - } - return repoOrg, providerAggregates, nil -} - -func (es *OrgEventstore) RemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) error { - repoOrg, agg, err := es.PrepareRemoveIDPProviderFromLoginPolicy(ctx, provider, false) - if err != nil { - return err - } - return es_sdk.PushAggregates(ctx, es.PushAggregates, repoOrg.AppendEvents, agg) -} - -func (es *OrgEventstore) AddSecondFactorToLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.SecondFactorType) (iam_model.SecondFactorType, error) { - if mfa == iam_model.SecondFactorTypeUnspecified { - return 0, errors.ThrowPreconditionFailed(nil, "EVENT-3Rf8s", "Errors.Org.LoginPolicy.MFA.Unspecified") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(aggregateID)) - if err != nil { - return 0, err - } - if org.LoginPolicy == nil { - return 0, errors.ThrowAlreadyExists(nil, "EVENT-hMd9s", "Errors.Org.LoginPolicy.NotExisting") - } - if _, m := org.LoginPolicy.GetSecondFactor(mfa); m != 0 { - return 0, errors.ThrowAlreadyExists(nil, "EVENT-3Bm9s", "Errors.Org.LoginPolicy.MFA.AlreadyExisting") - } - repoOrg := model.OrgFromModel(org) - repoMFA := iam_es_model.SecondFactorFromModel(mfa) - - addAggregate := LoginPolicySecondFactorAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMFA, es.IamID) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return 0, err - } - if _, m := iam_es_model.GetMFA(repoOrg.LoginPolicy.SecondFactors, repoMFA.MFAType); m != 0 { - return iam_model.SecondFactorType(m), nil - } - return 0, errors.ThrowInternal(nil, "EVENT-rM9so", "Errors.Internal") -} - -func (es *OrgEventstore) RemoveSecondFactorFromLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.SecondFactorType) error { - if mfa == iam_model.SecondFactorTypeUnspecified { - return errors.ThrowPreconditionFailed(nil, "EVENT-6Nm9s", "Errors.Org.LoginPolicy.MFA.Unspecified") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(aggregateID)) - if err != nil { - return err - } - if _, m := org.LoginPolicy.GetSecondFactor(mfa); m == 0 { - return errors.ThrowPreconditionFailed(nil, "EVENT-5Mso9", "Errors.IAM.LoginPolicy.MFA.NotExisting") - } - repoOrg := model.OrgFromModel(org) - repoMFA := iam_es_model.SecondFactorFromModel(mfa) - agg := LoginPolicySecondFactorRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMFA) - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, agg) -} - -func (es *OrgEventstore) AddMultiFactorToLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.MultiFactorType) (iam_model.MultiFactorType, error) { - if mfa == iam_model.MultiFactorTypeUnspecified { - return 0, errors.ThrowPreconditionFailed(nil, "EVENT-6Zms9", "Errors.Org.LoginPolicy.MFA.Unspecified") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(aggregateID)) - if err != nil { - return 0, err - } - if org.LoginPolicy == nil { - return 0, errors.ThrowAlreadyExists(nil, "EVENT-fGmx9", "Errors.Org.LoginPolicy.NotExisting") - } - if _, m := org.LoginPolicy.GetMultiFactor(mfa); m != 0 { - return 0, errors.ThrowAlreadyExists(nil, "EVENT-2Fj9s", "Errors.Org.LoginPolicy.MFA.AlreadyExisting") - } - repoOrg := model.OrgFromModel(org) - repoMFA := iam_es_model.MultiFactorFromModel(mfa) - - addAggregate := LoginPolicyMultiFactorAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMFA, es.IamID) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return 0, err - } - if _, m := iam_es_model.GetMFA(repoOrg.LoginPolicy.MultiFactors, repoMFA.MFAType); m != 0 { - return iam_model.MultiFactorType(m), nil - } - return 0, errors.ThrowInternal(nil, "EVENT-2fMo0", "Errors.Internal") -} - -func (es *OrgEventstore) RemoveMultiFactorFromLoginPolicy(ctx context.Context, aggregateID string, mfa iam_model.MultiFactorType) error { - if mfa == iam_model.MultiFactorTypeUnspecified { - return errors.ThrowPreconditionFailed(nil, "EVENT-lsM9c", "Errors.Org.LoginPolicy.MFA.Unspecified") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(aggregateID)) - if err != nil { - return err - } - if _, m := org.LoginPolicy.GetMultiFactor(mfa); m == 0 { - return errors.ThrowPreconditionFailed(nil, "EVENT-3dM0s", "Errors.IAM.LoginPolicy.MFA.NotExisting") - } - repoOrg := model.OrgFromModel(org) - repoMFA := iam_es_model.MultiFactorFromModel(mfa) - agg := LoginPolicyMultiFactorRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMFA) - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, agg) -} - -func (es *OrgEventstore) AddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sjkl9", "Errors.Org.PasswordComplexityPolicy.Invalid") - } - - if err := policy.IsValid(); err != nil { - return nil, err - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoPasswordComplexityPolicy := iam_es_model.PasswordComplexityPolicyFromModel(policy) - - addAggregate := PasswordComplexityPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPasswordComplexityPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.PasswordComplexityPolicyToModel(repoOrg.PasswordComplexityPolicy), nil -} - -func (es *OrgEventstore) ChangePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-r5Hd", "Errors.Org.PasswordComplexityPolicy.Empty") - } - if err := policy.IsValid(); err != nil { - return nil, err - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - if org.PasswordComplexityPolicy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-v6Hdr", "Errors.Org.PasswordComplexityPolicy.NotExisting") - } - - repoOrg := model.OrgFromModel(org) - repoPasswordComplexityPolicy := iam_es_model.PasswordComplexityPolicyFromModel(policy) - - addAggregate := PasswordComplexityPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPasswordComplexityPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.PasswordComplexityPolicyToModel(repoOrg.PasswordComplexityPolicy), nil -} - -func (es *OrgEventstore) RemovePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) error { - if policy == nil || policy.AggregateID == "" { - return errors.ThrowPreconditionFailed(nil, "EVENT-3Ghs8", "Errors.Org.PasswordComplexityPolicy.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return err - } - repoOrg := model.OrgFromModel(org) - - addAggregate := PasswordComplexityPolicyRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg) - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) -} - -func (es *OrgEventstore) AddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - if policy == nil || policy.AggregateID == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sjkl9", "Errors.Org.PasswordAgePolicy.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoPasswordAgePolicy := iam_es_model.PasswordAgePolicyFromModel(policy) - - addAggregate := PasswordAgePolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPasswordAgePolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.PasswordAgePolicyToModel(repoOrg.PasswordAgePolicy), nil -} - -func (es *OrgEventstore) ChangePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { - if policy == nil || policy.AggregateID == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-r5Hd", "Errors.Org.PasswordAgePolicy.Empty") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - if org.PasswordAgePolicy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-v6Hdr", "Errors.Org.PasswordAgePolicy.NotExisting") - } - - repoOrg := model.OrgFromModel(org) - repoPasswordAgePolicy := iam_es_model.PasswordAgePolicyFromModel(policy) - - addAggregate := PasswordAgePolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPasswordAgePolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.PasswordAgePolicyToModel(repoOrg.PasswordAgePolicy), nil -} - -func (es *OrgEventstore) RemovePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) error { - if policy == nil || policy.AggregateID == "" { - return errors.ThrowPreconditionFailed(nil, "EVENT-3Ghs8", "Errors.Org.PasswordAgePolicy.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return err - } - repoOrg := model.OrgFromModel(org) - - addAggregate := PasswordAgePolicyRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg) - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) -} - -func (es *OrgEventstore) AddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - if policy == nil || policy.AggregateID == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-6Zdk9", "Errors.Org.PasswordLockoutPolicy.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoPasswordLockoutPolicy := iam_es_model.PasswordLockoutPolicyFromModel(policy) - - addAggregate := PasswordLockoutPolicyAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPasswordLockoutPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.PasswordLockoutPolicyToModel(repoOrg.PasswordLockoutPolicy), nil -} - -func (es *OrgEventstore) ChangePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { - if policy == nil || policy.AggregateID == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-lp0Sf", "Errors.Org.PasswordLockoutPolicy.Empty") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return nil, err - } - - if org.PasswordLockoutPolicy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-3Fks9", "Errors.Org.PasswordLockoutPolicy.NotExisting") - } - - repoOrg := model.OrgFromModel(org) - repoPasswordLockoutPolicy := iam_es_model.PasswordLockoutPolicyFromModel(policy) - - addAggregate := PasswordLockoutPolicyChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoPasswordLockoutPolicy) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.PasswordLockoutPolicyToModel(repoOrg.PasswordLockoutPolicy), nil -} - -func (es *OrgEventstore) RemovePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) error { - if policy == nil || policy.AggregateID == "" { - return errors.ThrowPreconditionFailed(nil, "EVENT-6Hls0", "Errors.Org.PasswordLockoutPolicy.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(policy.AggregateID)) - if err != nil { - return err - } - repoOrg := model.OrgFromModel(org) - - addAggregate := PasswordLockoutPolicyRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg) - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) -} - -func (es *OrgEventstore) AddMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { - if template == nil || !template.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-nb66d", "Errors.Org.MailTemplateInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(template.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoMailTemplate := iam_es_model.MailTemplateFromModel(template) - - addAggregate := MailTemplateAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailTemplate) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - return iam_es_model.MailTemplateToModel(repoOrg.MailTemplate), nil -} - -func (es *OrgEventstore) ChangeMailTemplate(ctx context.Context, template *iam_model.MailTemplate) (*iam_model.MailTemplate, error) { - if template == nil || !template.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-FV2qE", "Errors.Org.MailTemplateInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(template.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoMailTemplate := iam_es_model.MailTemplateFromModel(template) - - addAggregate := MailTemplateChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailTemplate) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - repoOrg.MailTemplate.Template = repoMailTemplate.Template - return iam_es_model.MailTemplateToModel(repoOrg.MailTemplate), nil -} - -func (es *OrgEventstore) RemoveMailTemplate(ctx context.Context, template *iam_model.MailTemplate) error { - if template == nil || !template.IsValid() { - return errors.ThrowPreconditionFailed(nil, "EVENT-LulaW", "Errors.Org.MailTemplate.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(template.AggregateID)) - if err != nil { - return err - } - repoOrg := model.OrgFromModel(org) - - addAggregate := MailTemplateRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg) - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) -} - -func (es *OrgEventstore) AddMailText(ctx context.Context, mailtext *iam_model.MailText) (*iam_model.MailText, error) { - if mailtext == nil || !mailtext.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-108Iz", "Errors.Org.MailTextInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(mailtext.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoMailText := iam_es_model.MailTextFromModel(mailtext) - - addAggregate := MailTextAddedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailText) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - - if _, r := iam_es_model.GetMailText(repoOrg.MailTexts, repoMailText.MailTextType, repoMailText.Language); r != nil { - return iam_es_model.MailTextToModel(r), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-oc1GN", "Errors.Internal") -} - -func (es *OrgEventstore) ChangeMailText(ctx context.Context, mailtext *iam_model.MailText) (*iam_model.MailText, error) { - if mailtext == nil || !mailtext.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-fdbqE", "Errors.Org.MailTextInvalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(mailtext.AggregateID)) - if err != nil { - return nil, err - } - - repoOrg := model.OrgFromModel(org) - repoMailText := iam_es_model.MailTextFromModel(mailtext) - - addAggregate := MailTextChangedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailText) - err = es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - - if _, r := iam_es_model.GetMailText(repoOrg.MailTexts, mailtext.MailTextType, mailtext.Language); r != nil { - return iam_es_model.MailTextToModel(r), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-F2whI", "Errors.Internal") -} - -func (es *OrgEventstore) RemoveMailText(ctx context.Context, mailtext *iam_model.MailText) error { - if mailtext == nil || !mailtext.IsValid() { - return errors.ThrowPreconditionFailed(nil, "EVENT-LulaW", "Errors.Org.MailText.Invalid") - } - org, err := es.OrgByID(ctx, org_model.NewOrg(mailtext.AggregateID)) - if err != nil { - return err - } - repoOrg := model.OrgFromModel(org) - repoMailText := iam_es_model.MailTextFromModel(mailtext) - - addAggregate := MailTextRemovedAggregate(es.Eventstore.AggregateCreator(), repoOrg, repoMailText) - return es_sdk.Push(ctx, es.PushAggregates, repoOrg.AppendEvents, addAggregate) -} diff --git a/internal/org/repository/eventsourcing/eventstore_mock_test.go b/internal/org/repository/eventsourcing/eventstore_mock_test.go deleted file mode 100644 index 8ca15230c1..0000000000 --- a/internal/org/repository/eventsourcing/eventstore_mock_test.go +++ /dev/null @@ -1,222 +0,0 @@ -package eventsourcing - -import ( - "encoding/json" - - "github.com/caos/zitadel/internal/crypto" - 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/id" - - "github.com/caos/zitadel/internal/eventstore/mock" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - repo_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - "github.com/golang/mock/gomock" -) - -func GetMockedEventstore(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *OrgEventstore { - return &OrgEventstore{ - Eventstore: mockEs, - idGenerator: GetSonyFlake(), - } -} - -func GetMockedEventstoreWithCrypto(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *OrgEventstore { - return &OrgEventstore{ - Eventstore: mockEs, - idGenerator: GetSonyFlake(), - secretCrypto: crypto.NewBCrypt(10), - } -} - -func GetSonyFlake() id.Generator { - return id.SonyFlakeGenerator -} -func GetMockChangesOrgOK(ctrl *gomock.Controller) *OrgEventstore { - org := model.Org{ - Name: "MusterOrg", - } - data, err := json.Marshal(org) - if err != nil { - - } - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, AggregateType: repo_model.OrgAggregate, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgNoEvents(ctrl *gomock.Controller) *OrgEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithCrypto(ctrl *gomock.Controller) *OrgEventstore { - org := model.Org{ - Name: "MusterOrg", - } - data, _ := json.Marshal(org) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithCrypto(ctrl, mockEs) -} - -func GetMockChangesOrgWithOIDCIdp(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - idpData, _ := json.Marshal(iam_es_model.IDPConfig{IDPConfigID: "IDPConfigID", Name: "Name"}) - oidcData, _ := json.Marshal(iam_es_model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.IDPConfigAdded, Data: idpData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.OIDCIDPConfigAdded, Data: oidcData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithLoginPolicy(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - loginPolicy, _ := json.Marshal(iam_es_model.LoginPolicy{AllowRegister: true, AllowExternalIdp: true, AllowUsernamePassword: true}) - idpData, _ := json.Marshal(iam_es_model.IDPProvider{IDPConfigID: "IDPConfigID", Type: int32(iam_model.IDPProviderTypeSystem)}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyAdded, Data: loginPolicy}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyIDPProviderAdded, Data: idpData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithLoginPolicyWithMFA(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - loginPolicy, _ := json.Marshal(iam_es_model.LoginPolicy{AllowRegister: true, AllowExternalIdp: true, AllowUsernamePassword: true}) - idpData, _ := json.Marshal(iam_es_model.IDPProvider{IDPConfigID: "IDPConfigID", Type: int32(iam_model.IDPProviderTypeSystem)}) - secondFactor, _ := json.Marshal(iam_es_model.MFA{MFAType: int32(iam_model.SecondFactorTypeOTP)}) - multiFactor, _ := json.Marshal(iam_es_model.MFA{MFAType: int32(iam_model.MultiFactorTypeU2FWithPIN)}) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyAdded, Data: loginPolicy}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyIDPProviderAdded, Data: idpData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicySecondFactorAdded, Data: secondFactor}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.LoginPolicyMultiFactorAdded, Data: multiFactor}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithPasswordComplexityPolicy(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - passwordComplexityPolicy, _ := json.Marshal(iam_es_model.PasswordComplexityPolicy{ - MinLength: 10, - HasLowercase: true, - HasUppercase: true, - HasSymbol: true, - HasNumber: true, - }) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.PasswordComplexityPolicyAdded, Data: passwordComplexityPolicy}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithPasswordLockoutPolicy(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - passwordLockoutPolicy, _ := json.Marshal(iam_es_model.PasswordLockoutPolicy{ - MaxAttempts: 10, - ShowLockOutFailures: true, - }) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.PasswordLockoutPolicyAdded, Data: passwordLockoutPolicy}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithPasswordAgePolicy(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - passwordAgePolicy, _ := json.Marshal(iam_es_model.PasswordAgePolicy{ - MaxAgeDays: 10, - ExpireWarnDays: 10, - }) - events := []*es_models.Event{ - {AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - {AggregateID: "AggregateID", Sequence: 1, Type: model.PasswordAgePolicyAdded, Data: passwordAgePolicy}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithLabelPolicy(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - labelPolicy, _ := json.Marshal(iam_es_model.LabelPolicy{PrimaryColor: "000001", SecondaryColor: "FFFFF1"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.LabelPolicyAdded, Data: labelPolicy}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithMailTemplate(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - mailTemplate, _ := json.Marshal(iam_es_model.MailTemplate{Template: []byte("")}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTemplateAdded, Data: mailTemplate}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesOrgWithMailText(ctrl *gomock.Controller) *OrgEventstore { - orgData, _ := json.Marshal(model.Org{Name: "MusterOrg"}) - mailText, _ := json.Marshal(iam_es_model.MailText{MailTextType: "Type", Language: "DE"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OrgAdded, Data: orgData}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.MailTextAdded, Data: mailText}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} diff --git a/internal/org/repository/eventsourcing/eventstore_test.go b/internal/org/repository/eventsourcing/eventstore_test.go deleted file mode 100644 index 4db2c10943..0000000000 --- a/internal/org/repository/eventsourcing/eventstore_test.go +++ /dev/null @@ -1,4322 +0,0 @@ -package eventsourcing - -import ( - "context" - "encoding/json" - "testing" - "time" - - iam_model "github.com/caos/zitadel/internal/iam/model" - - "github.com/golang/mock/gomock" - "github.com/stretchr/testify/assert" - - "github.com/caos/zitadel/internal/api/authz" - http_util "github.com/caos/zitadel/internal/api/http" - "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/errors" - caos_errs "github.com/caos/zitadel/internal/errors" - es_mock "github.com/caos/zitadel/internal/eventstore/mock" - es_models "github.com/caos/zitadel/internal/eventstore/models" - org_model "github.com/caos/zitadel/internal/org/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -type testOrgEventstore struct { - OrgEventstore - mockEventstore *es_mock.MockEventstore -} - -func newTestEventstore(t *testing.T) *testOrgEventstore { - ctrl := gomock.NewController(t) - mock := es_mock.NewMockEventstore(ctrl) - verificationAlgorithm := crypto.NewMockEncryptionAlgorithm(ctrl) - verificationGenerator := crypto.NewMockGenerator(ctrl) - return &testOrgEventstore{ - OrgEventstore: OrgEventstore{ - Eventstore: mock, - verificationAlgorithm: verificationAlgorithm, - verificationGenerator: verificationGenerator, - }, - mockEventstore: mock} -} - -func (es *testOrgEventstore) expectFilterEvents(events []*es_models.Event, err error) *testOrgEventstore { - es.mockEventstore.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, err) - return es -} - -func (es *testOrgEventstore) expectPushEvents(startSequence uint64, err error) *testOrgEventstore { - es.mockEventstore.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).DoAndReturn( - func(_ context.Context, aggregates ...*es_models.Aggregate) error { - for _, aggregate := range aggregates { - for _, event := range aggregate.Events { - event.Sequence = startSequence - startSequence++ - } - } - return err - }) - return es -} - -func (es *testOrgEventstore) expectAggregateCreator() *testOrgEventstore { - es.mockEventstore.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("test")) - return es -} - -func (es *testOrgEventstore) expectGenerateVerification(r rune) *testOrgEventstore { - generator, _ := es.verificationGenerator.(*crypto.MockGenerator) - generator.EXPECT().Length().Return(uint(2)) - generator.EXPECT().Runes().Return([]rune("aa")) - generator.EXPECT().Alg().Return(es.verificationAlgorithm) - return es -} - -func (es *testOrgEventstore) expectEncrypt() *testOrgEventstore { - algorithm, _ := es.verificationAlgorithm.(*crypto.MockEncryptionAlgorithm) - algorithm.EXPECT().Encrypt(gomock.Any()).DoAndReturn( - func(value []byte) (*crypto.CryptoValue, error) { - return &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc", - KeyID: "id", - Crypted: value, - }, nil - }) - algorithm.EXPECT().Algorithm().Return("enc") - algorithm.EXPECT().EncryptionKeyID().Return("id") - return es -} - -func (es *testOrgEventstore) expectDecrypt() *testOrgEventstore { - algorithm, _ := es.verificationAlgorithm.(*crypto.MockEncryptionAlgorithm) - algorithm.EXPECT().Algorithm().AnyTimes().Return("enc") - algorithm.EXPECT().DecryptionKeyIDs().Return([]string{"id"}) - algorithm.EXPECT().DecryptString(gomock.Any(), gomock.Any()).DoAndReturn( - func(value []byte, id string) (string, error) { - return string(value), nil - }) - return es -} - -func (es *testOrgEventstore) expectVerification(success bool) *testOrgEventstore { - es.verificationValidator = func(_, _, _ string, _ http_util.CheckType) error { - if success { - return nil - } - return errors.ThrowInvalidArgument(nil, "id", "invalid token") - } - return es -} - -func TestOrgEventstore_OrgByID(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - expectedSequence uint64 - isErr func(error) bool - } - type args struct { - ctx context.Context - org *org_model.Org - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no input org", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - org: nil, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "no aggregate id in input org", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - org: &org_model.Org{ObjectRoot: es_models.ObjectRoot{Sequence: 4}}, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no events found success", - fields: fields{Eventstore: newTestEventstore(t).expectFilterEvents([]*es_models.Event{}, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - org: &org_model.Org{ObjectRoot: es_models.ObjectRoot{Sequence: 4, AggregateID: "hodor"}}, - }, - res: res{ - expectedSequence: 4, - isErr: nil, - }, - }, - { - name: "filter fail", - fields: fields{Eventstore: newTestEventstore(t).expectFilterEvents([]*es_models.Event{}, errors.ThrowInternal(nil, "EVENT-SAa1O", "message"))}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - org: &org_model.Org{ObjectRoot: es_models.ObjectRoot{Sequence: 4, AggregateID: "hodor"}}, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsInternal, - }, - }, - { - name: "new events found and added success", - fields: fields{Eventstore: newTestEventstore(t).expectFilterEvents([]*es_models.Event{ - {Sequence: 6, AggregateID: "hodor-org"}, - }, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - org: &org_model.Org{ObjectRoot: es_models.ObjectRoot{Sequence: 4, AggregateID: "hodor-org", ChangeDate: time.Now(), CreationDate: time.Now()}}, - }, - res: res{ - expectedSequence: 6, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.Eventstore.OrgByID(tt.args.ctx, tt.args.org) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if got == nil && tt.res.expectedSequence != 0 { - t.Errorf("org should be nil but was %v", got) - t.FailNow() - } - if tt.res.expectedSequence != 0 && tt.res.expectedSequence != got.Sequence { - t.Errorf("org should have sequence %d but had %d", tt.res.expectedSequence, got.Sequence) - } - }) - } -} - -func TestOrgEventstore_DeactivateOrg(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - expectedSequence uint64 - isErr func(error) bool - } - type args struct { - ctx context.Context - orgID string - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no input org", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - orgID: "", - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "push failed", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent()}, nil). - expectAggregateCreator(). - expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test"))}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - orgID: "hodor", - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsInternal, - }, - }, - { - name: "push correct", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent()}, nil). - expectAggregateCreator(). - expectPushEvents(6, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - orgID: "hodor", - }, - res: res{ - expectedSequence: 6, - isErr: nil, - }, - }, - { - name: "org already inactive error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgInactiveEvent()}, nil). - expectAggregateCreator(). - expectPushEvents(6, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - orgID: "hodor", - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsErrorInvalidArgument, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.Eventstore.DeactivateOrg(tt.args.ctx, tt.args.orgID) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if got == nil && tt.res.expectedSequence != 0 { - t.Errorf("org should be nil but was %v", got) - t.FailNow() - } - if tt.res.expectedSequence != 0 && tt.res.expectedSequence != got.Sequence { - t.Errorf("org should have sequence %d but had %d", tt.res.expectedSequence, got.Sequence) - } - }) - } -} - -func TestOrgEventstore_ReactivateOrg(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - expectedSequence uint64 - isErr func(error) bool - } - type args struct { - ctx context.Context - orgID string - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no input org", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - orgID: "", - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "push failed", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgInactiveEvent()}, nil). - expectAggregateCreator(). - expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test"))}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - orgID: "hodor", - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsInternal, - }, - }, - { - name: "push correct", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgInactiveEvent()}, nil). - expectAggregateCreator(). - expectPushEvents(6, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - orgID: "hodor", - }, - res: res{ - expectedSequence: 6, - isErr: nil, - }, - }, - { - name: "org already active error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent()}, nil). - expectAggregateCreator(). - expectPushEvents(6, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - orgID: "hodor", - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsErrorInvalidArgument, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.Eventstore.ReactivateOrg(tt.args.ctx, tt.args.orgID) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if got == nil && tt.res.expectedSequence != 0 { - t.Errorf("org should be nil but was %v", got) - t.FailNow() - } - if tt.res.expectedSequence != 0 && tt.res.expectedSequence != got.Sequence { - t.Errorf("org should have sequence %d but had %d", tt.res.expectedSequence, got.Sequence) - } - }) - } -} - -func TestOrgEventstore_GenerateOrgDomainValidation(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - token string - url string - isErr func(error) bool - } - type args struct { - ctx context.Context - domain *org_model.OrgDomain - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no domain", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: nil, - }, - res: res{ - token: "", - url: "", - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "validation type invalid error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent()}, nil). - expectGenerateVerification(65). - expectEncrypt(), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org"}, - }, - res: res{ - token: "", - url: "", - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "org doesn't exist error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - token: "", - url: "", - isErr: errors.IsNotFound, - }, - }, - { - name: "domain doesn't exist error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent()}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - token: "", - url: "", - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "domain already verified error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerifiedEvent()}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - token: "", - url: "", - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "push failed", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent()}, nil). - expectGenerateVerification(65). - expectEncrypt(). - expectAggregateCreator(). - expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test")), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - token: "", - url: "", - isErr: errors.IsInternal, - }, - }, - { - name: "push correct http", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent()}, nil). - expectGenerateVerification(65). - expectEncrypt(). - expectAggregateCreator(). - expectPushEvents(6, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - token: "aa", - url: "https://hodor.org/.well-known/zitadel-challenge/aa", - isErr: nil, - }, - }, - { - name: "push correct dns", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent()}, nil). - expectGenerateVerification(65). - expectEncrypt(). - expectAggregateCreator(). - expectPushEvents(6, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeDNS}, - }, - res: res{ - token: "aa", - url: "_zitadel-challenge.hodor.org", - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - token, url, err := tt.fields.Eventstore.GenerateOrgDomainValidation(tt.args.ctx, tt.args.domain) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - assert.Equal(t, tt.res.token, token) - assert.Equal(t, tt.res.url, url) - }) - } -} - -func TestOrgEventstore_ValidateOrgDomain(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - isErr func(error) bool - } - type args struct { - ctx context.Context - domain *org_model.OrgDomain - users func(ctx context.Context, domain string) ([]*es_models.Aggregate, error) - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no domain", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: nil, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "org doesn't exist error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsNotFound, - }, - }, - { - name: "domain doesn't exist error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent()}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "domain already verified error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerifiedEvent()}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "domain validation not created error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent()}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "verification fails", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerificationAddedEvent("token")}, nil). - expectDecrypt(). - expectVerification(false). - expectAggregateCreator(). - expectPushEvents(0, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "verification and push fails", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerificationAddedEvent("token")}, nil). - expectDecrypt(). - expectVerification(false). - expectAggregateCreator(). - expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test")), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsInternal, - }, - }, - { - name: "(user) aggregate fails", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerificationAddedEvent("token")}, nil). - expectDecrypt(). - expectVerification(true). - expectAggregateCreator(). - expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test")), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - users: func(ctx context.Context, domain string) ([]*es_models.Aggregate, error) { - return nil, errors.ThrowInternal(nil, "id", "internal error") - }, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "push failed", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerificationAddedEvent("token")}, nil). - expectDecrypt(). - expectVerification(true). - expectAggregateCreator(). - expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test")), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsInternal, - }, - }, - { - name: "push correct", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerificationAddedEvent("token")}, nil). - expectDecrypt(). - expectVerification(true). - expectAggregateCreator(). - expectPushEvents(6, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.fields.Eventstore.ValidateOrgDomain(tt.args.ctx, tt.args.domain, tt.args.users) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - }) - } -} - -func TestOrgEventstore_SetPrimaryOrgDomain(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - isErr func(error) bool - } - type args struct { - ctx context.Context - domain *org_model.OrgDomain - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no domain", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: nil, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "org doesn't exist error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsNotFound, - }, - }, - { - name: "domain doesn't exist error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent()}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "domain not verified error", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent()}, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "push failed", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerifiedEvent()}, nil). - expectAggregateCreator(). - expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test")), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: errors.IsInternal, - }, - }, - { - name: "push correct", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerifiedEvent()}, nil). - expectAggregateCreator(). - expectPushEvents(6, nil), - }, - args: args{ - ctx: authz.NewMockContext("org", "user"), - domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP}, - }, - res: res{ - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.fields.Eventstore.SetPrimaryOrgDomain(tt.args.ctx, tt.args.domain) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - }) - } -} - -func TestOrgEventstore_OrgMemberByIDs(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - expectedSequence uint64 - isErr func(error) bool - } - type args struct { - ctx context.Context - member *org_model.OrgMember - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no input member", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: nil, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no aggregate id in input member", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ObjectRoot: es_models.ObjectRoot{Sequence: 4}, UserID: "asdf"}, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no aggregate id in input member", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ObjectRoot: es_models.ObjectRoot{Sequence: 4, AggregateID: "asdf"}}, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no events found success", - fields: fields{Eventstore: newTestEventstore(t).expectFilterEvents([]*es_models.Event{}, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ObjectRoot: es_models.ObjectRoot{Sequence: 4, AggregateID: "plants"}, UserID: "banana"}, - }, - res: res{ - expectedSequence: 4, - isErr: nil, - }, - }, - { - name: "filter fail", - fields: fields{Eventstore: newTestEventstore(t).expectFilterEvents([]*es_models.Event{}, errors.ThrowInternal(nil, "EVENT-SAa1O", "message"))}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ObjectRoot: es_models.ObjectRoot{Sequence: 4, AggregateID: "plants"}, UserID: "banana"}, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsInternal, - }, - }, - { - name: "new events found and added success", - fields: fields{Eventstore: newTestEventstore(t).expectFilterEvents([]*es_models.Event{ - {Sequence: 6, Data: []byte("{\"userId\": \"banana\", \"roles\": [\"bananaa\"]}"), Type: model.OrgMemberChanged}, - }, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ObjectRoot: es_models.ObjectRoot{Sequence: 4, AggregateID: "plants", ChangeDate: time.Now(), CreationDate: time.Now()}, UserID: "banana"}, - }, - res: res{ - expectedSequence: 6, - isErr: nil, - }, - }, - { - name: "not member of org error", - fields: fields{Eventstore: newTestEventstore(t).expectFilterEvents([]*es_models.Event{ - {Sequence: 6, Data: []byte("{\"userId\": \"banana\", \"roles\": [\"bananaa\"]}"), Type: model.OrgMemberAdded}, - {Sequence: 7, Data: []byte("{\"userId\": \"apple\"}"), Type: model.OrgMemberRemoved}, - }, nil)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ObjectRoot: es_models.ObjectRoot{Sequence: 4, AggregateID: "plants", ChangeDate: time.Now(), CreationDate: time.Now()}, UserID: "apple"}, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.Eventstore.OrgMemberByIDs(tt.args.ctx, tt.args.member) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if got == nil && tt.res.expectedSequence != 0 { - t.Errorf("org should be nil but was %v", got) - t.FailNow() - } - if tt.res.expectedSequence != 0 && tt.res.expectedSequence != got.Sequence { - t.Errorf("org should have sequence %d but had %d", tt.res.expectedSequence, got.Sequence) - } - }) - } -} - -func TestOrgEventstore_AddOrgMember(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - expectedSequence uint64 - isErr func(error) bool - } - type args struct { - ctx context.Context - member *org_model.OrgMember - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no input member", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: nil, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "push failed", - fields: fields{Eventstore: newTestEventstore(t). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - }, nil). - expectAggregateCreator(). - expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test"))}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{ - Sequence: 4, - AggregateID: "hodor-org", - }, - UserID: "hodor", - Roles: []string{"nix"}, - }, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsInternal, - }, - }, - { - name: "push correct", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - }, nil). - expectPushEvents(6, nil), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{ - Sequence: 4, - AggregateID: "hodor-org", - }, - UserID: "hodor", - Roles: []string{"nix"}, - }, - }, - res: res{ - expectedSequence: 6, - isErr: nil, - }, - }, - { - name: "member already exists error", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "hodor", "roles": ["master"]}`), - Sequence: 6, - }, - }, nil). - expectPushEvents(0, errors.ThrowAlreadyExists(nil, "EVENT-yLTI6", "weiss nöd wie teste")), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{ - Sequence: 4, - AggregateID: "hodor-org", - }, - UserID: "hodor", - Roles: []string{"nix"}, - }, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsErrorAlreadyExists, - }, - }, - { - name: "member deleted success", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectPushEvents(10, nil). - expectFilterEvents([]*es_models.Event{ - { - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "hodor", "roles": ["master"]}`), - Sequence: 6, - }, - { - Type: model.OrgMemberRemoved, - Data: []byte(`{"userId": "hodor"}`), - Sequence: 10, - }, - }, nil), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{ - Sequence: 4, - AggregateID: "hodor-org", - }, - UserID: "hodor", - Roles: []string{"nix"}, - }, - }, - res: res{ - expectedSequence: 10, - isErr: nil, - }, - }, - { - name: "org not exists error", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents(nil, nil). - expectPushEvents(0, errors.ThrowAlreadyExists(nil, "EVENT-yLTI6", "weiss nöd wie teste")), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{ - Sequence: 4, - AggregateID: "hodor-org", - }, - UserID: "hodor", - Roles: []string{"nix"}, - }, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsErrorAlreadyExists, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := tt.fields.Eventstore.AddOrgMember(tt.args.ctx, tt.args.member) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if got == nil && tt.res.expectedSequence != 0 { - t.Errorf("org should not be nil but was %v", got) - t.FailNow() - } - if tt.res.expectedSequence != 0 && tt.res.expectedSequence != got.Sequence { - t.Errorf("org should have sequence %d but had %d", tt.res.expectedSequence, got.Sequence) - } - }) - } -} - -func TestOrgEventstore_ChangeOrgMember(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - isErr func(error) bool - expectedSequence uint64 - } - type args struct { - ctx context.Context - member *org_model.OrgMember - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no input member", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: nil, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "member not found error", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - { - AggregateID: "hodor-org", - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "brudi", "roles": ["master of desaster"]}`), - Sequence: 6, - }, - }, nil), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org", Sequence: 5}, - UserID: "hodor", - Roles: []string{"master"}, - }, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsNotFound, - }, - }, - { - name: "member found no changes error", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - { - AggregateID: "hodor-org", - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "hodor", "roles": ["master"]}`), - Sequence: 6, - }, - }, nil), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org", Sequence: 5}, - UserID: "hodor", - Roles: []string{"master"}, - }, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "push error", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - { - AggregateID: "hodor-org", - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "hodor", "roles": ["master"]}`), - Sequence: 6, - }, - }, nil). - expectPushEvents(0, errors.ThrowInternal(nil, "PEVENT-3wqa2", "test")), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org", Sequence: 5}, - UserID: "hodor", - Roles: []string{"master of desaster"}, - }, - }, - res: res{ - expectedSequence: 0, - isErr: errors.IsInternal, - }, - }, - { - name: "change success", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - { - AggregateID: "hodor-org", - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "hodor", "roles": ["master"]}`), - Sequence: 6, - }, - }, nil). - expectPushEvents(7, nil), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org", Sequence: 5}, - UserID: "hodor", - Roles: []string{"master of desaster"}, - }, - }, - res: res{ - expectedSequence: 7, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - es := &OrgEventstore{ - Eventstore: tt.fields.Eventstore, - } - got, err := es.ChangeOrgMember(tt.args.ctx, tt.args.member) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if got == nil && tt.res.expectedSequence != 0 { - t.Errorf("org should not be nil but was %v", got) - t.FailNow() - } - if tt.res.expectedSequence != 0 && tt.res.expectedSequence != got.Sequence { - t.Errorf("org should have sequence %d but had %d", tt.res.expectedSequence, got.Sequence) - } - }) - } -} - -func TestOrgEventstore_RemoveOrgMember(t *testing.T) { - type fields struct { - Eventstore *testOrgEventstore - } - type res struct { - isErr func(error) bool - } - type args struct { - ctx context.Context - member *org_model.OrgMember - } - tests := []struct { - name string - fields fields - args args - res res - }{ - { - name: "no input member", - fields: fields{Eventstore: newTestEventstore(t)}, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: nil, - }, - res: res{ - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "member not found error", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - { - AggregateID: "hodor-org", - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "brudi", "roles": ["master of desaster"]}`), - Sequence: 6, - }, - }, nil), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org", Sequence: 5}, - UserID: "hodor", - Roles: []string{"master"}, - }, - }, - res: res{ - isErr: nil, - }, - }, - { - name: "push error", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - { - AggregateID: "hodor-org", - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "hodor", "roles": ["master"]}`), - Sequence: 6, - }, - }, nil). - expectPushEvents(0, errors.ThrowInternal(nil, "PEVENT-3wqa2", "test")), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org", Sequence: 5}, - UserID: "hodor", - }, - }, - res: res{ - isErr: errors.IsInternal, - }, - }, - { - name: "remove success", - fields: fields{Eventstore: newTestEventstore(t). - expectAggregateCreator(). - expectFilterEvents([]*es_models.Event{ - { - AggregateID: "hodor-org", - Type: model.OrgAdded, - Sequence: 4, - Data: []byte("{}"), - }, - { - AggregateID: "hodor-org", - Type: model.OrgMemberAdded, - Data: []byte(`{"userId": "hodor", "roles": ["master"]}`), - Sequence: 6, - }, - }, nil). - expectPushEvents(7, nil), - }, - args: args{ - ctx: authz.NewMockContext("user", "org"), - member: &org_model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org", Sequence: 5}, - UserID: "hodor", - }, - }, - res: res{ - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - es := &OrgEventstore{ - Eventstore: tt.fields.Eventstore, - } - err := es.RemoveOrgMember(tt.args.ctx, tt.args.member) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - }) - } -} - -func orgCreatedEvent() *es_models.Event { - return &es_models.Event{ - AggregateID: "hodor-org", - AggregateType: model.OrgAggregate, - AggregateVersion: "v1", - CreationDate: time.Now().Add(-1 * time.Minute), - Data: []byte(`{"name": "hodor-org"}`), - EditorService: "testsvc", - EditorUser: "testuser", - ID: "sdlfö4t23kj", - ResourceOwner: "hodor-org", - Sequence: 32, - Type: model.OrgAdded, - } -} - -func orgDomainAddedEvent() *es_models.Event { - return &es_models.Event{ - AggregateID: "hodor-org", - AggregateType: model.OrgAggregate, - AggregateVersion: "v1", - CreationDate: time.Now().Add(-1 * time.Minute), - Data: []byte(`{"domain":"hodor.org"}`), - EditorService: "testsvc", - EditorUser: "testuser", - ID: "sdlfö4t23kj", - ResourceOwner: "hodor-org", - Sequence: 33, - Type: model.OrgDomainAdded, - } -} - -func orgDomainVerificationAddedEvent(token string) *es_models.Event { - data, _ := json.Marshal(&org_model.OrgDomain{ - Domain: "hodor.org", - ValidationType: org_model.OrgDomainValidationTypeDNS, - ValidationCode: &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc", - KeyID: "id", - Crypted: []byte(token), - }, - }) - return &es_models.Event{ - AggregateID: "hodor-org", - AggregateType: model.OrgAggregate, - AggregateVersion: "v1", - CreationDate: time.Now().Add(-1 * time.Minute), - Data: data, - EditorService: "testsvc", - EditorUser: "testuser", - ID: "sdlfö4t23kj", - ResourceOwner: "hodor-org", - Sequence: 34, - Type: model.OrgDomainVerificationAdded, - } -} - -func orgDomainVerifiedEvent() *es_models.Event { - return &es_models.Event{ - AggregateID: "hodor-org", - AggregateType: model.OrgAggregate, - AggregateVersion: "v1", - CreationDate: time.Now().Add(-1 * time.Minute), - Data: []byte(`{"domain":"hodor.org"}`), - EditorService: "testsvc", - EditorUser: "testuser", - ID: "sdlfö4t23kj", - ResourceOwner: "hodor-org", - Sequence: 35, - Type: model.OrgDomainVerified, - } -} - -func orgInactiveEvent() *es_models.Event { - return &es_models.Event{ - AggregateID: "hodor-org", - AggregateType: model.OrgAggregate, - AggregateVersion: "v1", - CreationDate: time.Now().Add(-1 * time.Minute), - Data: nil, - EditorService: "testsvc", - EditorUser: "testuser", - ID: "sdlfö4t23kj", - ResourceOwner: "hodor-org", - Sequence: 52, - Type: model.OrgDeactivated, - } -} - -func TestChangesOrg(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - id string - lastSequence uint64 - limit uint64 - } - type res struct { - changes *org_model.OrgChanges - org *model.Org - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "changes from events, ok", - args: args{ - es: GetMockChangesOrgOK(ctrl), - id: "1", - lastSequence: 0, - limit: 0, - }, - res: res{ - changes: &org_model.OrgChanges{Changes: []*org_model.OrgChange{{EventType: "", Sequence: 1, ModifierId: ""}}, LastSequence: 1}, - org: &model.Org{Name: "MusterOrg"}, - }, - }, - { - name: "changes from events, no events", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - id: "2", - lastSequence: 0, - limit: 0, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.OrgChanges(nil, tt.args.id, tt.args.lastSequence, tt.args.limit, false) - - org := &model.Org{} - if result != nil && len(result.Changes) > 0 { - b, err := json.Marshal(result.Changes[0].Data) - json.Unmarshal(b, org) - if err != nil { - } - } - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.LastSequence != tt.res.changes.LastSequence && org.Name != tt.res.org.Name { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.changes.LastSequence, result.LastSequence) - } - }) - } -} - -func TestAddIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - result *iam_model.IDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add idp, ok", - args: args{ - es: GetMockChangesOrgWithCrypto(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - Type: iam_model.IDPConfigTypeOIDC, - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - ClientSecretString: "ClientSecret", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - }, - res: res{ - result: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Name: "Name", - Type: iam_model.IDPConfigTypeOIDC, - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - }, - }, - { - name: "invalid idp config", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - ClientSecretString: "ClientSecret", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddIDPConfig(tt.args.ctx, tt.args.idp) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.IDPConfigID == "" { - t.Errorf("result has no id") - } - if result.OIDCConfig.IDPConfigID == "" { - t.Errorf("result has no id") - } - if result.OIDCConfig == nil && result.OIDCConfig.ClientSecret == nil { - t.Errorf("result has no client secret") - } - if result.Name != tt.res.result.Name { - t.Errorf("got wrong result key: expected: %v, actual: %v ", tt.res.result.Name, result.Name) - } - if result.OIDCConfig.ClientID != tt.res.result.OIDCConfig.ClientID { - t.Errorf("got wrong result key: expected: %v, actual: %v ", tt.res.result.OIDCConfig.ClientID, result.OIDCConfig.ClientID) - } - }) - } -} - -func TestChangeIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - result *iam_model.IDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change idp, ok", - args: args{ - es: GetMockChangesOrgWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "NameChanged", - }, - }, - res: res{ - result: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "NameChanged", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - }, - { - name: "invalid idp", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeIDPConfig(tt.args.ctx, tt.args.idp) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) - } - if result.Name != tt.res.result.Name { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.result.Name, result.Name) - } - }) - } -} - -func TestRemoveIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove idp, ok", - args: args{ - es: GetMockChangesOrgWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - }, - }, - }, - { - name: "no IDPConfigID", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing idp not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveIDPConfig(tt.args.ctx, tt.args.idp) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} -func TestDeactivateIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - result *iam_model.IDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate, ok", - args: args{ - es: GetMockChangesOrgWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - }, - res: res{ - result: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - State: iam_model.IDPConfigStateInactive, - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - }, - { - name: "no idp id", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.DeactivateIDPConfig(tt.args.ctx, tt.args.idp.AggregateID, tt.args.idp.IDPConfigID) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) - } - if result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - }) - } -} - -func TestReactivateIdpConfiguration(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - idp *iam_model.IDPConfig - } - type res struct { - result *iam_model.IDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate, ok", - args: args{ - es: GetMockChangesOrgWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - }, - res: res{ - result: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - State: iam_model.IDPConfigStateActive, - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - }, - { - name: "no idp id", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - idp: &iam_model.IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCConfig: &iam_model.OIDCIDPConfig{ - ClientID: "ClientID", - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ReactivateIDPConfig(tt.args.ctx, tt.args.idp.AggregateID, tt.args.idp.IDPConfigID) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - t.Errorf("got wrong result IDPConfigID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) - } - if result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - }) - } -} - -func TestChangeOIDCIDPConfig(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - config *iam_model.OIDCIDPConfig - } - type res struct { - result *iam_model.OIDCIDPConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change oidc config, ok", - args: args{ - es: GetMockChangesOrgWithOIDCIdp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientIDChange", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - res: res{ - result: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientIDChange", - }, - }, - }, - { - name: "invalid config", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp not existing", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientID", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &iam_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientID", - Issuer: "Issuer", - Scopes: []string{"scope"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeIDPOIDCConfig(tt.args.ctx, tt.args.config) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.AggregateID == "" { - t.Errorf("result has no id") - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.IDPConfigID, result.IDPConfigID) - } - if result.ClientID != tt.res.result.ClientID { - t.Errorf("got wrong result responsetype: expected: %v, actual: %v ", tt.res.result.ClientID, result.ClientID) - } - }) - } -} - -func TestAddLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.LoginPolicy - } - type res struct { - result *iam_model.LoginPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add login policy, ok", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - }, - }, - res: res{ - result: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddLoginPolicy(tt.args.ctx, tt.args.policy) - - if !tt.res.wantErr && result.AllowRegister != tt.res.result.AllowRegister { - t.Errorf("got wrong result AllowRegister: expected: %v, actual: %v ", tt.res.result.AllowRegister, result.AllowRegister) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.LoginPolicy - } - type res struct { - result *iam_model.LoginPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add login policy, ok", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - AllowExternalIdp: false, - AllowUsernamePassword: false, - }, - }, - res: res{ - result: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - AllowExternalIdp: false, - AllowUsernamePassword: false, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeLoginPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.AllowRegister != tt.res.result.AllowRegister { - t.Errorf("got wrong result AllowRegister: expected: %v, actual: %v ", tt.res.result.AllowRegister, result.AllowRegister) - } - if result.AllowUsernamePassword != tt.res.result.AllowUsernamePassword { - t.Errorf("got wrong result AllowUsernamePassword: expected: %v, actual: %v ", tt.res.result.AllowUsernamePassword, result.AllowUsernamePassword) - } - if result.AllowExternalIdp != tt.res.result.AllowExternalIdp { - t.Errorf("got wrong result AllowExternalIDP: expected: %v, actual: %v ", tt.res.result.AllowExternalIdp, result.AllowExternalIdp) - } - }) - } -} - -func TestRemoveLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.LoginPolicy - } - type res struct { - result *iam_model.LoginPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove login policy, ok", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AllowRegister: true, - AllowExternalIdp: false, - AllowUsernamePassword: false, - }, - }, - res: res{}, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LoginPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveLoginPolicy(tt.args.ctx, tt.args.policy) - - if !tt.res.wantErr && err != nil { - t.Errorf("got wrong result should not get err: %v", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddIdpProviderToLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - provider *iam_model.IDPProvider - } - type res struct { - result *iam_model.IDPProvider - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add idp to login policy, ok", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IdpConfigID2", - Type: iam_model.IDPProviderTypeSystem, - }, - }, - res: res{ - result: &iam_model.IDPProvider{IDPConfigID: "IdpConfigID2"}, - }, - }, - { - name: "add idp to login policy, already existing", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - Type: iam_model.IDPProviderTypeSystem, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "invalid provider", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IdpConfigID2", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddIDPProviderToLoginPolicy(tt.args.ctx, tt.args.provider) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.IDPConfigID != tt.res.result.IDPConfigID { - 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 KeyType: expected: %v, actual: %v ", tt.res.result.Type, result.Type) - } - }) - } -} - -func TestRemoveIdpProviderFromLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - provider *iam_model.IDPProvider - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove idp to login policy, ok", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IDPConfigID", - Type: iam_model.IDPProviderTypeSystem, - }, - }, - res: res{}, - }, - { - name: "remove idp to login policy, not existing", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IdpConfigID2", - Type: iam_model.IDPProviderTypeSystem, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "invalid provider", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - provider: &iam_model.IDPProvider{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - IDPConfigID: "IdpConfigID2", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveIDPProviderFromLoginPolicy(tt.args.ctx, tt.args.provider) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err: %v ", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddSecondFactorToLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - aggregateID string - mfa iam_model.SecondFactorType - } - type res struct { - result iam_model.SecondFactorType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add second factor to login policy, ok", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - result: iam_model.SecondFactorTypeOTP, - }, - }, - { - name: "add second factor to login policy, already existing", - args: args{ - es: GetMockChangesOrgWithLoginPolicyWithMFA(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "invalid mfa", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeUnspecified, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "Test", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddSecondFactorToLoginPolicy(tt.args.ctx, tt.args.aggregateID, tt.args.mfa) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result != tt.res.result { - t.Errorf("got wrong result : expected: %v, actual: %v ", tt.res.result, result) - } - }) - } -} - -func TestRemoveSecondFactorFromLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - aggregateID string - mfa iam_model.SecondFactorType - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove second factor from login policy, ok", - args: args{ - es: GetMockChangesOrgWithLoginPolicyWithMFA(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{}, - }, - { - name: "remove second factor from login policy, not existing", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "invalid provider", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.SecondFactorTypeUnspecified, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "Test", - mfa: iam_model.SecondFactorTypeOTP, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveSecondFactorFromLoginPolicy(tt.args.ctx, tt.args.aggregateID, tt.args.mfa) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err: %v ", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddMultiFactorToLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - aggregateID string - mfa iam_model.MultiFactorType - } - type res struct { - result iam_model.MultiFactorType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mfa to login policy, ok", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - result: iam_model.MultiFactorTypeU2FWithPIN, - }, - }, - { - name: "add mfa to login policy, already existing", - args: args{ - es: GetMockChangesOrgWithLoginPolicyWithMFA(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "invalid mfa", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeUnspecified, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "Test", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddMultiFactorToLoginPolicy(tt.args.ctx, tt.args.aggregateID, tt.args.mfa) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result != tt.res.result { - t.Errorf("got wrong result : expected: %v, actual: %v ", tt.res.result, result) - } - }) - } -} - -func TestRemoveMultiFactorFromLoginPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - aggregateID string - mfa iam_model.MultiFactorType - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove mfa from login policy, ok", - args: args{ - es: GetMockChangesOrgWithLoginPolicyWithMFA(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{}, - }, - { - name: "remove mfa from login policy, not existing", - args: args{ - es: GetMockChangesOrgWithLoginPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "invalid provider", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "AggregateID", - mfa: iam_model.MultiFactorTypeUnspecified, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - aggregateID: "Test", - mfa: iam_model.MultiFactorTypeU2FWithPIN, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveMultiFactorFromLoginPolicy(tt.args.ctx, tt.args.aggregateID, tt.args.mfa) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err: %v ", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddLabelPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.LabelPolicy - } - type res struct { - result *iam_model.LabelPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add label policy, ok", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - PrimaryColor: "000000", - }, - }, - res: res{ - result: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - PrimaryColor: "000000", - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddLabelPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.PrimaryColor != tt.res.result.PrimaryColor { - t.Errorf("got wrong result PrimaryColor: expected: %v, actual: %v ", tt.res.result.PrimaryColor, result.PrimaryColor) - } - }) - } -} - -func TestChangeLabelPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.LabelPolicy - } - type res struct { - result *iam_model.LabelPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add label policy, ok", - args: args{ - es: GetMockChangesOrgWithLabelPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - PrimaryColor: "000000", - SecondaryColor: "FFFFFF", - }, - }, - res: res{ - result: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - PrimaryColor: "000000", - SecondaryColor: "FFFFFF", - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.LabelPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeLabelPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.PrimaryColor != tt.res.result.PrimaryColor { - t.Errorf("got wrong result PrimaryColor: expected: %v, actual: %v ", tt.res.result.PrimaryColor, result.PrimaryColor) - } - if result.SecondaryColor != tt.res.result.SecondaryColor { - t.Errorf("got wrong result SecondaryColor: expected: %v, actual: %v ", tt.res.result.SecondaryColor, result.SecondaryColor) - } - }) - } -} -func TestAddPasswordComplexityPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicy - } - type res struct { - result *iam_model.PasswordComplexityPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password complexity policy, ok", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 10, - HasLowercase: true, - HasUppercase: true, - HasSymbol: true, - HasNumber: true, - }, - }, - res: res{ - result: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 10, - HasLowercase: true, - HasUppercase: true, - HasSymbol: true, - HasNumber: true, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddPasswordComplexityPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MinLength != tt.res.result.MinLength { - t.Errorf("got wrong result MinLength: expected: %v, actual: %v ", tt.res.result.MinLength, result.MinLength) - } - if result.HasLowercase != tt.res.result.HasLowercase { - t.Errorf("got wrong result HasLowercase: expected: %v, actual: %v ", tt.res.result.HasLowercase, result.HasLowercase) - } - if result.HasUppercase != tt.res.result.HasUppercase { - t.Errorf("got wrong result HasUppercase: expected: %v, actual: %v ", tt.res.result.HasUppercase, result.HasUppercase) - } - if result.HasNumber != tt.res.result.HasNumber { - t.Errorf("got wrong result HasNumber: expected: %v, actual: %v ", tt.res.result.HasNumber, result.HasNumber) - } - if result.HasSymbol != tt.res.result.HasSymbol { - t.Errorf("got wrong result HasSymbol: expected: %v, actual: %v ", tt.res.result.HasSymbol, result.HasSymbol) - } - }) - } -} - -func TestChangePasswordComplexityPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicy - } - type res struct { - result *iam_model.PasswordComplexityPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password complexity policy, ok", - args: args{ - es: GetMockChangesOrgWithPasswordComplexityPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 5, - HasLowercase: false, - HasUppercase: false, - HasSymbol: false, - HasNumber: false, - }, - }, - res: res{ - result: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 5, - HasLowercase: false, - HasUppercase: false, - HasSymbol: false, - HasNumber: false, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MinLength: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangePasswordComplexityPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MinLength != tt.res.result.MinLength { - t.Errorf("got wrong result MinLength: expected: %v, actual: %v ", tt.res.result.MinLength, result.MinLength) - } - if result.HasLowercase != tt.res.result.HasLowercase { - t.Errorf("got wrong result HasLowercase: expected: %v, actual: %v ", tt.res.result.HasLowercase, result.HasLowercase) - } - if result.HasUppercase != tt.res.result.HasUppercase { - t.Errorf("got wrong result HasUppercase: expected: %v, actual: %v ", tt.res.result.HasUppercase, result.HasUppercase) - } - if result.HasNumber != tt.res.result.HasNumber { - t.Errorf("got wrong result HasNumber: expected: %v, actual: %v ", tt.res.result.HasNumber, result.HasNumber) - } - if result.HasSymbol != tt.res.result.HasSymbol { - t.Errorf("got wrong result HasSymbol: expected: %v, actual: %v ", tt.res.result.HasSymbol, result.HasSymbol) - } - }) - } -} - -func TestRemovePasswordComplexityPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicy - } - type res struct { - result *iam_model.PasswordComplexityPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove password compelxity policy, ok", - args: args{ - es: GetMockChangesOrgWithPasswordComplexityPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{}, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemovePasswordComplexityPolicy(tt.args.ctx, tt.args.policy) - - if !tt.res.wantErr && err != nil { - t.Errorf("got wrong result should not get err: %v", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddPasswordAgePolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordAgePolicy - } - type res struct { - result *iam_model.PasswordAgePolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password age policy, ok", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 10, - ExpireWarnDays: 10, - }, - }, - res: res{ - result: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 10, - ExpireWarnDays: 10, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 10, - ExpireWarnDays: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddPasswordAgePolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MaxAgeDays != tt.res.result.MaxAgeDays { - t.Errorf("got wrong result MaxAgeDays: expected: %v, actual: %v ", tt.res.result.MaxAgeDays, result.MaxAgeDays) - } - if result.ExpireWarnDays != tt.res.result.ExpireWarnDays { - t.Errorf("got wrong result.ExpireWarnDays: expected: %v, actual: %v ", tt.res.result.ExpireWarnDays, result.ExpireWarnDays) - } - }) - } -} - -func TestChangePasswordAgePolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordAgePolicy - } - type res struct { - result *iam_model.PasswordAgePolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password age policy, ok", - args: args{ - es: GetMockChangesOrgWithPasswordAgePolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 5, - ExpireWarnDays: 5, - }, - }, - res: res{ - result: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 5, - ExpireWarnDays: 5, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAgeDays: 10, - ExpireWarnDays: 10, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangePasswordAgePolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MaxAgeDays != tt.res.result.MaxAgeDays { - t.Errorf("got wrong result MaxAgeDays: expected: %v, actual: %v ", tt.res.result.MaxAgeDays, result.MaxAgeDays) - } - if result.ExpireWarnDays != tt.res.result.ExpireWarnDays { - t.Errorf("got wrong result.ExpireWarnDays: expected: %v, actual: %v ", tt.res.result.ExpireWarnDays, result.ExpireWarnDays) - } - }) - } -} - -func TestRemovePasswordAgePolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordAgePolicy - } - type res struct { - result *iam_model.PasswordAgePolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove password age policy, ok", - args: args{ - es: GetMockChangesOrgWithPasswordAgePolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{}, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordAgePolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemovePasswordAgePolicy(tt.args.ctx, tt.args.policy) - - if !tt.res.wantErr && err != nil { - t.Errorf("got wrong result should not get err: %v", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddPasswordLockoutPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordLockoutPolicy - } - type res struct { - result *iam_model.PasswordLockoutPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password lockout policy, ok", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 10, - ShowLockOutFailures: true, - }, - }, - res: res{ - result: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 10, - ShowLockOutFailures: true, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 10, - ShowLockOutFailures: true, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddPasswordLockoutPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MaxAttempts != tt.res.result.MaxAttempts { - t.Errorf("got wrong result MaxAttempts: expected: %v, actual: %v ", tt.res.result.MaxAttempts, result.MaxAttempts) - } - if result.ShowLockOutFailures != tt.res.result.ShowLockOutFailures { - t.Errorf("got wrong result.ShowLockOutFailures: expected: %v, actual: %v ", tt.res.result.ShowLockOutFailures, result.ShowLockOutFailures) - } - }) - } -} - -func TestChangePasswordLockoutPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordLockoutPolicy - } - type res struct { - result *iam_model.PasswordLockoutPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password lockout policy, ok", - args: args{ - es: GetMockChangesOrgWithPasswordLockoutPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 5, - ShowLockOutFailures: false, - }, - }, - res: res{ - result: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 5, - ShowLockOutFailures: false, - }, - }, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MaxAttempts: 10, - ShowLockOutFailures: true, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangePasswordLockoutPolicy(tt.args.ctx, tt.args.policy) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MaxAttempts != tt.res.result.MaxAttempts { - t.Errorf("got wrong result MaxAttempts: expected: %v, actual: %v ", tt.res.result.MaxAttempts, result.MaxAttempts) - } - if result.ShowLockOutFailures != tt.res.result.ShowLockOutFailures { - t.Errorf("got wrong result.ShowLockOutFailures: expected: %v, actual: %v ", tt.res.result.ShowLockOutFailures, result.ShowLockOutFailures) - } - }) - } -} - -func TestRemovePasswordLockoutPolicy(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - policy *iam_model.PasswordLockoutPolicy - } - type res struct { - result *iam_model.PasswordLockoutPolicy - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove password lockout policy, ok", - args: args{ - es: GetMockChangesOrgWithPasswordLockoutPolicy(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{}, - }, - { - name: "invalid policy", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordLockoutPolicy{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemovePasswordLockoutPolicy(tt.args.ctx, tt.args.policy) - - if !tt.res.wantErr && err != nil { - t.Errorf("got wrong result should not get err: %v", err) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddMailTemplate(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - template *iam_model.MailTemplate - } - type res struct { - result *iam_model.MailTemplate - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add label template, ok", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - res: res{ - result: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - }, - { - name: "invalid template", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddMailTemplate(tt.args.ctx, tt.args.template) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.Template) != string(tt.res.result.Template) { - t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) - } - }) - } -} - -func TestChangeMailTemplate(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - template *iam_model.MailTemplate - } - type res struct { - result *iam_model.MailTemplate - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mail template, ok", - args: args{ - es: GetMockChangesOrgWithMailTemplate(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - res: res{ - result: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - Template: []byte(""), - }, - }, - }, - { - name: "invalid template", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - template: &iam_model.MailTemplate{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeMailTemplate(tt.args.ctx, tt.args.template) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.Template) != string(tt.res.result.Template) { - t.Errorf("got wrong result Template: expected: %v, actual: %v ", tt.res.result.Template, result.Template) - } - }) - } -} - -func TestAddMailText(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - mailtext *iam_model.MailText - } - type res struct { - result *iam_model.MailText - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add label mailtext, ok", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - mailtext: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", - Language: "DE", - }, - }, - res: res{ - result: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", - Language: "DE", - }, - }, - }, - { - name: "invalid mailtext", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - mailtext: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing org not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - mailtext: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddMailText(tt.args.ctx, tt.args.mailtext) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if result.MailTextType != tt.res.result.MailTextType { - t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) - } - }) - } -} - -func TestChangeMailText(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *OrgEventstore - ctx context.Context - mailtext *iam_model.MailText - } - type res struct { - result *iam_model.MailText - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add label mailtext, ok", - args: args{ - es: GetMockChangesOrgWithMailText(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - mailtext: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", - Language: "DE", - }, - }, - res: res{ - result: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - MailTextType: "Type", - Language: "DE", - }, - }, - }, - { - name: "invalid mailtext", - args: args{ - es: GetMockChangesOrgOK(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - mailtext: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing iam not found", - args: args{ - es: GetMockChangesOrgNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - mailtext: &iam_model.MailText{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeMailText(tt.args.ctx, tt.args.mailtext) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if string(result.MailTextType) != string(tt.res.result.MailTextType) { - t.Errorf("got wrong result MailTextType: expected: %v, actual: %v ", tt.res.result.MailTextType, result.MailTextType) - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/label_policy.go b/internal/org/repository/eventsourcing/label_policy.go deleted file mode 100644 index 051f5e025e..0000000000 --- a/internal/org/repository/eventsourcing/label_policy.go +++ /dev/null @@ -1,77 +0,0 @@ -package eventsourcing - -import ( - "context" - - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func LabelPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.LabelPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-TUWod", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingLabelPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LabelPolicyAdded, policy) - } -} - -func LabelPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.LabelPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-unRI2", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - changes := existing.LabelPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Tz130", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.LabelPolicyChanged, changes) - } -} - -func LabelPolicyRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-v7E9b", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.LabelPolicyRemoved, nil) - } -} - -func checkExistingLabelPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existing := false - for _, event := range events { - switch event.Type { - case model.LabelPolicyAdded: - existing = true - case model.LabelPolicyRemoved: - existing = false - } - } - if existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-g9mCI", "Errors.Org.LabelPolicy.AlreadyExists") - } - return nil - } -} diff --git a/internal/org/repository/eventsourcing/label_policy_test.go b/internal/org/repository/eventsourcing/label_policy_test.go deleted file mode 100644 index 9be177f664..0000000000 --- a/internal/org/repository/eventsourcing/label_policy_test.go +++ /dev/null @@ -1,186 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func TestLabelPolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.LabelPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add label policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.LabelPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - PrimaryColor: "000000", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LabelPolicyAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "label policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LabelPolicyAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLabelPolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.LabelPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change label policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - LabelPolicy: &iam_es_model.LabelPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - new: &iam_es_model.LabelPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - PrimaryColor: "000000", - SecondaryColor: "FFFFFF", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LabelPolicyChanged}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "label policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LabelPolicyChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/login_policy.go b/internal/org/repository/eventsourcing/login_policy.go deleted file mode 100644 index def04a04b0..0000000000 --- a/internal/org/repository/eventsourcing/login_policy.go +++ /dev/null @@ -1,331 +0,0 @@ -package eventsourcing - -import ( - "context" - "github.com/caos/zitadel/internal/errors" - es_models "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/org/repository/eventsourcing/model" -) - -func LoginPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, policy *iam_es_model.LoginPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smla8", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDFilter(org.AggregateID) - - validation := checkExistingLoginPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LoginPolicyAdded, policy) - } -} - -func LoginPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, policy *iam_es_model.LoginPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Mlco9", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - changes := org.LoginPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smk8d", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.LoginPolicyChanged, changes) - } -} - -func LoginPolicyRemovedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if org == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-S8sio", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.LoginPolicyRemoved, nil) - } -} - -func LoginPolicyIDPProviderAddedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, provider *iam_es_model.IDPProvider, iamID string) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if provider == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sml9d", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate, iam_es_model.IAMAggregate). - AggregateIDsFilter(org.AggregateID, iamID) - - validation := checkExistingLoginPolicyIDPProviderValidation(provider) - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LoginPolicyIDPProviderAdded, provider) - } -} - -func LoginPolicyIDPProviderRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, org *model.Org, provider *iam_es_model.IDPProviderID, cascade bool) (*es_models.Aggregate, error) { - if provider == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sml9d", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - eventType := model.LoginPolicyIDPProviderRemoved - if cascade { - eventType = model.LoginPolicyIDPProviderCascadeRemoved - } - return agg.AppendEvent(eventType, provider) -} - -func LoginPolicySecondFactorAddedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, mfa *iam_es_model.MFA, iamID string) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mfa == nil || org == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-5Gk9s", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDsFilter(org.AggregateID) - - validation := checkExistingLoginPolicySecondFactorValidation(mfa.MFAType) - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LoginPolicySecondFactorAdded, mfa) - } -} - -func LoginPolicySecondFactorRemovedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, mfa *iam_es_model.MFA) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mfa == nil || org == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Sml9d", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.LoginPolicySecondFactorRemoved, mfa) - } -} - -func LoginPolicyMultiFactorAddedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, mfa *iam_es_model.MFA, iamID string) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mfa == nil || org == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4Bm9s", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDsFilter(org.AggregateID) - - validation := checkExistingLoginPolicyMultiFactorValidation(mfa.MFAType) - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.LoginPolicyMultiFactorAdded, mfa) - } -} - -func LoginPolicyMultiFactorRemovedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, mfa *iam_es_model.MFA) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mfa == nil || org == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-6Nm9s", "Errors.Internal") - } - - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.LoginPolicyMultiFactorRemoved, mfa) - } -} - -func checkExistingLoginPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existing := false - for _, event := range events { - switch event.Type { - case model.LoginPolicyAdded: - existing = true - case model.LoginPolicyRemoved: - existing = false - } - } - if existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-Nsh8u", "Errors.Org.LoginPolicy.AlreadyExists") - } - return nil - } -} - -func checkExistingLoginPolicyIDPProviderValidation(idpProvider *iam_es_model.IDPProvider) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - idpConfigs := make([]*iam_es_model.IDPConfig, 0) - idps := make([]*iam_es_model.IDPProvider, 0) - for _, event := range events { - switch event.Type { - case model.IDPConfigAdded, iam_es_model.IDPConfigAdded: - config := new(iam_es_model.IDPConfig) - err := config.SetData(event) - if err != nil { - return err - } - idpConfigs = append(idpConfigs, config) - if event.AggregateType == model.OrgAggregate { - config.Type = int32(iam_model.IDPProviderTypeOrg) - } else { - config.Type = int32(iam_model.IDPProviderTypeSystem) - } - case model.IDPConfigRemoved, iam_es_model.IDPConfigRemoved: - config := new(iam_es_model.IDPConfig) - err := config.SetData(event) - if err != nil { - return err - } - for i := len(idpConfigs) - 1; i >= 0; i-- { - if idpConfigs[i].IDPConfigID == config.IDPConfigID { - idpConfigs[i] = idpConfigs[len(idpConfigs)-1] - idpConfigs[len(idpConfigs)-1] = nil - idpConfigs = idpConfigs[:len(idpConfigs)-1] - break - } - } - case model.LoginPolicyIDPProviderAdded: - idp := new(iam_es_model.IDPProvider) - err := idp.SetData(event) - if err != nil { - return err - } - idps = append(idps, idp) - case model.LoginPolicyIDPProviderRemoved, model.LoginPolicyIDPProviderCascadeRemoved: - idp := new(iam_es_model.IDPProvider) - err := idp.SetData(event) - if err != nil { - return err - } - for i := len(idps) - 1; i >= 0; i-- { - if idps[i].IDPConfigID == idp.IDPConfigID { - idps[i] = idps[len(idps)-1] - idps[len(idps)-1] = nil - idps = idps[:len(idps)-1] - break - } - } - case model.LoginPolicyRemoved: - idps = make([]*iam_es_model.IDPProvider, 0) - } - } - exists := false - for _, p := range idpConfigs { - if p.IDPConfigID == idpProvider.IDPConfigID && p.Type == idpProvider.Type { - exists = true - } - } - if !exists { - return errors.ThrowPreconditionFailed(nil, "EVENT-Djlo9", "Errors.IAM.IdpNotExisting") - } - for _, p := range idps { - if p.IDPConfigID == idpProvider.IDPConfigID { - return errors.ThrowPreconditionFailed(nil, "EVENT-us5Zw", "Errors.Org.LoginPolicy.IdpProviderAlreadyExisting") - } - } - return nil - } -} - -func checkExistingLoginPolicySecondFactorValidation(mfaType int32) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - mfas := make([]int32, 0) - for _, event := range events { - switch event.Type { - case model.LoginPolicySecondFactorAdded: - mfa := new(iam_es_model.MFA) - err := mfa.SetData(event) - if err != nil { - return err - } - mfas = append(mfas, mfa.MFAType) - case model.LoginPolicySecondFactorRemoved: - idp := new(iam_es_model.IDPProvider) - err := idp.SetData(event) - if err != nil { - return err - } - for i := len(mfas) - 1; i >= 0; i-- { - if mfas[i] == mfaType { - mfas[i] = mfas[len(mfas)-1] - mfas[len(mfas)-1] = 0 - mfas = mfas[:len(mfas)-1] - break - } - } - case model.LoginPolicyRemoved: - mfas = make([]int32, 0) - } - } - - for _, m := range mfas { - if m == mfaType { - return errors.ThrowPreconditionFailed(nil, "EVENT-4Bo0sw", "Errors.Org.LoginPolicy.MFA.AlreadyExisting") - } - } - return nil - } -} - -func checkExistingLoginPolicyMultiFactorValidation(mfaType int32) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - mfas := make([]int32, 0) - for _, event := range events { - switch event.Type { - case model.LoginPolicyMultiFactorAdded: - mfa := new(iam_es_model.MFA) - err := mfa.SetData(event) - if err != nil { - return err - } - mfas = append(mfas, mfa.MFAType) - case model.LoginPolicyMultiFactorRemoved: - idp := new(iam_es_model.IDPProvider) - err := idp.SetData(event) - if err != nil { - return err - } - for i := len(mfas) - 1; i >= 0; i-- { - if mfas[i] == mfaType { - mfas[i] = mfas[len(mfas)-1] - mfas[len(mfas)-1] = 0 - mfas = mfas[:len(mfas)-1] - break - } - } - case model.LoginPolicyRemoved: - mfas = make([]int32, 0) - } - } - - for _, m := range mfas { - if m == mfaType { - return errors.ThrowPreconditionFailed(nil, "EVENT-4Bo0sw", "Errors.Org.LoginPolicy.MFA.AlreadyExisting") - } - } - return nil - } -} diff --git a/internal/org/repository/eventsourcing/login_policy_test.go b/internal/org/repository/eventsourcing/login_policy_test.go deleted file mode 100644 index e4c11d5215..0000000000 --- a/internal/org/repository/eventsourcing/login_policy_test.go +++ /dev/null @@ -1,793 +0,0 @@ -package eventsourcing - -import ( - "context" - "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" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - "testing" -) - -func TestLoginPolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.LoginPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add login polciy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.LoginPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AllowUsernamePassword: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "login policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestLoginPolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.LoginPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - LoginPolicy: &iam_es_model.LoginPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - new: &iam_es_model.LoginPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AllowUsernamePassword: true, - AllowRegister: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyChanged}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "login policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestLoginPolicyRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - LoginPolicy: &iam_es_model.LoginPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyRemoved}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyRemovedAggregate(tt.args.aggCreator, tt.args.existing)(tt.args.ctx) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - }) - } -} - -func TestLoginPolicyIdpProviderAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.IDPProvider - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add idp provider to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.IDPProvider{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Type: int32(iam_model.IDPProviderTypeSystem), - IDPConfigID: "IDPConfigID", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyIDPProviderAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - 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) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestLoginPolicyIdpProviderRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.IDPProviderID - cascade bool - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove idp provider to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - LoginPolicy: &iam_es_model.LoginPolicy{ - AllowUsernamePassword: true, - IDPProviders: []*iam_es_model.IDPProvider{ - {IDPConfigID: "IDPConfigID", Type: int32(iam_model.IDPProviderTypeSystem)}, - }, - }}, - new: &iam_es_model.IDPProviderID{ - IDPConfigID: "IDPConfigID", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyIDPProviderRemoved}, - }, - }, - { - name: "remove idp provider to login policy cascade", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - LoginPolicy: &iam_es_model.LoginPolicy{ - AllowUsernamePassword: true, - IDPProviders: []*iam_es_model.IDPProvider{ - {IDPConfigID: "IDPConfigID", Type: int32(iam_model.IDPProviderTypeSystem)}, - }, - }}, - new: &iam_es_model.IDPProviderID{ - IDPConfigID: "IDPConfigID", - }, - cascade: true, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyIDPProviderCascadeRemoved}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "idp config config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyIDPProviderRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existing, tt.args.new, tt.args.cascade) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestLoginPolicySecondFactorAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.MFA - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add second factor to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.MFA{ - MFAType: int32(iam_model.SecondFactorTypeOTP), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicySecondFactorAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mfa nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - 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) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && (agg == nil || len(agg.Events) != tt.res.eventLen) { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - return - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - }) - } -} - -func TestLoginPolicySecondFactorRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.MFA - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove second factor from login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - LoginPolicy: &iam_es_model.LoginPolicy{ - AllowUsernamePassword: true, - SecondFactors: []int32{ - int32(iam_model.SecondFactorTypeOTP), - }, - }}, - new: &iam_es_model.MFA{ - MFAType: int32(iam_model.SecondFactorTypeOTP), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicySecondFactorRemoved}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mfa nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicySecondFactorRemovedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestLoginPolicyMultiFactorAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.MFA - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mfa to login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.MFA{ - MFAType: int32(iam_model.MultiFactorTypeU2FWithPIN), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyMultiFactorAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mfa nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - 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) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && (agg == nil || len(agg.Events) != tt.res.eventLen) { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - return - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - }) - } -} - -func TestLoginPolicyMultiFactorRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.MFA - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove mfa from login policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - LoginPolicy: &iam_es_model.LoginPolicy{ - AllowUsernamePassword: true, - MultiFactors: []int32{ - int32(iam_model.MultiFactorTypeU2FWithPIN), - }, - }}, - new: &iam_es_model.MFA{ - MFAType: int32(iam_model.MultiFactorTypeU2FWithPIN), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.LoginPolicyMultiFactorRemoved}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mfa nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := LoginPolicyMultiFactorRemovedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if tt.res.wantErr && !tt.res.errFunc(err) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/mail_template.go b/internal/org/repository/eventsourcing/mail_template.go deleted file mode 100644 index f185b1c07d..0000000000 --- a/internal/org/repository/eventsourcing/mail_template.go +++ /dev/null @@ -1,77 +0,0 @@ -package eventsourcing - -import ( - "context" - - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func MailTemplateAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4BeRi", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingMailTemplateValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.MailTemplateAdded, policy) - } -} - -func MailTemplateChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, template *iam_es_model.MailTemplate) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if template == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-yzXO0", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - changes := existing.MailTemplate.Changes(template) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-erTCI", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.MailTemplateChanged, changes) - } -} - -func MailTemplateRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-2jVit", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.MailTemplateRemoved, nil) - } -} - -func checkExistingMailTemplateValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existing := false - for _, event := range events { - switch event.Type { - case model.MailTemplateAdded: - existing = true - case model.MailTemplateRemoved: - existing = false - } - } - if existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-aUH4D", "Errors.Org.MailTemplate.AlreadyExists") - } - return nil - } -} diff --git a/internal/org/repository/eventsourcing/mail_template_test.go b/internal/org/repository/eventsourcing/mail_template_test.go deleted file mode 100644 index bd2b10ce06..0000000000 --- a/internal/org/repository/eventsourcing/mail_template_test.go +++ /dev/null @@ -1,185 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func TestMailTemplateAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.MailTemplate - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mailtemplate", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.MailTemplate{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Template: []byte(""), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.MailTemplateAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mailtemplate config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := MailTemplateAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestMailTemplateChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.MailTemplate - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change mailtemplate", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MailTemplate: &iam_es_model.MailTemplate{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - new: &iam_es_model.MailTemplate{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Template: []byte(""), - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.MailTemplateChanged}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mailtemplate config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := MailTemplateChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/mail_text.go b/internal/org/repository/eventsourcing/mail_text.go deleted file mode 100644 index 2f6ea08b13..0000000000 --- a/internal/org/repository/eventsourcing/mail_text.go +++ /dev/null @@ -1,94 +0,0 @@ -package eventsourcing - -import ( - "context" - - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func MailTextAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, mailText *iam_es_model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mailText == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Gk3Cn", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingMailTextValidation(mailText, existing.MailTexts) - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.MailTextAdded, mailText) - } -} - -func MailTextChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, mailText *iam_es_model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if mailText == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Hog8a", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - changes := make(map[string]interface{}, 2) - for _, exMailText := range existing.MailTexts { - if exMailText.MailTextType == mailText.MailTextType && exMailText.Language == mailText.Language { - changes = exMailText.Changes(mailText) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-DuRxA", "Errors.NoChangesFound") - } - } - } - return agg.AppendEvent(model.MailTextChanged, changes) - } -} - -func MailTextRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, mailText *iam_es_model.MailText) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-cJ5Wp", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - changes := make(map[string]interface{}, 2) - for _, exMailText := range existing.MailTexts { - if exMailText.MailTextType == mailText.MailTextType && exMailText.Language == mailText.Language { - mailText.ButtonText = exMailText.ButtonText - mailText.Greeting = exMailText.Greeting - mailText.Text = exMailText.Text - mailText.Title = exMailText.Title - mailText.Subject = exMailText.Subject - mailText.PreHeader = exMailText.PreHeader - changes = exMailText.Changes(mailText) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-DuRxA", "Errors.NoChangesFound") - } - } - } - return agg.AppendEvent(model.MailTextRemoved, changes) - } -} - -func checkExistingMailTextValidation(mailText *iam_es_model.MailText, existingMailTexts []*iam_es_model.MailText) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existing := false - for _, text := range existingMailTexts { - if text.MailTextType == mailText.MailTextType && text.Language == mailText.Language { - existing = true - } - } - if existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-zEZh7", "Errors.Org.MailText.AlreadyExists") - } - return nil - } -} diff --git a/internal/org/repository/eventsourcing/mail_text_test.go b/internal/org/repository/eventsourcing/mail_text_test.go deleted file mode 100644 index f6b1879ead..0000000000 --- a/internal/org/repository/eventsourcing/mail_text_test.go +++ /dev/null @@ -1,188 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func TestMailTextAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.MailText - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add mailtext", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.MailText{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MailTextType: "Type", - Language: "DE", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.MailTextAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mailtext config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := MailTextAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestMailTextChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.MailText - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change mailtext", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MailTexts: []*iam_es_model.MailText{&iam_es_model.MailText{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - }, - }, - new: &iam_es_model.MailText{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MailTextType: "Type", - Language: "DE", - Subject: "Subject", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.MailTextChanged}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "mailtext config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := MailTextChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/org.go b/internal/org/repository/eventsourcing/org.go index aa035a16a3..9e112ec618 100644 --- a/internal/org/repository/eventsourcing/org.go +++ b/internal/org/repository/eventsourcing/org.go @@ -5,8 +5,6 @@ import ( "github.com/caos/zitadel/internal/errors" es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - org_model "github.com/caos/zitadel/internal/org/model" "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" ) @@ -43,428 +41,3 @@ func OrgQuery(latestSequence uint64) *es_models.SearchQuery { func OrgAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, id string, sequence uint64) (*es_models.Aggregate, error) { return aggCreator.NewAggregate(ctx, id, model.OrgAggregate, model.OrgVersion, sequence, es_models.OverwriteResourceOwner(id)) } - -func orgCreatedAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, org *model.Org, users func(context.Context, string) ([]*es_models.Aggregate, error)) (_ []*es_models.Aggregate, err error) { - if org == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kdie7", "Errors.Internal") - } - - agg, err := aggCreator.NewAggregate(ctx, org.AggregateID, model.OrgAggregate, model.OrgVersion, org.Sequence, es_models.OverwriteResourceOwner(org.AggregateID)) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.OrgAdded, org) - if err != nil { - return nil, err - } - aggregates := make([]*es_models.Aggregate, 0) - aggregates, err = addDomainAggregateAndEvents(ctx, aggCreator, agg, aggregates, org, users) - if err != nil { - return nil, err - } - nameAggregate, err := reservedUniqueNameAggregate(ctx, aggCreator, org.AggregateID, org.Name) - if err != nil { - return nil, err - } - aggregates = append(aggregates, nameAggregate) - return append(aggregates, agg), nil -} - -func addDomainAggregateAndEvents(ctx context.Context, aggCreator *es_models.AggregateCreator, orgAggregate *es_models.Aggregate, aggregates []*es_models.Aggregate, org *model.Org, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) { - for _, domain := range org.Domains { - orgAggregate, err := orgAggregate.AppendEvent(model.OrgDomainAdded, domain) - if err != nil { - return nil, err - } - if domain.Verified { - domainAggregates, err := orgDomainVerified(ctx, aggCreator, orgAggregate, org, domain, users) - if err != nil { - return nil, err - } - aggregates = append(aggregates, domainAggregates...) - } - if domain.Primary { - orgAggregate, err = orgAggregate.AppendEvent(model.OrgDomainPrimarySet, domain) - if err != nil { - return nil, err - } - } - } - return aggregates, nil -} - -func OrgUpdateAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, existingOrg *model.Org, updatedOrg *model.Org) ([]*es_models.Aggregate, error) { - if existingOrg == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dk83d", "Errors.Internal") - } - if updatedOrg == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal") - } - changes := existingOrg.Changes(updatedOrg) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-E0hc5", "Errors.NoChangesFound") - } - - aggregates := make([]*es_models.Aggregate, 0, 3) - - if name, ok := changes["name"]; ok { - nameAggregate, err := reservedUniqueNameAggregate(ctx, aggCreator, "", name.(string)) - if err != nil { - return nil, err - } - aggregates = append(aggregates, nameAggregate) - nameReleasedAggregate, err := releasedUniqueNameAggregate(ctx, aggCreator, "", existingOrg.Name) - if err != nil { - return nil, err - } - aggregates = append(aggregates, nameReleasedAggregate) - } - - orgAggregate, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence) - if err != nil { - return nil, err - } - - orgAggregate, err = orgAggregate.AppendEvent(model.OrgChanged, changes) - if err != nil { - return nil, err - } - aggregates = append(aggregates, orgAggregate) - - return aggregates, nil -} - -func orgDeactivateAggregate(aggCreator *es_models.AggregateCreator, org *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if org == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-R03z8", "Errors.Internal") - } - if org.State == int32(org_model.OrgStateInactive) { - return nil, errors.ThrowInvalidArgument(nil, "EVENT-mcPH0", "Errors.Internal.AlreadyDeactivated") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - - return agg.AppendEvent(model.OrgDeactivated, nil) - } -} - -func orgReactivateAggregate(aggCreator *es_models.AggregateCreator, org *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if org == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-cTHLd", "Errors.Internal") - } - if org.State == int32(org_model.OrgStateActive) { - return nil, errors.ThrowInvalidArgument(nil, "EVENT-pUSMs", "Errors.Org.AlreadyActive") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - - return agg.AppendEvent(model.OrgReactivated, nil) - } -} - -func reservedUniqueDomainAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, resourceOwner, domain string) (*es_models.Aggregate, error) { - aggregate, err := aggCreator.NewAggregate(ctx, domain, model.OrgDomainAggregate, model.OrgVersion, 0) - if resourceOwner != "" { - aggregate, err = aggCreator.NewAggregate(ctx, domain, model.OrgDomainAggregate, model.OrgVersion, 0, es_models.OverwriteResourceOwner(resourceOwner)) - } - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.OrgDomainReserved, nil) - if err != nil { - return nil, err - } - return aggregate.SetPrecondition(OrgDomainUniqueQuery(domain), isEventValidation(aggregate, model.OrgDomainReserved)), nil -} - -func releasedUniqueDomainAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, resourceOwner, domain string) (*es_models.Aggregate, error) { - aggregate, err := aggCreator.NewAggregate(ctx, domain, model.OrgDomainAggregate, model.OrgVersion, 0) - if resourceOwner != "" { - aggregate, err = aggCreator.NewAggregate(ctx, domain, model.OrgDomainAggregate, model.OrgVersion, 0, es_models.OverwriteResourceOwner(resourceOwner)) - } - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.OrgDomainReleased, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(OrgDomainUniqueQuery(domain), isEventValidation(aggregate, model.OrgDomainReleased)), nil -} - -func reservedUniqueNameAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, resourceOwner, name string) (aggregate *es_models.Aggregate, err error) { - aggregate, err = aggCreator.NewAggregate(ctx, name, model.OrgNameAggregate, model.OrgVersion, 0) - if resourceOwner != "" { - aggregate, err = aggCreator.NewAggregate(ctx, name, model.OrgNameAggregate, model.OrgVersion, 0, es_models.OverwriteResourceOwner(resourceOwner)) - } - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.OrgNameReserved, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(OrgNameUniqueQuery(name), isEventValidation(aggregate, model.OrgNameReserved)), nil -} - -func releasedUniqueNameAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, resourceOwner, name string) (aggregate *es_models.Aggregate, err error) { - aggregate, err = aggCreator.NewAggregate(ctx, name, model.OrgNameAggregate, model.OrgVersion, 0) - if resourceOwner != "" { - aggregate, err = aggCreator.NewAggregate(ctx, name, model.OrgNameAggregate, model.OrgVersion, 0, es_models.OverwriteResourceOwner(resourceOwner)) - } - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.OrgNameReleased, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(OrgNameUniqueQuery(name), isEventValidation(aggregate, model.OrgNameReleased)), nil -} - -func OrgDomainAddedAggregate(aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if domain == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-OSid3", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.OrgDomainAdded, domain) - } -} - -func OrgDomainValidationGeneratedAggregate(aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if domain == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-GD2gq", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.OrgDomainVerificationAdded, domain) - } -} - -func OrgDomainValidationFailedAggregate(aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if domain == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-BHF52", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.OrgDomainVerificationFailed, domain) - } -} - -func OrgDomainVerifiedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) { - if domain == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-DHs7s", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence) - if err != nil { - return nil, err - } - - aggregates, err := orgDomainVerified(ctx, aggCreator, agg, existingOrg, domain, users) - if err != nil { - return nil, err - } - return append(aggregates, agg), nil -} - -func orgDomainVerified(ctx context.Context, aggCreator *es_models.AggregateCreator, agg *es_models.Aggregate, existingOrg *model.Org, domain *model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) { - agg, err := agg.AppendEvent(model.OrgDomainVerified, domain) - if err != nil { - return nil, err - } - domainAgregate, err := reservedUniqueDomainAggregate(ctx, aggCreator, existingOrg.AggregateID, domain.Domain) - if err != nil { - return nil, err - } - aggregates := []*es_models.Aggregate{domainAgregate} - if users != nil { - userAggregates, err := users(ctx, domain.Domain) - if err != nil { - return nil, errors.ThrowPreconditionFailed(err, "EVENT-HBwsw", "Errors.Internal") - } - aggregates = append(aggregates, userAggregates...) - } - return aggregates, nil -} - -func OrgDomainSetPrimaryAggregate(aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if domain == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-PSw3j", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.OrgDomainPrimarySet, domain) - } -} - -func OrgDomainRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingOrg *model.Org, domain *model.OrgDomain) ([]*es_models.Aggregate, error) { - if domain == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-si8dW", "Errors.Internal") - } - aggregates := make([]*es_models.Aggregate, 0, 2) - agg, err := OrgAggregate(ctx, aggCreator, existingOrg.AggregateID, existingOrg.Sequence) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.OrgDomainRemoved, domain) - if err != nil { - return nil, err - } - aggregates = append(aggregates, agg) - domainAgregate, err := releasedUniqueDomainAggregate(ctx, aggCreator, existingOrg.AggregateID, domain.Domain) - if err != nil { - return nil, err - } - return append(aggregates, domainAgregate), nil -} - -func IDPConfigAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, idp *iam_es_model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-MSki8", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - agg.AppendEvent(model.IDPConfigAdded, idp) - if idp.OIDCIDPConfig != nil { - agg.AppendEvent(model.OIDCIDPConfigAdded, idp.OIDCIDPConfig) - } - return agg, nil - } -} - -func IDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, idp *iam_es_model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Akdi8", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - var changes map[string]interface{} - for _, i := range existing.IDPs { - if i.IDPConfigID == idp.IDPConfigID { - changes = i.Changes(idp) - } - } - agg.AppendEvent(model.IDPConfigChanged, changes) - - return agg, nil - } -} - -func IDPConfigRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Org, idp *iam_es_model.IDPConfig, provider *iam_es_model.IDPProvider) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Mlso9", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - - agg, err = agg.AppendEvent(model.IDPConfigRemoved, &iam_es_model.IDPConfigID{IDPConfigID: idp.IDPConfigID}) - - if err != nil { - return nil, err - } - if provider != nil { - return agg.AppendEvent(model.LoginPolicyIDPProviderCascadeRemoved, &iam_es_model.IDPProviderID{IDPConfigID: provider.IDPConfigID}) - } - return agg, nil - -} - -func IDPConfigDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, idp *iam_es_model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-3sz7d", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - agg.AppendEvent(model.IDPConfigDeactivated, &iam_es_model.IDPConfigID{IDPConfigID: idp.IDPConfigID}) - - return agg, nil - } -} - -func IDPConfigReactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, idp *iam_es_model.IDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if idp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4jdiS", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - agg.AppendEvent(model.IDPConfigReactivated, &iam_es_model.IDPConfigID{IDPConfigID: idp.IDPConfigID}) - - return agg, nil - } -} - -func OIDCIDPConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, config *iam_es_model.OIDCIDPConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if config == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-6Fjso", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - var changes map[string]interface{} - for _, idp := range existing.IDPs { - if idp.IDPConfigID == config.IDPConfigID { - if idp.OIDCIDPConfig != nil { - changes = idp.OIDCIDPConfig.Changes(config) - } - } - } - if len(changes) <= 1 { - return nil, errors.ThrowPreconditionFailedf(nil, "EVENT-Rks9u", "Errors.NoChangesFound") - } - agg.AppendEvent(model.OIDCIDPConfigChanged, changes) - - return agg, nil - } -} - -func isEventValidation(aggregate *es_models.Aggregate, eventType es_models.EventType) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - if len(events) == 0 { - aggregate.PreviousSequence = 0 - return nil - } - if events[0].Type == eventType { - return errors.ThrowPreconditionFailedf(nil, "EVENT-eJQqe", "user is already %v", eventType) - } - aggregate.PreviousSequence = events[0].Sequence - return nil - } -} diff --git a/internal/org/repository/eventsourcing/org_iam_policy.go b/internal/org/repository/eventsourcing/org_iam_policy.go deleted file mode 100644 index a922aeaa7a..0000000000 --- a/internal/org/repository/eventsourcing/org_iam_policy.go +++ /dev/null @@ -1,50 +0,0 @@ -package eventsourcing - -import ( - "context" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func OrgIAMPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, policy *iam_es_model.OrgIAMPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-i9sJS", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.OrgIAMPolicyAdded, policy) - } -} - -func OrgIAMPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, policy *iam_es_model.OrgIAMPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9Ksie", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - changes := org.OrgIAMPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Js6Vs", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.OrgIAMPolicyChanged, changes) - } -} - -func OrgIamPolicyRemovedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.OrgIAMPolicyRemoved, nil) - } -} diff --git a/internal/org/repository/eventsourcing/org_iam_policy_test.go b/internal/org/repository/eventsourcing/org_iam_policy_test.go deleted file mode 100644 index 319efd8de9..0000000000 --- a/internal/org/repository/eventsourcing/org_iam_policy_test.go +++ /dev/null @@ -1,233 +0,0 @@ -package eventsourcing - -import ( - "context" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "testing" - - "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func TestOrgIamPolicyAddedAggregates(t *testing.T) { - type res struct { - eventsCount int - eventType es_models.EventType - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - org *model.Org - policy *iam_es_model.OrgIAMPolicy - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no policy error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "policy successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - }, - policy: &iam_es_model.OrgIAMPolicy{ - UserLoginMustBeDomain: true, - }, - }, - res: res{ - eventsCount: 1, - eventType: model.OrgIAMPolicyAdded, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg := OrgIAMPolicyAddedAggregate(tt.args.aggCreator, tt.args.org, tt.args.policy) - got, err := agg(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && got.Events[0].Type != tt.res.eventType { - t.Errorf("OrgIAMPolicyAddedAggregate() event type = %v, wanted count %v", got.Events[0].Type, tt.res.eventType) - } - if tt.res.isErr == nil && len(got.Events) != tt.res.eventsCount { - t.Errorf("OrgIAMPolicyAddedAggregate() event count = %d, wanted count %d", len(got.Events), tt.res.eventsCount) - } - }) - } -} - -func TestOrgIamPolicyChangedAggregates(t *testing.T) { - type res struct { - eventsCount int - eventType es_models.EventType - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - org *model.Org - policy *iam_es_model.OrgIAMPolicy - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no policy error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "policy successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - OrgIAMPolicy: &iam_es_model.OrgIAMPolicy{ - UserLoginMustBeDomain: true, - }, - }, - policy: &iam_es_model.OrgIAMPolicy{ - UserLoginMustBeDomain: false, - }, - }, - res: res{ - eventsCount: 1, - eventType: model.OrgIAMPolicyChanged, - isErr: nil, - }, - }, - { - name: "policy no changes", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - OrgIAMPolicy: &iam_es_model.OrgIAMPolicy{ - UserLoginMustBeDomain: true, - }, - }, - policy: &iam_es_model.OrgIAMPolicy{ - UserLoginMustBeDomain: true, - }, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg := OrgIAMPolicyChangedAggregate(tt.args.aggCreator, tt.args.org, tt.args.policy) - got, err := agg(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && got.Events[0].Type != tt.res.eventType { - t.Errorf("OrgIAMPolicyChangedAggregate() event type = %v, wanted count %v", got.Events[0].Type, tt.res.eventType) - } - if tt.res.isErr == nil && len(got.Events) != tt.res.eventsCount { - t.Errorf("OrgIAMPolicyChangedAggregate() event count = %d, wanted count %d", len(got.Events), tt.res.eventsCount) - } - }) - } -} - -func TestOrgIamPolicyRemovedAggregates(t *testing.T) { - type res struct { - eventsCount int - eventType es_models.EventType - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - org *model.Org - } - tests := []struct { - name string - args args - res res - }{ - { - name: "policy successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - OrgIAMPolicy: &iam_es_model.OrgIAMPolicy{ - UserLoginMustBeDomain: true, - }, - }, - }, - res: res{ - eventsCount: 1, - eventType: model.OrgIAMPolicyRemoved, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg := OrgIamPolicyRemovedAggregate(tt.args.aggCreator, tt.args.org) - got, err := agg(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && got.Events[0].Type != tt.res.eventType { - t.Errorf("OrgIAMPolicyChangedAggregate() event type = %v, wanted count %v", got.Events[0].Type, tt.res.eventType) - } - if tt.res.isErr == nil && len(got.Events) != tt.res.eventsCount { - t.Errorf("OrgIAMPolicyChangedAggregate() event count = %d, wanted count %d", len(got.Events), tt.res.eventsCount) - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/org_member.go b/internal/org/repository/eventsourcing/org_member.go deleted file mode 100644 index 24b67c2f38..0000000000 --- a/internal/org/repository/eventsourcing/org_member.go +++ /dev/null @@ -1,97 +0,0 @@ -package eventsourcing - -import ( - "context" - - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - usr_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -func orgMemberAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, member *model.OrgMember, resourceOwner string) (agg *es_models.Aggregate, err error) { - if member == nil { - return nil, errors.ThrowInvalidArgument(nil, "EVENT-c63Ap", "Errors.Internal") - } - - if resourceOwner != "" { - agg, err = aggCreator.NewAggregate(ctx, member.AggregateID, model.OrgAggregate, model.OrgVersion, member.Sequence, es_models.OverwriteResourceOwner(resourceOwner)) - } else { - agg, err = aggCreator.NewAggregate(ctx, member.AggregateID, model.OrgAggregate, model.OrgVersion, member.Sequence) - } - if err != nil { - return nil, err - } - - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate, usr_model.UserAggregate). - AggregateIDsFilter(member.AggregateID, member.UserID) - - validation := addMemberValidation(agg, member) - return agg.SetPrecondition(validationQuery, validation).AppendEvent(model.OrgMemberAdded, member) -} - -func orgMemberChangedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, existingMember, member *model.OrgMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil || org == nil || existingMember == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d34fs", "Errors.Internal") - } - - changes := existingMember.Changes(member) - if len(changes) == 0 { - return nil, errors.ThrowInvalidArgument(nil, "EVENT-VLMGn", "Errors.NoChangesFound") - } - - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.OrgMemberChanged, changes) - } -} - -func orgMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, org *model.Org, member *model.OrgMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-vNPVX", "Errors.Internal") - } - - agg, err := OrgAggregate(ctx, aggCreator, org.AggregateID, org.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.OrgMemberRemoved, member) - } -} - -func addMemberValidation(aggregate *es_models.Aggregate, member *model.OrgMember) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existsOrg := false - existsUser := false - isMember := false - for _, event := range events { - switch event.AggregateType { - case usr_model.UserAggregate: - existsUser = true - case model.OrgAggregate: - aggregate.PreviousSequence = event.Sequence - existsOrg = true - switch event.Type { - case model.OrgMemberAdded, model.OrgMemberRemoved: - manipulatedMember, err := model.OrgMemberFromEvent(new(model.OrgMember), event) - if err != nil { - return errors.ThrowInternal(err, "EVENT-Eg8St", "unable to validate object") - } - if manipulatedMember.UserID == member.UserID { - isMember = event.Type == model.OrgMemberAdded - } - } - } - } - if existsOrg && existsUser && !isMember { - return nil - } - return errors.ThrowPreconditionFailed(nil, "EVENT-3OfIm", "conditions not met") - } -} diff --git a/internal/org/repository/eventsourcing/org_member_test.go b/internal/org/repository/eventsourcing/org_member_test.go deleted file mode 100644 index 59e571e6f3..0000000000 --- a/internal/org/repository/eventsourcing/org_member_test.go +++ /dev/null @@ -1,409 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - - "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - usr_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -func TestOrgMemberAddedAggregate(t *testing.T) { - type res struct { - isErr func(error) bool - eventCount int - } - type args struct { - aggCreator *es_models.AggregateCreator - member *model.OrgMember - ctx context.Context - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no member", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - member: nil, - }, - res: res{ - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "member added sucessfully", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - member: &model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, - }, - }, - res: res{ - isErr: nil, - eventCount: 1, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregate, err := orgMemberAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.member, "") - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && aggregate == nil { - t.Error("aggregate must not be nil") - } - if tt.res.isErr == nil && len(aggregate.Events) != tt.res.eventCount { - t.Error("wrong amount of events") - } - }) - } -} - -func TestOrgMemberChangedAggregate(t *testing.T) { - type res struct { - isErr func(error) bool - eventCount int - } - type args struct { - aggCreator *es_models.AggregateCreator - org *model.Org - existingMember *model.OrgMember - member *model.OrgMember - ctx context.Context - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no member", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: &model.Org{}, - member: nil, - existingMember: &model.OrgMember{}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no existing member", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: &model.Org{}, - existingMember: nil, - member: &model.OrgMember{}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no changes", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - member: &model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, - }, - existingMember: &model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, - }, - org: &model.Org{}, - }, - res: res{ - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "with changes success", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - member: &model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, - Roles: []string{"asdf"}, - }, - existingMember: &model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, - Roles: []string{"asdf", "woeri"}, - }, - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, - }, - }, - res: res{ - isErr: nil, - eventCount: 1, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregateCreator := orgMemberChangedAggregate(tt.args.aggCreator, tt.args.org, tt.args.existingMember, tt.args.member) - aggregate, err := aggregateCreator(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && aggregate == nil { - t.Error("aggregate must not be nil") - } - if tt.res.isErr == nil && len(aggregate.Events) != tt.res.eventCount { - t.Error("wrong amount of events") - } - }) - } -} - -func TestOrgMemberRemovedAggregate(t *testing.T) { - type res struct { - isErr func(error) bool - eventCount int - } - type args struct { - aggCreator *es_models.AggregateCreator - org *model.Org - member *model.OrgMember - ctx context.Context - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no member", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: &model.Org{}, - member: nil, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "member added sucessfully", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, - }, - member: &model.OrgMember{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "asdf", Sequence: 234}, - }, - }, - res: res{ - isErr: nil, - eventCount: 1, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregateCreator := orgMemberRemovedAggregate(tt.args.aggCreator, tt.args.org, tt.args.member) - aggregate, err := aggregateCreator(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && aggregate == nil { - t.Error("aggregate must not be nil") - } - if tt.res.isErr == nil && len(aggregate.Events) != tt.res.eventCount { - t.Error("wrong amount of events") - } - }) - } -} - -func Test_addMemberValidation(t *testing.T) { - type res struct { - isErr func(error) bool - preivousSequence uint64 - } - type args struct { - aggregate *es_models.Aggregate - events []*es_models.Event - member *model.OrgMember - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no events", - args: args{ - aggregate: &es_models.Aggregate{}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "only org events", - args: args{ - aggregate: &es_models.Aggregate{}, - events: []*es_models.Event{ - { - AggregateType: model.OrgAggregate, - Sequence: 13, - }, - { - AggregateType: model.OrgAggregate, - Sequence: 142, - }, - { - AggregateType: model.OrgAggregate, - Sequence: 1234, - Type: model.OrgMemberAdded, - Data: []byte(`{"userId":"hodor"}`), - }, - }, - member: &model.OrgMember{UserID: "hodor"}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "only user events", - args: args{ - aggregate: &es_models.Aggregate{}, - events: []*es_models.Event{ - { - AggregateType: usr_model.UserAggregate, - Sequence: 13, - }, - { - AggregateType: usr_model.UserAggregate, - Sequence: 142, - }, - }, - member: &model.OrgMember{UserID: "hodor"}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "user, org events success", - args: args{ - aggregate: &es_models.Aggregate{}, - events: []*es_models.Event{ - { - AggregateType: usr_model.UserAggregate, - Sequence: 13, - }, - { - AggregateType: model.OrgAggregate, - Sequence: 142, - }, - }, - member: &model.OrgMember{UserID: "hodor"}, - }, - res: res{ - isErr: nil, - preivousSequence: 142, - }, - }, - { - name: "user, org and member events success", - args: args{ - aggregate: &es_models.Aggregate{}, - events: []*es_models.Event{ - { - AggregateType: usr_model.UserAggregate, - Sequence: 13, - }, - { - AggregateType: model.OrgAggregate, - Sequence: 142, - }, - { - AggregateType: model.OrgAggregate, - Sequence: 1234, - Type: model.OrgMemberAdded, - Data: []byte(`{"userId":"hodor"}`), - }, - { - AggregateType: model.OrgAggregate, - Sequence: 1236, - Type: model.OrgMemberRemoved, - Data: []byte(`{"userId":"hodor"}`), - }, - }, - member: &model.OrgMember{UserID: "hodor"}, - }, - res: res{ - isErr: nil, - preivousSequence: 1236, - }, - }, - { - name: "user, org and member added events fail", - args: args{ - aggregate: &es_models.Aggregate{}, - events: []*es_models.Event{ - { - AggregateType: usr_model.UserAggregate, - Sequence: 13, - }, - { - AggregateType: model.OrgAggregate, - Sequence: 142, - }, - { - AggregateType: model.OrgAggregate, - Sequence: 1234, - Type: model.OrgMemberAdded, - Data: []byte(`{"userId":"hodor"}`), - }, - }, - member: &model.OrgMember{UserID: "hodor"}, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - validaiton := addMemberValidation(tt.args.aggregate, tt.args.member) - err := validaiton(tt.args.events...) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && tt.args.aggregate.PreviousSequence != tt.res.preivousSequence { - t.Errorf("wrong previous sequence got: %d want %d", tt.args.aggregate.PreviousSequence, tt.res.preivousSequence) - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/org_test.go b/internal/org/repository/eventsourcing/org_test.go deleted file mode 100644 index 02a27dd648..0000000000 --- a/internal/org/repository/eventsourcing/org_test.go +++ /dev/null @@ -1,1430 +0,0 @@ -package eventsourcing - -import ( - "context" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "testing" - - "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - org_model "github.com/caos/zitadel/internal/org/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func Test_isReservedValidation(t *testing.T) { - type res struct { - isErr func(error) bool - agggregateSequence uint64 - } - type args struct { - aggregate *es_models.Aggregate - eventType es_models.EventType - Events []*es_models.Event - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no events success", - args: args{ - aggregate: &es_models.Aggregate{}, - eventType: "object.reserved", - Events: []*es_models.Event{}, - }, - res: res{ - isErr: nil, - agggregateSequence: 0, - }, - }, - { - name: "not reseved success", - args: args{ - aggregate: &es_models.Aggregate{}, - eventType: "object.reserved", - Events: []*es_models.Event{ - { - AggregateID: "asdf", - AggregateType: "org", - Sequence: 45, - Type: "object.released", - }, - }, - }, - res: res{ - isErr: nil, - agggregateSequence: 45, - }, - }, - { - name: "reseved error", - args: args{ - aggregate: &es_models.Aggregate{}, - eventType: "object.reserved", - Events: []*es_models.Event{ - { - AggregateID: "asdf", - AggregateType: "org", - Sequence: 45, - Type: "object.reserved", - }, - }, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - agggregateSequence: 0, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - validate := isEventValidation(tt.args.aggregate, tt.args.eventType) - - err := validate(tt.args.Events...) - - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got: %v", err) - } - if err == nil && tt.args.aggregate.PreviousSequence != tt.res.agggregateSequence { - t.Errorf("expected sequence %d got %d", tt.res.agggregateSequence, tt.args.aggregate.PreviousSequence) - } - }) - } -} - -func aggregateWithPrecondition() *es_models.Aggregate { - return nil -} - -func Test_uniqueNameAggregate(t *testing.T) { - type res struct { - expected *es_models.Aggregate - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - orgName string - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no org name error", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - aggCreator: es_models.NewAggregateCreator("test"), - orgName: "", - }, - res: res{ - expected: nil, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "aggregate created", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - aggCreator: es_models.NewAggregateCreator("test"), - orgName: "asdf", - }, - res: res{ - expected: aggregateWithPrecondition(), - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := reservedUniqueNameAggregate(tt.args.ctx, tt.args.aggCreator, "", tt.args.orgName) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && (got.Precondition == nil || got.Precondition.Query == nil || got.Precondition.Validation == nil) { - t.Errorf("precondition is not set correctly") - } - }) - } -} - -func Test_uniqueDomainAggregate(t *testing.T) { - type res struct { - expected *es_models.Aggregate - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - orgDomain string - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no org domain error", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - aggCreator: es_models.NewAggregateCreator("test"), - orgDomain: "", - }, - res: res{ - expected: nil, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "aggregate created", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - aggCreator: es_models.NewAggregateCreator("test"), - orgDomain: "asdf", - }, - res: res{ - expected: aggregateWithPrecondition(), - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := reservedUniqueDomainAggregate(tt.args.ctx, tt.args.aggCreator, "", tt.args.orgDomain) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && (got.Precondition == nil || got.Precondition.Query == nil || got.Precondition.Validation == nil) { - t.Errorf("precondition is not set correctly") - } - }) - } -} - -func TestOrgReactivateAggregate(t *testing.T) { - type res struct { - isErr func(error) bool - } - type args struct { - aggCreator *es_models.AggregateCreator - org *model.Org - ctx context.Context - } - tests := []struct { - name string - args args - res res - }{ - { - name: "correct", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "orgID", - Sequence: 2, - }, - State: int32(org_model.OrgStateInactive), - }, - }, - }, - { - name: "already active error", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "orgID", - Sequence: 2, - }, - State: int32(org_model.OrgStateActive), - }, - }, - res: res{ - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "org nil error", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: nil, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregateCreator := orgReactivateAggregate(tt.args.aggCreator, tt.args.org) - aggregate, err := aggregateCreator(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && aggregate == nil { - t.Error("aggregate must not be nil") - } - }) - } -} - -func TestOrgDeactivateAggregate(t *testing.T) { - type res struct { - isErr func(error) bool - } - type args struct { - aggCreator *es_models.AggregateCreator - org *model.Org - ctx context.Context - } - tests := []struct { - name string - args args - res res - }{ - { - name: "correct", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "orgID", - Sequence: 2, - }, - State: int32(org_model.OrgStateActive), - }, - }, - }, - { - name: "already inactive error", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "orgID", - Sequence: 2, - }, - State: int32(org_model.OrgStateInactive), - }, - }, - res: res{ - isErr: errors.IsErrorInvalidArgument, - }, - }, - { - name: "org nil error", - args: args{ - aggCreator: es_models.NewAggregateCreator("test"), - ctx: authz.NewMockContext("org", "user"), - org: nil, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregateCreator := orgDeactivateAggregate(tt.args.aggCreator, tt.args.org) - aggregate, err := aggregateCreator(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && aggregate == nil { - t.Error("aggregate must not be nil") - } - }) - } -} - -func TestOrgUpdateAggregates(t *testing.T) { - type res struct { - aggregateCount int - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - existingOrg *model.Org - updated *model.Org - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no existing org error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - existingOrg: nil, - updated: &model.Org{}, - }, - res: res{ - aggregateCount: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no updated org error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - existingOrg: &model.Org{}, - updated: nil, - }, - res: res{ - aggregateCount: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no changes", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - existingOrg: &model.Org{}, - updated: &model.Org{}, - }, - res: res{ - aggregateCount: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "name changed", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - existingOrg: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - Name: "coas", - }, - updated: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - Name: "caos", - }, - }, - res: res{ - aggregateCount: 3, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := OrgUpdateAggregates(tt.args.ctx, tt.args.aggCreator, tt.args.existingOrg, tt.args.updated) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got: %v", err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && len(got) != tt.res.aggregateCount { - t.Errorf("OrgUpdateAggregates() aggregate count = %d, wanted count %d", len(got), tt.res.aggregateCount) - } - }) - } -} - -func TestOrgCreatedAggregates(t *testing.T) { - type res struct { - aggregateCount int - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - org *model.Org - users func(ctx context.Context, domain string) ([]*es_models.Aggregate, error) - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no org error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: nil, - }, - res: res{ - aggregateCount: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "org successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - Name: "caos", - }, - }, - res: res{ - aggregateCount: 2, - isErr: nil, - }, - }, - { - name: "org with domain successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - Name: "caos", - Domains: []*model.OrgDomain{{ - Domain: "caos.ch", - }}, - }, - }, - res: res{ - aggregateCount: 2, - isErr: nil, - }, - }, - { - name: "org with domain users aggregate error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - Name: "caos", - Domains: []*model.OrgDomain{{ - Domain: "caos.ch", - Verified: true, - }}, - }, - users: func(ctx context.Context, domain string) ([]*es_models.Aggregate, error) { - return nil, errors.ThrowInternal(nil, "id", "internal error") - }, - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "no name error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - }, - }, - res: res{ - aggregateCount: 2, - isErr: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := orgCreatedAggregates(tt.args.ctx, tt.args.aggCreator, tt.args.org, tt.args.users) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && len(got) != tt.res.aggregateCount { - t.Errorf("OrgUpdateAggregates() aggregate count = %d, wanted count %d", len(got), tt.res.aggregateCount) - } - }) - } -} - -func TestOrgDomainAddedAggregates(t *testing.T) { - type res struct { - eventCount int - eventType es_models.EventType - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - org *model.Org - domain *model.OrgDomain - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no domain error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "domain successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - }, - domain: &model.OrgDomain{ - Domain: "caos.ch", - }, - }, - res: res{ - eventCount: 1, - eventType: model.OrgDomainAdded, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg := OrgDomainAddedAggregate(tt.args.aggCreator, tt.args.org, tt.args.domain) - got, err := agg(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - - if tt.res.isErr == nil && got.Events[0].Type != tt.res.eventType { - t.Errorf("OrgDomainAddedAggregate() event type = %v, wanted count %v", got.Events[0].Type, tt.res.eventType) - } - if tt.res.isErr == nil && len(got.Events) != tt.res.eventCount { - t.Errorf("OrgDomainAddedAggregate() event count = %v, wanted count %v", len(got.Events), tt.res.eventCount) - } - }) - } -} - -func TestOrgDomainVerifiedAggregates(t *testing.T) { - type res struct { - aggregateCount int - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - org *model.Org - domain *model.OrgDomain - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no domain error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "domain successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - }, - domain: &model.OrgDomain{ - Domain: "caos.ch", - }, - }, - res: res{ - aggregateCount: 2, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := OrgDomainVerifiedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.org, tt.args.domain, nil) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && len(got) != tt.res.aggregateCount { - t.Errorf("OrgDomainVerifiedAggregate() aggregate count = %d, wanted count %d", len(got), tt.res.aggregateCount) - } - }) - } -} - -func TestOrgDomainSetPrimaryAggregates(t *testing.T) { - type res struct { - eventsCount int - eventType es_models.EventType - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - org *model.Org - domain *model.OrgDomain - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no domain error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - }, - res: res{ - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "domain successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - }, - domain: &model.OrgDomain{ - Domain: "caos.ch", - }, - }, - res: res{ - eventsCount: 1, - eventType: model.OrgDomainPrimarySet, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg := OrgDomainSetPrimaryAggregate(tt.args.aggCreator, tt.args.org, tt.args.domain) - got, err := agg(tt.args.ctx) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && got.Events[0].Type != tt.res.eventType { - t.Errorf("OrgDomainSetPrimaryAggregate() event type = %v, wanted count %v", got.Events[0].Type, tt.res.eventType) - } - if tt.res.isErr == nil && len(got.Events) != tt.res.eventsCount { - t.Errorf("OrgDomainSetPrimaryAggregate() event count = %d, wanted count %d", len(got.Events), tt.res.eventsCount) - } - }) - } -} - -func TestOrgDomainRemovedAggregates(t *testing.T) { - type res struct { - aggregateCount int - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *es_models.AggregateCreator - org *model.Org - domain *model.OrgDomain - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no domain error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - }, - res: res{ - aggregateCount: 0, - isErr: errors.IsPreconditionFailed, - }, - }, - { - name: "domain successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: es_models.NewAggregateCreator("test"), - org: &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "sdaf", - Sequence: 5, - }, - }, - domain: &model.OrgDomain{ - Domain: "caos.ch", - }, - }, - res: res{ - aggregateCount: 2, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := OrgDomainRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.org, tt.args.domain) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && len(got) != tt.res.aggregateCount { - t.Errorf("OrgDomainRemovedAggregate() aggregate count = %d, wanted count %d", len(got), tt.res.aggregateCount) - } - }) - } -} - -func TestIdpConfigAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.IDPConfig - aggCreator *es_models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []es_models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add oidc idp configuration", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Name: "Name"}, - new: &iam_es_model.IDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - OIDCIDPConfig: &iam_es_model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}, - }, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []es_models.EventType{model.IDPConfigAdded, model.OIDCIDPConfigAdded}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Name: "Name"}, - new: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigurationChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.IDPConfig - aggCreator *es_models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []es_models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change idp configuration", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "Name", - IDPs: []*iam_es_model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "IDPName"}, - }}, - new: &iam_es_model.IDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "NameChanged", - }, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []es_models.EventType{model.IDPConfigChanged}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Name: "Name"}, - new: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigurationRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.IDPConfig - provider *iam_es_model.IDPProvider - aggCreator *es_models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []es_models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove idp config", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "Name", - IDPs: []*iam_es_model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name"}, - }}, - new: &iam_es_model.IDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []es_models.EventType{model.IDPConfigRemoved}, - }, - }, - { - name: "remove idp config with provider", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "Name", - IDPs: []*iam_es_model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name"}, - }}, - new: &iam_es_model.IDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - provider: &iam_es_model.IDPProvider{ - IDPConfigID: "IDPConfigID", - }, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []es_models.EventType{model.IDPConfigRemoved, model.LoginPolicyIDPProviderCascadeRemoved}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Name: "Name"}, - new: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existing, tt.args.new, tt.args.provider) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigurationDeactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.IDPConfig - aggCreator *es_models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []es_models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate idp config", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "Name", - IDPs: []*iam_es_model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name"}, - }}, - new: &iam_es_model.IDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []es_models.EventType{model.IDPConfigDeactivated}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Name: "Name"}, - new: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigDeactivatedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestIdpConfigurationReactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.IDPConfig - aggCreator *es_models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []es_models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "Name", - IDPs: []*iam_es_model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name"}, - }}, - new: &iam_es_model.IDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - Name: "Name", - }, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []es_models.EventType{model.IDPConfigReactivated}, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - { - name: "idp config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Name: "Name"}, - new: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := IDPConfigReactivatedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOIDCConfigChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.OIDCIDPConfig - aggCreator *es_models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []es_models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change oidc config", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "Name", - IDPs: []*iam_es_model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name", OIDCIDPConfig: &iam_es_model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}}, - }}, - new: &iam_es_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientIDChanged", - }, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []es_models.EventType{model.OIDCIDPConfigChanged}, - }, - }, - { - name: "no changes", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "Name", - IDPs: []*iam_es_model.IDPConfig{ - {IDPConfigID: "IDPConfigID", Name: "Name", OIDCIDPConfig: &iam_es_model.OIDCIDPConfig{IDPConfigID: "IDPConfigID", ClientID: "ClientID"}}, - }}, - new: &iam_es_model.OIDCIDPConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - IDPConfigID: "IDPConfigID", - ClientID: "ClientID", - }, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - { - name: "existing iam nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - { - name: "oidc config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Name: "Name"}, - new: nil, - aggCreator: es_models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: errors.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := OIDCIDPConfigChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/password_age_policy.go b/internal/org/repository/eventsourcing/password_age_policy.go deleted file mode 100644 index 04d2acd03e..0000000000 --- a/internal/org/repository/eventsourcing/password_age_policy.go +++ /dev/null @@ -1,76 +0,0 @@ -package eventsourcing - -import ( - "context" - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func PasswordAgePolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.PasswordAgePolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Hms9d", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingPasswordAgePolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.PasswordAgePolicyAdded, policy) - } -} - -func PasswordAgePolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.PasswordAgePolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-3Gms0f", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - changes := existing.PasswordAgePolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Ls0rs", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.PasswordAgePolicyChanged, changes) - } -} - -func PasswordAgePolicyRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4Gsk9", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.PasswordAgePolicyRemoved, nil) - } -} - -func checkExistingPasswordAgePolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existing := false - for _, event := range events { - switch event.Type { - case model.PasswordAgePolicyAdded: - existing = true - case model.PasswordAgePolicyRemoved: - existing = false - } - } - if existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-2Fjs0", "Errors.Org.PasswordAgePolicy.AlreadyExists") - } - return nil - } -} diff --git a/internal/org/repository/eventsourcing/password_age_policy_test.go b/internal/org/repository/eventsourcing/password_age_policy_test.go deleted file mode 100644 index fb2b637985..0000000000 --- a/internal/org/repository/eventsourcing/password_age_policy_test.go +++ /dev/null @@ -1,258 +0,0 @@ -package eventsourcing - -import ( - "context" - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - "testing" -) - -func TestPasswordAgePolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.PasswordAgePolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password age policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.PasswordAgePolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAgeDays: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordAgePolicyAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "password age policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordAgePolicyAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestPasswordAgePolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.PasswordAgePolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password age policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - PasswordAgePolicy: &iam_es_model.PasswordAgePolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - new: &iam_es_model.PasswordAgePolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAgeDays: 5, - ExpireWarnDays: 5, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordAgePolicyChanged}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "password age policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordAgePolicyChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestPasswordAgePolicyRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove password age policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - PasswordAgePolicy: &iam_es_model.PasswordAgePolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordAgePolicyRemoved}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordAgePolicyRemovedAggregate(tt.args.aggCreator, tt.args.existing)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/password_complexity_policy.go b/internal/org/repository/eventsourcing/password_complexity_policy.go deleted file mode 100644 index f87ec93c25..0000000000 --- a/internal/org/repository/eventsourcing/password_complexity_policy.go +++ /dev/null @@ -1,76 +0,0 @@ -package eventsourcing - -import ( - "context" - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func PasswordComplexityPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.PasswordComplexityPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-F8iso", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingPasswordComplexityPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.PasswordComplexityPolicyAdded, policy) - } -} - -func PasswordComplexityPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.PasswordComplexityPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-2dFT5", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - changes := existing.PasswordComplexityPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Smk8d", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.PasswordComplexityPolicyChanged, changes) - } -} - -func PasswordComplexityPolicyRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Lso9f", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.PasswordComplexityPolicyRemoved, nil) - } -} - -func checkExistingPasswordComplexityPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existing := false - for _, event := range events { - switch event.Type { - case model.PasswordComplexityPolicyAdded: - existing = true - case model.PasswordComplexityPolicyRemoved: - existing = false - } - } - if existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-5Fjs8", "Errors.Org.PasswordComplexityPolicy.AlreadyExists") - } - return nil - } -} diff --git a/internal/org/repository/eventsourcing/password_complexity_policy_test.go b/internal/org/repository/eventsourcing/password_complexity_policy_test.go deleted file mode 100644 index f9ca57c76a..0000000000 --- a/internal/org/repository/eventsourcing/password_complexity_policy_test.go +++ /dev/null @@ -1,258 +0,0 @@ -package eventsourcing - -import ( - "context" - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - "testing" -) - -func TestPasswordComplexityPolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.PasswordComplexityPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password complexity polciy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.PasswordComplexityPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MinLength: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordComplexityPolicyAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "password complexity policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordComplexityPolicyAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestPasswordComplexityPolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.PasswordComplexityPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password complexity policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - PasswordComplexityPolicy: &iam_es_model.PasswordComplexityPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - new: &iam_es_model.PasswordComplexityPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MinLength: 5, - HasLowercase: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordComplexityPolicyChanged}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "password complexity policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordComplexityPolicyChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestPasswordComplexityPolicyRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove password complexity policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - PasswordComplexityPolicy: &iam_es_model.PasswordComplexityPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordComplexityPolicyRemoved}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordComplexityPolicyRemovedAggregate(tt.args.aggCreator, tt.args.existing)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - }) - } -} diff --git a/internal/org/repository/eventsourcing/password_lockout_policy.go b/internal/org/repository/eventsourcing/password_lockout_policy.go deleted file mode 100644 index adb6583c78..0000000000 --- a/internal/org/repository/eventsourcing/password_lockout_policy.go +++ /dev/null @@ -1,76 +0,0 @@ -package eventsourcing - -import ( - "context" - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -func PasswordLockoutPolicyAddedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.PasswordLockoutPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4Tfi9", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.OrgAggregate). - AggregateIDFilter(existing.AggregateID) - - validation := checkExistingPasswordLockoutPolicyValidation() - agg.SetPrecondition(validationQuery, validation) - return agg.AppendEvent(model.PasswordLockoutPolicyAdded, policy) - } -} - -func PasswordLockoutPolicyChangedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org, policy *iam_es_model.PasswordLockoutPolicy) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if policy == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-5lf9s", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - changes := existing.PasswordLockoutPolicy.Changes(policy) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-1dj9G", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.PasswordLockoutPolicyChanged, changes) - } -} - -func PasswordLockoutPolicyRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *model.Org) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if existing == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-6Hsl0", "Errors.Internal") - } - agg, err := OrgAggregate(ctx, aggCreator, existing.AggregateID, existing.Sequence) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.PasswordLockoutPolicyRemoved, nil) - } -} - -func checkExistingPasswordLockoutPolicyValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existing := false - for _, event := range events { - switch event.Type { - case model.PasswordLockoutPolicyAdded: - existing = true - case model.PasswordLockoutPolicyRemoved: - existing = false - } - } - if existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-2Dfl0", "Errors.Org.PasswordLockoutPolicy.AlreadyExists") - } - return nil - } -} diff --git a/internal/org/repository/eventsourcing/password_lockout_policy_test.go b/internal/org/repository/eventsourcing/password_lockout_policy_test.go deleted file mode 100644 index 3cb83b0ef7..0000000000 --- a/internal/org/repository/eventsourcing/password_lockout_policy_test.go +++ /dev/null @@ -1,258 +0,0 @@ -package eventsourcing - -import ( - "context" - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - "testing" -) - -func TestPasswordLockoutPolicyAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.PasswordLockoutPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add password lockout polciy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - new: &iam_es_model.PasswordLockoutPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAttempts: 10, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordLockoutPolicyAdded}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "password lockout policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordLockoutPolicyAddedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestPasswordLockoutPolicyChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - new *iam_es_model.PasswordLockoutPolicy - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change password lockout policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - PasswordLockoutPolicy: &iam_es_model.PasswordLockoutPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - new: &iam_es_model.PasswordLockoutPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - MaxAttempts: 5, - ShowLockOutFailures: true, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordLockoutPolicyChanged}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "password lockout policy config nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordLockoutPolicyChangedAggregate(tt.args.aggCreator, tt.args.existing, tt.args.new)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - }) - } -} - -func TestPasswordLockoutPolicyRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existing *model.Org - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove password lockout policy", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: &model.Org{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - PasswordLockoutPolicy: &iam_es_model.PasswordLockoutPolicy{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.PasswordLockoutPolicyRemoved}, - }, - }, - { - name: "existing org nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existing: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordLockoutPolicyRemovedAggregate(tt.args.aggCreator, tt.args.existing)(tt.args.ctx) - if (tt.res.wantErr && !tt.res.errFunc(err)) || (err != nil && !tt.res.wantErr) { - t.Errorf("got wrong err: %v ", err) - return - } - if tt.res.wantErr && tt.res.errFunc(err) { - return - } - if len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - }) - } -} diff --git a/internal/project/model/project_role.go b/internal/project/model/project_role.go index 2705627c9e..c63b369ffd 100644 --- a/internal/project/model/project_role.go +++ b/internal/project/model/project_role.go @@ -10,10 +10,6 @@ type ProjectRole struct { Group string } -func NewProjectRole(projectID, key string) *ProjectRole { - return &ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: projectID}, Key: key} -} - func (p *ProjectRole) IsValid() bool { return p.AggregateID != "" && p.Key != "" } diff --git a/internal/project/repository/eventsourcing/eventstore.go b/internal/project/repository/eventsourcing/eventstore.go index f5e211945e..39df97cdd0 100644 --- a/internal/project/repository/eventsourcing/eventstore.go +++ b/internal/project/repository/eventsourcing/eventstore.go @@ -9,7 +9,6 @@ import ( "github.com/caos/logging" "github.com/golang/protobuf/ptypes" - "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/cache/config" sd "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/crypto" @@ -87,352 +86,6 @@ func (es *ProjectEventstore) ProjectEventsByID(ctx context.Context, id string, s return es.FilterEvents(ctx, query) } -func (es *ProjectEventstore) CreateProject(ctx context.Context, project *proj_model.Project, global bool) (*proj_model.Project, error) { - if !project.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-IOVCC", "Errors.Project.Invalid") - } - id, err := es.idGenerator.Next() - if err != nil { - return nil, err - } - project.AggregateID = id - project.State = proj_model.ProjectStateActive - repoProject := model.ProjectFromModel(project) - projectRole := projectOwnerRole - if global { - projectRole = projectOwnerGlobalRole - } - member := &model.ProjectMember{ - UserID: authz.GetCtxData(ctx).UserID, - Roles: []string{projectRole}, - } - - createAggregate := ProjectCreateAggregate(es.AggregateCreator(), repoProject, member) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, createAggregate) - if err != nil { - return nil, err - } - - es.projectCache.cacheProject(repoProject) - return model.ProjectToModel(repoProject), nil -} - -func (es *ProjectEventstore) UpdateProject(ctx context.Context, project *proj_model.Project) (*proj_model.Project, error) { - if !project.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7eBD6", "Errors.Project.Invalid") - } - existingProject, err := es.ProjectByID(ctx, project.AggregateID) - if err != nil { - return nil, err - } - repoExisting := model.ProjectFromModel(existingProject) - repoNew := model.ProjectFromModel(project) - - updateAggregate := ProjectUpdateAggregate(es.AggregateCreator(), repoExisting, repoNew) - err = es_sdk.Push(ctx, es.PushAggregates, repoExisting.AppendEvents, updateAggregate) - if err != nil { - return nil, err - } - - es.projectCache.cacheProject(repoExisting) - return model.ProjectToModel(repoExisting), nil -} - -func (es *ProjectEventstore) DeactivateProject(ctx context.Context, id string) (*proj_model.Project, error) { - existingProject, err := es.ProjectByID(ctx, id) - if err != nil { - return nil, err - } - if !existingProject.IsActive() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die45", "Errors.Project.NotActive") - } - - repoExisting := model.ProjectFromModel(existingProject) - aggregate := ProjectDeactivateAggregate(es.AggregateCreator(), repoExisting) - err = es_sdk.Push(ctx, es.PushAggregates, repoExisting.AppendEvents, aggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoExisting) - return model.ProjectToModel(repoExisting), nil -} - -func (es *ProjectEventstore) ReactivateProject(ctx context.Context, id string) (*proj_model.Project, error) { - existingProject, err := es.ProjectByID(ctx, id) - if err != nil { - return nil, err - } - if existingProject.IsActive() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die45", "Errors.Project.NotInactive") - } - - repoExisting := model.ProjectFromModel(existingProject) - aggregate := ProjectReactivateAggregate(es.AggregateCreator(), repoExisting) - err = es_sdk.Push(ctx, es.PushAggregates, repoExisting.AppendEvents, aggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoExisting) - return model.ProjectToModel(repoExisting), nil -} - -func (es *ProjectEventstore) RemoveProject(ctx context.Context, proj *proj_model.Project) error { - project, aggregate, err := es.PrepareRemoveProject(ctx, proj) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, project.AppendEvents, aggregate) - if err != nil { - return err - } - es.projectCache.cacheProject(project) - return nil -} - -func (es *ProjectEventstore) PrepareRemoveProject(ctx context.Context, proj *proj_model.Project) (*model.Project, *es_models.Aggregate, error) { - if proj.AggregateID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Akbov", "Errors.ProjectInvalid") - } - existingProject, err := es.ProjectByID(ctx, proj.AggregateID) - if err != nil { - return nil, nil, err - } - repoProject := model.ProjectFromModel(existingProject) - projectAggregate, err := ProjectRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoProject) - if err != nil { - return nil, nil, err - } - return repoProject, projectAggregate, nil -} - -func (es *ProjectEventstore) ProjectMemberByIDs(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) { - if member.UserID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld93d", "Errors.Project.UserIDMissing") - } - project, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return nil, err - } - - if _, m := project.GetMember(member.UserID); m != nil { - return m, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-3udjs", "Errors.Project.Member.NotFound") -} - -func (es *ProjectEventstore) AddProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) { - if !member.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-2OWkC", "Errors.Project.Member.Invalid") - } - existingProject, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return nil, err - } - if _, m := existingProject.GetMember(member.UserID); m != nil { - return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-idke6", "Errors.Project.Member.AlreadyExists") - } - repoProject := model.ProjectFromModel(existingProject) - repoMember := model.ProjectMemberFromModel(member) - - addAggregate := ProjectMemberAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - - if _, m := model.GetProjectMember(repoProject.Members, member.UserID); m != nil { - return model.ProjectMemberToModel(m), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-rfQWv", "Errors.Internal") -} - -func (es *ProjectEventstore) ChangeProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) { - if !member.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Buh04", "Errors.Project.Member.Invalid") - } - existingProject, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return nil, err - } - if _, m := existingProject.GetMember(member.UserID); m == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe39f", "Errors.Project.Member.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoMember := model.ProjectMemberFromModel(member) - - projectAggregate := ProjectMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - - if _, m := model.GetProjectMember(repoProject.Members, member.UserID); m != nil { - return model.ProjectMemberToModel(m), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-pLyzi", "Errors.Internal") -} - -func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *proj_model.ProjectMember) error { - if member.UserID == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-d43fs", "Errors.Project.Member.Invalid") - } - existingProject, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return err - } - if _, m := existingProject.GetMember(member.UserID); m == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-swf34", "Errors.Project.Member.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoMember := model.ProjectMemberFromModel(member) - - projectAggregate := ProjectMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return err - } - es.projectCache.cacheProject(repoProject) - return err -} - -func (es *ProjectEventstore) PrepareRemoveProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*model.ProjectMember, *es_models.Aggregate, error) { - if member.UserID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-tCXHE", "Errors.Project.Member.Invalid") - } - existingProject, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return nil, nil, err - } - if _, m := existingProject.GetMember(member.UserID); m == nil { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-wPcg5", "Errors.Project.Member.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoMember := model.ProjectMemberFromModel(member) - - projectAggregate := ProjectMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember) - agg, err := projectAggregate(ctx) - if err != nil { - return nil, nil, err - } - - return repoMember, agg, err -} - -func (es *ProjectEventstore) AddProjectRoles(ctx context.Context, roles ...*proj_model.ProjectRole) (*proj_model.ProjectRole, error) { - if roles == nil || len(roles) == 0 { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-uOJAs", "Errors.Project.MinimumOneRoleNeeded") - } - for _, role := range roles { - if !role.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-iduG4", "Errors.Project.Role.Invalid") - } - } - existingProject, err := es.ProjectByID(ctx, roles[0].AggregateID) - if err != nil { - return nil, err - } - for _, role := range roles { - if existingProject.ContainsRole(role) { - return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-sk35t", "Errors.Project.Role.AlreadyExists") - } - } - - repoProject := model.ProjectFromModel(existingProject) - repoRoles := model.ProjectRolesFromModel(roles) - projectAggregate := ProjectRoleAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoRoles...) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - if len(repoRoles) > 1 { - return nil, nil - } - es.projectCache.cacheProject(repoProject) - if _, r := model.GetProjectRole(repoProject.Roles, repoRoles[0].Key); r != nil { - return model.ProjectRoleToModel(r), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-sie83", "Errors.Internal") -} - -func (es *ProjectEventstore) ChangeProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*proj_model.ProjectRole, error) { - if !role.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9die3", "Errors.Project.Role.Invalid") - } - existingProject, err := es.ProjectByID(ctx, role.AggregateID) - if err != nil { - return nil, err - } - if !existingProject.ContainsRole(role) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die34", "Errors.Project.Role.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoRole := model.ProjectRoleFromModel(role) - projectAggregate := ProjectRoleChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoRole) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - - es.projectCache.cacheProject(repoProject) - - if _, r := model.GetProjectRole(repoProject.Roles, role.Key); r != nil { - return model.ProjectRoleToModel(r), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-sl1or", "Errors.Internal") -} - -func (es *ProjectEventstore) PrepareRemoveProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*model.Project, *es_models.Aggregate, error) { - if role.Key == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-id823", "Errors.Project.Role.Invalid") - } - existingProject, err := es.ProjectByID(ctx, role.AggregateID) - if err != nil { - return nil, nil, err - } - if !existingProject.ContainsRole(role) { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe823", "Errors.Project.Role.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoRole := model.ProjectRoleFromModel(role) - grants := es.RemoveRoleFromGrants(repoProject, role.Key) - projectAggregate, err := ProjectRoleRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoProject, repoRole, grants) - if err != nil { - return nil, nil, err - } - return repoProject, projectAggregate, nil -} - -func (es *ProjectEventstore) RemoveRoleFromGrants(existingProject *model.Project, roleKey string) []*model.ProjectGrant { - grants := make([]*model.ProjectGrant, len(existingProject.Grants)) - for i, grant := range existingProject.Grants { - newGrant := *grant - roles := make([]string, 0) - for _, role := range newGrant.RoleKeys { - if role != roleKey { - roles = append(roles, role) - } - } - newGrant.RoleKeys = roles - grants[i] = &newGrant - } - return grants -} - -func (es *ProjectEventstore) RemoveProjectRole(ctx context.Context, role *proj_model.ProjectRole) error { - project, aggregate, err := es.PrepareRemoveProjectRole(ctx, role) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, project.AppendEvents, aggregate) - if err != nil { - return err - } - es.projectCache.cacheProject(project) - return nil -} - func (es *ProjectEventstore) ProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ProjectChanges, error) { query := ChangesQuery(id, lastSequence, limit, sortAscending) @@ -494,21 +147,6 @@ func ChangesQuery(projectID string, latestSequence, limit uint64, sortAscending return query } -func (es *ProjectEventstore) ApplicationByIDs(ctx context.Context, projectID, appID string) (*proj_model.Application, error) { - if projectID == "" || appID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld93d", "Errors.Project.IDMissing") - } - project, err := es.ProjectByID(ctx, projectID) - if err != nil { - return nil, err - } - - if _, a := project.GetApp(appID); a != nil { - return a, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-8ei2s", "Errors.Project.App.NotFound") -} - func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) { if app == nil || !app.IsValid(true) { return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9eidw", "Errors.Project.App.Invalid") @@ -568,75 +206,6 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model return nil, caos_errs.ThrowInternal(nil, "EVENT-GvPct", "Errors.Internal") } -func (es *ProjectEventstore) ChangeApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) { - if app == nil || !app.IsValid(false) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dieuw", "Errors.Project.App.Invalid") - } - existingProject, err := es.ProjectByID(ctx, app.AggregateID) - if err != nil { - return nil, err - } - if _, app := existingProject.GetApp(app.AppID); app == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "Errors.Project.App.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoApp := model.AppFromModel(app) - - projectAggregate := ApplicationChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - if _, a := model.GetApplication(repoProject.Applications, app.AppID); a != nil { - return model.AppToModel(a), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-dksi8", "Errors.Internal") -} - -func (es *ProjectEventstore) RemoveApplication(ctx context.Context, app *proj_model.Application) error { - if app.AppID == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-id832", "Errors.Project.IDMissing") - } - existingProject, err := es.ProjectByID(ctx, app.AggregateID) - if err != nil { - return err - } - if _, app := existingProject.GetApp(app.AppID); app == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83s", "Errors.Project.App.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - appRepo := model.AppFromModel(app) - projectAggregate := ApplicationRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, appRepo) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return err - } - es.projectCache.cacheProject(repoProject) - return nil -} - -func (es *ProjectEventstore) PrepareRemoveApplication(ctx context.Context, app *proj_model.Application) (*model.Application, *es_models.Aggregate, error) { - if app.AppID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-xu0Wy", "Errors.Project.IDMissing") - } - existingProject, err := es.ProjectByID(ctx, app.AggregateID) - if err != nil { - return nil, nil, err - } - if _, app := existingProject.GetApp(app.AppID); app == nil { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-gaOD2", "Errors.Project.App.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - appRepo := model.AppFromModel(app) - projectAggregate := ApplicationRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, appRepo) - agg, err := projectAggregate(ctx) - if err != nil { - return nil, nil, err - } - return appRepo, agg, nil -} - func (es *ProjectEventstore) ApplicationChanges(ctx context.Context, projectID string, appID string, lastSequence uint64, limit uint64, sortAscending bool) (*proj_model.ApplicationChanges, error) { query := ChangesQuery(projectID, lastSequence, limit, sortAscending) @@ -683,90 +252,6 @@ func (es *ProjectEventstore) ApplicationChanges(ctx context.Context, projectID s }, nil } -func (es *ProjectEventstore) DeactivateApplication(ctx context.Context, projectID, appID string) (*proj_model.Application, error) { - if appID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dlp9e", "Errors.Project.IDMissing") - } - existingProject, err := es.ProjectByID(ctx, projectID) - if err != nil { - return nil, err - } - app := &proj_model.Application{AppID: appID} - if _, app := existingProject.GetApp(app.AppID); app == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "Errors.Project.App.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoApp := model.AppFromModel(app) - - projectAggregate := ApplicationDeactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - if _, a := model.GetApplication(repoProject.Applications, app.AppID); a != nil { - return model.AppToModel(a), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-sie83", "Errors.Internal") -} - -func (es *ProjectEventstore) ReactivateApplication(ctx context.Context, projectID, appID string) (*proj_model.Application, error) { - if appID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0odi2", "Errors.Project.IDMissing") - } - existingProject, err := es.ProjectByID(ctx, projectID) - if err != nil { - return nil, err - } - app := &proj_model.Application{AppID: appID} - if _, app := existingProject.GetApp(app.AppID); app == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld92d", "Errors.Project.App.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoApp := model.AppFromModel(app) - - projectAggregate := ApplicationReactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - if _, a := model.GetApplication(repoProject.Applications, app.AppID); a != nil { - return model.AppToModel(a), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-sld93", "Errors.Internal") -} - -func (es *ProjectEventstore) ChangeOIDCConfig(ctx context.Context, config *proj_model.OIDCConfig) (*proj_model.OIDCConfig, error) { - if config == nil || !config.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-du834", "Errors.Project.App.OIDCConfigInvalid") - } - existingProject, err := es.ProjectByID(ctx, config.AggregateID) - if err != nil { - return nil, err - } - var app *proj_model.Application - if _, app = existingProject.GetApp(config.AppID); app == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkso8", "Errors.Project.AppNoExisting") - } - if app.Type != proj_model.AppTypeOIDC { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-98uje", "Errors.Project.App.IsNotOIDC") - } - repoProject := model.ProjectFromModel(existingProject) - repoConfig := model.OIDCConfigFromModel(config) - - projectAggregate := OIDCConfigChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoConfig) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - if _, a := model.GetApplication(repoProject.Applications, app.AppID); a != nil { - return model.OIDCConfigToModel(a.OIDCConfig), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-dk87s", "Errors.Internal") -} - func (es *ProjectEventstore) ChangeAPIConfig(ctx context.Context, config *proj_model.APIConfig) (*proj_model.APIConfig, error) { if config == nil || !config.IsValid() { return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-SDg54", "Errors.Project.APIConfigInvalid") @@ -995,270 +480,3 @@ func (es *ProjectEventstore) RemoveApplicationKey(ctx context.Context, projectID es.projectCache.cacheProject(repoProject) return nil } - -func (es *ProjectEventstore) ProjectGrantByIDs(ctx context.Context, projectID, grantID string) (*proj_model.ProjectGrant, error) { - if grantID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-e8die", "Errors.Project.IDMissing") - } - project, err := es.ProjectByID(ctx, projectID) - if err != nil { - return nil, err - } - if _, g := project.GetGrant(grantID); g != nil { - return g, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-slo45", "Errors.Project.Grant.NotFound") -} - -func (es *ProjectEventstore) AddProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) { - if grant == nil || !grant.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-37dhs", "Errors.Project.Grant.Invalid") - } - project, err := es.ProjectByID(ctx, grant.AggregateID) - if err != nil { - return nil, err - } - if project.ContainsGrantForOrg(grant.GrantedOrgID) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ug4g", "Errors.Project.Grant.AlreadyExists") - } - if !project.ContainsRoles(grant.RoleKeys) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83d", "Errors.Project.Grant.HasNotExistingRole") - } - id, err := es.idGenerator.Next() - if err != nil { - return nil, err - } - grant.GrantID = id - - repoProject := model.ProjectFromModel(project) - repoGrant := model.GrantFromModel(grant) - - addAggregate := ProjectGrantAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoGrant) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - if _, g := model.GetProjectGrant(repoProject.Grants, grant.GrantID); g != nil { - return model.GrantToModel(g), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-sk3t5", "Errors.Internal") -} - -func (es *ProjectEventstore) PrepareChangeProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*model.Project, func(ctx context.Context) (*es_models.Aggregate, error), []string, error) { - if grant == nil && grant.GrantID == "" { - return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8sie3", "Errors.Project.Grant.Invalid") - } - existingProject, err := es.ProjectByID(ctx, grant.AggregateID) - if err != nil { - return nil, nil, nil, err - } - _, existingGrant := existingProject.GetGrant(grant.GrantID) - if existingGrant == nil { - return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "Errors.Project.Grant.NotExisting") - } - if !existingProject.ContainsRoles(grant.RoleKeys) { - return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83d", "Error.Project.Grant.HasNotExistingRole") - } - removedRoles := existingGrant.GetRemovedRoles(grant.RoleKeys) - repoProject := model.ProjectFromModel(existingProject) - repoGrant := model.GrantFromModel(grant) - - projectAggregate := ProjectGrantChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoGrant) - return repoProject, projectAggregate, removedRoles, nil -} - -func (es *ProjectEventstore) RemoveProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) error { - repoProject, projectAggregate, err := es.PrepareRemoveProjectGrant(ctx, grant) - if err != nil { - return err - } - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return err - } - es.projectCache.cacheProject(repoProject) - return nil -} - -func (es *ProjectEventstore) RemoveProjectGrants(ctx context.Context, grants ...*proj_model.ProjectGrant) error { - aggregates := make([]*es_models.Aggregate, len(grants)) - for i, grant := range grants { - _, projectAggregate, err := es.PrepareRemoveProjectGrant(ctx, grant) - if err != nil { - return err - } - agg, err := projectAggregate(ctx) - if err != nil { - return err - } - aggregates[i] = agg - } - return es_sdk.PushAggregates(ctx, es.PushAggregates, nil, aggregates...) -} - -func (es *ProjectEventstore) PrepareRemoveProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*model.Project, func(ctx context.Context) (*es_models.Aggregate, error), error) { - if grant.GrantID == "" { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8eud6", "Errors.Project.IDMissing") - } - existingProject, err := es.ProjectByID(ctx, grant.AggregateID) - if err != nil { - return nil, nil, err - } - if _, g := existingProject.GetGrant(grant.GrantID); g == nil { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9ie3s", "Errors.Project.Grant.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - grantRepo := model.GrantFromModel(grant) - projectAggregate := ProjectGrantRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, grantRepo) - return repoProject, projectAggregate, nil -} - -func (es *ProjectEventstore) DeactivateProjectGrant(ctx context.Context, projectID, grantID string) (*proj_model.ProjectGrant, error) { - if grantID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7due2", "Errors.Project.IDMissing") - } - existingProject, err := es.ProjectByID(ctx, projectID) - if err != nil { - return nil, err - } - grant := &proj_model.ProjectGrant{GrantID: grantID} - if _, g := existingProject.GetGrant(grant.GrantID); g == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "Errors.Project.Grant.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoGrant := model.GrantFromModel(grant) - - projectAggregate := ProjectGrantDeactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoGrant) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - if _, g := model.GetProjectGrant(repoProject.Grants, grant.GrantID); g != nil { - return model.GrantToModel(g), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-sie83", "Errors.Internal") -} - -func (es *ProjectEventstore) ReactivateProjectGrant(ctx context.Context, projectID, grantID string) (*proj_model.ProjectGrant, error) { - if grantID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-d7suw", "Errors.Project.IDMissing") - } - existingProject, err := es.ProjectByID(ctx, projectID) - if err != nil { - return nil, err - } - grant := &proj_model.ProjectGrant{GrantID: grantID} - if _, g := existingProject.GetGrant(grant.GrantID); g == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0spew", "Errors.Project.Grant.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoGrant := model.GrantFromModel(grant) - - projectAggregate := ProjectGrantReactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoGrant) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - - if _, g := model.GetProjectGrant(repoProject.Grants, grant.GrantID); g != nil { - return model.GrantToModel(g), nil - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-9osjw", "Errors.Internal") -} - -func (es *ProjectEventstore) ProjectGrantMemberByIDs(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) { - if member.GrantID == "" || member.UserID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8diw2", "Errors.Project.UserIDMissing") - } - project, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return nil, err - } - if _, g := project.GetGrant(member.GrantID); g != nil { - if _, m := g.GetMember(member.UserID); m != nil { - return m, nil - } - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-LxiBI", "Errors.Project.Member.NotFound") -} - -func (es *ProjectEventstore) AddProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) { - if !member.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0dor4", "Errors.Project.Member.Invalid") - } - existingProject, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return nil, err - } - if existingProject.ContainsGrantMember(member) { - return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-8die3", "Errors.Project.Member.AlreadyExists") - } - repoProject := model.ProjectFromModel(existingProject) - repoMember := model.GrantMemberFromModel(member) - - addAggregate := ProjectGrantMemberAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, addAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - if _, g := model.GetProjectGrant(repoProject.Grants, member.GrantID); g != nil { - if _, m := model.GetProjectGrantMember(g.Members, member.UserID); m != nil { - return model.GrantMemberToModel(m), nil - } - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-BBcGD", "Errors.Internal") -} - -func (es *ProjectEventstore) ChangeProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) { - if !member.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkw35", "Errors.Project.Member.Invalid") - } - existingProject, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return nil, err - } - if !existingProject.ContainsGrantMember(member) { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8dj4s", "Errors.Project.Member.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoMember := model.GrantMemberFromModel(member) - - projectAggregate := ProjectGrantMemberChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.projectCache.cacheProject(repoProject) - if _, g := model.GetProjectGrant(repoProject.Grants, member.GrantID); g != nil { - if _, m := model.GetProjectGrantMember(g.Members, member.UserID); m != nil { - return model.GrantMemberToModel(m), nil - } - } - return nil, caos_errs.ThrowInternal(nil, "EVENT-s8ur3", "Errors.Internal") -} - -func (es *ProjectEventstore) RemoveProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) error { - if member.UserID == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-8su4r", "Errors.Project.Member.Invalid") - } - existingProject, err := es.ProjectByID(ctx, member.AggregateID) - if err != nil { - return err - } - if !existingProject.ContainsGrantMember(member) { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-9ode4", "Errors.Project.Member.NotExisting") - } - repoProject := model.ProjectFromModel(existingProject) - repoMember := model.GrantMemberFromModel(member) - - projectAggregate := ProjectGrantMemberRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoMember) - err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate) - if err != nil { - return err - } - es.projectCache.cacheProject(repoProject) - return err -} diff --git a/internal/project/repository/eventsourcing/eventstore_mock_test.go b/internal/project/repository/eventsourcing/eventstore_mock_test.go deleted file mode 100644 index 8c8f36d08e..0000000000 --- a/internal/project/repository/eventsourcing/eventstore_mock_test.go +++ /dev/null @@ -1,335 +0,0 @@ -package eventsourcing - -import ( - "encoding/json" - - "github.com/golang/mock/gomock" - - mock_cache "github.com/caos/zitadel/internal/cache/mock" - "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/eventstore/mock" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/id" - proj_model "github.com/caos/zitadel/internal/project/model" - "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - repo_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" -) - -func GetMockedEventstore(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *ProjectEventstore { - return &ProjectEventstore{ - Eventstore: mockEs, - projectCache: GetMockCache(ctrl), - idGenerator: GetSonyFlacke(), - } -} - -func GetMockedEventstoreWithPw(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *ProjectEventstore { - return &ProjectEventstore{ - Eventstore: mockEs, - projectCache: GetMockCache(ctrl), - idGenerator: GetSonyFlacke(), - pwGenerator: GetMockPwGenerator(ctrl), - } -} -func GetMockCache(ctrl *gomock.Controller) *ProjectCache { - mockCache := mock_cache.NewMockCache(ctrl) - mockCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - mockCache.EXPECT().Set(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - return &ProjectCache{projectCache: mockCache} -} - -func GetSonyFlacke() id.Generator { - return id.SonyFlakeGenerator -} - -func GetMockPwGenerator(ctrl *gomock.Controller) crypto.Generator { - generator := crypto.NewMockGenerator(ctrl) - generator.EXPECT().Length().Return(uint(10)) - generator.EXPECT().Runes().Return([]rune("abcdefghijklmnopqrstuvwxyz")) - generator.EXPECT().Alg().Return(crypto.NewBCrypt(10)) - return generator -} - -func GetMockProjectByIDOK(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockProjectByIDNoEvents(ctrl *gomock.Controller) *ProjectEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProject(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProjectWithPw(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs) -} - -func GetMockManipulateInactiveProject(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 2, Type: model.ProjectDeactivated, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProjectWithMember(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - memberData, _ := json.Marshal(model.ProjectMember{UserID: "UserID", Roles: []string{"Role"}}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectMemberAdded, Data: memberData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProjectWithRole(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - roleData, _ := json.Marshal(model.ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectRoleAdded, Data: roleData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProjectWithOIDCApp(ctrl *gomock.Controller, authMethod proj_model.OIDCAuthMethodType) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - appData, _ := json.Marshal(model.Application{AppID: "AppID", Name: "Name"}) - oidcData, _ := json.Marshal(model.OIDCConfig{ - AppID: "AppID", - ResponseTypes: []int32{int32(proj_model.OIDCResponseTypeCode)}, - GrantTypes: []int32{int32(proj_model.OIDCGrantTypeAuthorizationCode)}, - AuthMethodType: int32(authMethod), - }) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ApplicationAdded, Data: appData}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OIDCConfigAdded, Data: oidcData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs) -} - -func GetMockManipulateProjectWithSAMLApp(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - appData, _ := json.Marshal(model.Application{AppID: "AppID", Name: "Name"}) - - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ApplicationAdded, Data: appData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProjectWithGrant(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantAdded, Data: grantData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProjectWithGrantExistingRole(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - roleData, _ := json.Marshal(model.ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}) - roleData2, _ := json.Marshal(model.ProjectRole{Key: "KeyChanged", DisplayName: "DisplayName", Group: "Group"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectRoleAdded, Data: roleData}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectRoleAdded, Data: roleData2}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantAdded, Data: grantData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProjectWithGrantMember(ctrl *gomock.Controller) *ProjectEventstore { - data, _ := json.Marshal(model.Project{Name: "Name"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) - memberData, _ := json.Marshal(model.ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantAdded, Data: grantData}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantMemberAdded, Data: memberData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateProjectNoEvents(ctrl *gomock.Controller) *ProjectEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockProjectMemberByIDsOK(ctrl *gomock.Controller) *ProjectEventstore { - projectData, _ := json.Marshal(model.Project{Name: "Name"}) - memberData, _ := json.Marshal(model.ProjectMember{UserID: "UserID", Roles: []string{"Role"}}) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: projectData}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectMemberAdded, Data: memberData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockProjectAppsByIDsOK(ctrl *gomock.Controller) *ProjectEventstore { - projectData, _ := json.Marshal(model.Project{Name: "Name"}) - appData, _ := json.Marshal(model.Application{AppID: "AppID", Name: "Name"}) - oidcData, _ := json.Marshal(model.OIDCConfig{ClientID: "ClientID"}) - - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: projectData}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ApplicationAdded, Data: appData}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OIDCConfigAdded, Data: oidcData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockProjectGrantByIDsOK(ctrl *gomock.Controller) *ProjectEventstore { - projectData, _ := json.Marshal(model.Project{Name: "Name"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "ProjectGrantID", RoleKeys: []string{"Key"}}) - - events := []*es_models.Event{ - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: projectData}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantAdded, Data: grantData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockProjectGrantMemberByIDsOK(ctrl *gomock.Controller) *ProjectEventstore { - projectData, _ := json.Marshal(model.Project{Name: "Name"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "ProjectGrantID", RoleKeys: []string{"Key"}}) - memberData, _ := json.Marshal(model.ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}) - - events := []*es_models.Event{ - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: projectData}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantAdded, Data: grantData}, - &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantMemberAdded, Data: memberData}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockChangesProjectOK(ctrl *gomock.Controller) *ProjectEventstore { - project := model.Project{ - Name: "MusterProject", - } - data, err := json.Marshal(project) - if err != nil { - - } - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateIDProject", Sequence: 1, AggregateType: repo_model.ProjectAggregate, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstoreComplexity(ctrl, mockEs) -} - -func GetMockChangesProjectNoEvents(ctrl *gomock.Controller) *ProjectEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstoreComplexity(ctrl, mockEs) -} - -func GetMockedEventstoreComplexity(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *ProjectEventstore { - return &ProjectEventstore{ - Eventstore: mockEs, - } -} - -func GetMockChangesApplicationOK(ctrl *gomock.Controller) *ProjectEventstore { - app := model.Application{ - Name: "MusterApp", - AppID: "AppId", - Type: 3, - } - data, err := json.Marshal(app) - if err != nil { - - } - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateIDApp", Type: "project.application.added", Sequence: 1, AggregateType: repo_model.ProjectAggregate, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstoreComplexity(ctrl, mockEs) -} - -func GetMockChangesApplicationNoEvents(ctrl *gomock.Controller) *ProjectEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstoreComplexity(ctrl, mockEs) -} diff --git a/internal/project/repository/eventsourcing/eventstore_test.go b/internal/project/repository/eventsourcing/eventstore_test.go deleted file mode 100644 index 3448f911c9..0000000000 --- a/internal/project/repository/eventsourcing/eventstore_test.go +++ /dev/null @@ -1,2888 +0,0 @@ -package eventsourcing - -import ( - "context" - "encoding/json" - "testing" - - "github.com/golang/mock/gomock" - - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/project/model" -) - -func TestProjectByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - project *model.Project - } - type res struct { - project *model.Project - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project from events, ok", - args: args{ - es: GetMockProjectByIDOK(ctrl), - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - }, - { - name: "project from events, no events", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "project from events, no id", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ProjectByID(nil, tt.args.project.AggregateID) - - if !tt.res.wantErr && result.AggregateID != tt.res.project.AggregateID { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.project.AggregateID, result.AggregateID) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCreateProject(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - project *model.Project - global bool - } - type res struct { - project *model.Project - role string - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "create project, ok", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name"}, - }, - res: res{ - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name"}, - role: projectOwnerRole, - }, - }, - { - name: "create global project, ok", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name"}, - global: true, - }, - res: res{ - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name"}, - role: projectOwnerGlobalRole, - }, - }, - { - name: "create project no name", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.CreateProject(tt.args.ctx, tt.args.project, tt.args.global) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.Name != tt.res.project.Name { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.project.Name, result.Name) - } - if !tt.res.wantErr && result.Members[0].Roles[0] != tt.res.role { - t.Errorf("got wrong result role: expected: %v, actual: %v ", tt.res.role, result.Members[0].Roles[0]) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUpdateProject(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - new *model.Project - } - type res struct { - project *model.Project - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "update project, ok", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - new: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "NameNew"}, - }, - res: res{ - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "NameNew"}, - }, - }, - { - name: "update project no name", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - new: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: ""}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - new: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "NameNew"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.UpdateProject(tt.args.ctx, tt.args.new) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.Name != tt.res.project.Name { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.project.Name, result.Name) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestDeactivateProject(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - existingProject *model.Project - newProject *model.Project - } - type res struct { - project *model.Project - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate project, ok", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive}, - }, - res: res{ - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "NameNew", State: model.ProjectStateInactive}, - }, - }, - { - name: "deactivate project with inactive state", - args: args{ - es: GetMockManipulateInactiveProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateInactive}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.DeactivateProject(tt.args.ctx, tt.args.existingProject.AggregateID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.State != tt.res.project.State { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.project.State, result.State) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestReactivateProject(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - existingPolicy *model.Project - newPolicy *model.Project - } - type res struct { - project *model.Project - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate project, ok", - args: args{ - es: GetMockManipulateInactiveProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingPolicy: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateInactive}, - }, - res: res{ - project: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "NameNew", State: model.ProjectStateActive}, - }, - }, - { - name: "reactivate project with inactive state", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingPolicy: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingPolicy: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Name: "Name", State: model.ProjectStateActive}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ReactivateProject(tt.args.ctx, tt.args.existingPolicy.AggregateID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.State != tt.res.project.State { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.project.State, result.State) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveProject(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - existingPolicy *model.Project - } - type res struct { - result *model.Project - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove project, ok", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingPolicy: &model.Project{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Name: "Name", - Members: []*model.ProjectMember{ - {UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - }, - res: res{ - result: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - }, - { - name: "no projectid", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingPolicy: &model.Project{ - ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - Name: "Name", - Members: []*model.ProjectMember{ - {UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "project not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingPolicy: &model.Project{}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingPolicy: &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "OtherAggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveProject(tt.args.ctx, tt.args.existingPolicy) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectMemberByIDs(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - member *model.ProjectMember - } - type res struct { - member *model.ProjectMember - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project member from events, ok", - args: args{ - es: GetMockProjectMemberByIDsOK(ctrl), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"}, - }, - res: res{ - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Role"}}, - }, - }, - { - name: "project member from events, no events", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "project member from events, no id", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: func(err error) bool { - return caos_errs.IsPreconditionFailed(err) - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ProjectMemberByIDs(nil, tt.args.member) - if !tt.res.wantErr && result.AggregateID != tt.res.member.AggregateID { - t.Errorf("got wrong result id: expected: %v, actual: %v ", tt.res.member.AggregateID, result.AggregateID) - } - if !tt.res.wantErr && result.UserID != tt.res.member.UserID { - t.Errorf("got wrong result userid: expected: %v, actual: %v ", tt.res.member.UserID, result.UserID) - } - if !tt.res.wantErr && len(result.Roles) != len(tt.res.member.Roles) { - t.Errorf("got wrong result roles: expected: %v, actual: %v ", tt.res.member.Roles, result.Roles) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddProjectMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - member *model.ProjectMember - } - type res struct { - result *model.ProjectMember - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add project member, ok", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - result: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - { - name: "no userid", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Roles: []string{"Roles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no roles", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member already existing", - args: args{ - es: GetMockManipulateProjectWithMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddProjectMember(tt.args.ctx, tt.args.member) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.UserID != tt.res.result.UserID { - t.Errorf("got wrong result userid: expected: %v, actual: %v ", tt.res.result.UserID, result.UserID) - } - if !tt.res.wantErr && len(result.Roles) != len(tt.res.result.Roles) { - t.Errorf("got wrong result roles: expected: %v, actual: %v ", tt.res.result.Roles, result.Roles) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeProjectMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - member *model.ProjectMember - } - type res struct { - result *model.ProjectMember - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add project member, ok", - args: args{ - es: GetMockManipulateProjectWithMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"ChangeRoles"}}, - }, - res: res{ - result: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - { - name: "no userid", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Roles: []string{"ChangeRoles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no roles", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"ChangeRoles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeProjectMember(tt.args.ctx, tt.args.member) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.UserID != tt.res.result.UserID { - t.Errorf("got wrong result userid: expected: %v, actual: %v ", tt.res.result.UserID, result.UserID) - } - if !tt.res.wantErr && len(result.Roles) != len(tt.res.result.Roles) { - t.Errorf("got wrong result roles: expected: %v, actual: %v ", tt.res.result.Roles, result.Roles) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveProjectMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - existingProject *model.Project - member *model.ProjectMember - } - type res struct { - result *model.ProjectMember - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove project member, ok", - args: args{ - es: GetMockManipulateProjectWithMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Name: "Name", - Members: []*model.ProjectMember{ - {UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID"}, - }, - res: res{ - result: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - { - name: "no userid", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Name: "Name", - Members: []*model.ProjectMember{ - {UserID: "UserID", Roles: []string{"Roles"}}, - }, - }, - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Roles: []string{"ChangeRoles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Name: "Name", - }, - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"Roles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", Roles: []string{"ChangeRoles"}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveProjectMember(tt.args.ctx, tt.args.member) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddProjectRole(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - roles []*model.ProjectRole - } - type res struct { - result *model.ProjectRole - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add project role, ok", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - roles: []*model.ProjectRole{ - {ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - }, - }, - res: res{ - result: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - }, - }, - { - name: "no key", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - roles: []*model.ProjectRole{ - {ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, DisplayName: "DisplayName", Group: "Group"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "role already existing", - args: args{ - es: GetMockManipulateProjectWithRole(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - roles: []*model.ProjectRole{ - {ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - roles: []*model.ProjectRole{ - {ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddProjectRoles(tt.args.ctx, tt.args.roles...) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.Key != tt.res.result.Key { - t.Errorf("got wrong result key: expected: %v, actual: %v ", tt.res.result.Key, result.Key) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeProjectRole(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - role *model.ProjectRole - } - type res struct { - result *model.ProjectRole - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change project role, ok", - args: args{ - es: GetMockManipulateProjectWithRole(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - role: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayNameChanged", Group: "Group"}, - }, - res: res{ - result: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayNameChanged", Group: "Group"}, - }, - }, - { - name: "no key", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - role: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, DisplayName: "DisplayName", Group: "Group"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "role not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - role: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - role: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeProjectRole(tt.args.ctx, tt.args.role) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.Key != tt.res.result.Key { - t.Errorf("got wrong result key: expected: %v, actual: %v ", tt.res.result.Key, result.Key) - } - if !tt.res.wantErr && result.DisplayName != tt.res.result.DisplayName { - t.Errorf("got wrong result displayName: expected: %v, actual: %v ", tt.res.result.DisplayName, result.DisplayName) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveProjectRole(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - role *model.ProjectRole - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove project role, ok", - args: args{ - es: GetMockManipulateProjectWithRole(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - role: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key"}, - }, - }, - { - name: "no key", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - role: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, DisplayName: "DisplayName", Group: "Group"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "role not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - role: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - role: &model.ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveProjectRole(tt.args.ctx, tt.args.role) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestApplicationByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - app *model.Application - } - type res struct { - app *model.Application - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get app", - args: args{ - es: GetMockProjectAppsByIDsOK(ctrl), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, AppID: "AppID"}, - }, - res: res{ - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ClientID: "ClientID"}}, - }, - }, - { - name: "no events for project", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, AppID: "AppID"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "app has no id", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: func(err error) bool { - return caos_errs.IsPreconditionFailed(err) - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ApplicationByIDs(nil, tt.args.app.AggregateID, tt.args.app.AppID) - if !tt.res.wantErr && result.AggregateID != tt.res.app.AggregateID { - t.Errorf("got wrong result id: expected: %v, actual: %v ", tt.res.app.AggregateID, result.AggregateID) - } - if !tt.res.wantErr && result.AppID != tt.res.app.AppID { - t.Errorf("got wrong result appid: expected: %v, actual: %v ", tt.res.app.AppID, result.AppID) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddApplication(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - app *model.Application - } - type res struct { - result *model.Application - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add app, ok", - args: args{ - es: GetMockManipulateProjectWithPw(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - res: res{ - result: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - }, - { - name: "add app (none), ok", - args: args{ - es: GetMockManipulateProjectWithPw(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - AuthMethodType: model.OIDCAuthMethodTypeNone, - }, - }, - }, - res: res{ - result: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - AuthMethodType: model.OIDCAuthMethodTypeNone, - }, - }, - }, - }, - { - name: "invalid app", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddApplication(tt.args.ctx, tt.args.app) - if tt.res.errFunc == nil && err != nil { - t.Errorf("no error expected got:%T %v", err, err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.result != nil && result.AppID == "" { - t.Errorf("result has no id") - } - if tt.res.result != nil && (tt.res.result.OIDCConfig.AuthMethodType != model.OIDCAuthMethodTypeNone && result.OIDCConfig.ClientSecretString == "") { - t.Errorf("result has no client secret") - } - if tt.res.result != nil && result.OIDCConfig.ClientID == "" { - t.Errorf("result has no clientid") - } - if tt.res.result != nil && tt.res.result.Name != result.Name { - t.Errorf("got wrong result key: expected: %v, actual: %v ", tt.res.result.Name, result.Name) - } - }) - } -} - -func TestChangeApp(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - app *model.Application - } - type res struct { - result *model.Application - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change app, ok", - args: args{ - es: GetMockManipulateProjectWithOIDCApp(ctrl, model.OIDCAuthMethodTypeBasic), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "NameChanged", - }, - }, - res: res{ - result: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "NameChanged", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - }, - { - name: "invalid app", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeApplication(tt.args.ctx, tt.args.app) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.AppID != tt.res.result.AppID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.AppID, result.AppID) - } - if !tt.res.wantErr && result.Name != tt.res.result.Name { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.result.Name, result.Name) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveApp(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - app *model.Application - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove app, ok", - args: args{ - es: GetMockManipulateProjectWithOIDCApp(ctrl, model.OIDCAuthMethodTypeBasic), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - }, - }, - }, - { - name: "no appID", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveApplication(tt.args.ctx, tt.args.app) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestDeactivateApp(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - app *model.Application - } - type res struct { - result *model.Application - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate, ok", - args: args{ - es: GetMockManipulateProjectWithOIDCApp(ctrl, model.OIDCAuthMethodTypeBasic), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - }, - }, - res: res{ - result: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - State: model.AppStateInactive, - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - }, - { - name: "no app id", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.DeactivateApplication(tt.args.ctx, tt.args.app.AggregateID, tt.args.app.AppID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.AppID != tt.res.result.AppID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.AppID, result.AppID) - } - if !tt.res.wantErr && result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestReactivateApp(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - app *model.Application - } - type res struct { - result *model.Application - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate, ok", - args: args{ - es: GetMockManipulateProjectWithOIDCApp(ctrl, model.OIDCAuthMethodTypeBasic), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - }, - }, - res: res{ - result: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - State: model.AppStateActive, - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - }, - { - name: "no app id", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - app: &model.Application{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - AppID: "AppID", - Name: "Name", - OIDCConfig: &model.OIDCConfig{ - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - }, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ReactivateApplication(tt.args.ctx, tt.args.app.AggregateID, tt.args.app.AppID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.AppID != tt.res.result.AppID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.AppID, result.AppID) - } - if !tt.res.wantErr && result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeOIDCConfig(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - config *model.OIDCConfig - } - type res struct { - result *model.OIDCConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change oidc config, ok", - args: args{ - es: GetMockManipulateProjectWithOIDCApp(ctrl, model.OIDCAuthMethodTypeBasic), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeIDToken}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeImplicit}, - }, - }, - res: res{ - result: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeIDToken}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeImplicit}, - }, - }, - }, - { - name: "invalid config", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeIDToken}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app is not oidc", - args: args{ - es: GetMockManipulateProjectWithSAMLApp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeIDToken}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeImplicit}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeIDToken}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeImplicit}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeIDToken}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeImplicit}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeOIDCConfig(tt.args.ctx, tt.args.config) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.AppID != tt.res.result.AppID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.AppID, result.AppID) - } - if !tt.res.wantErr && result.ResponseTypes[0] != tt.res.result.ResponseTypes[0] { - t.Errorf("got wrong result responsetype: expected: %v, actual: %v ", tt.res.result.ResponseTypes[0], result.ResponseTypes[0]) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeOIDCConfigSecret(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - config *model.OIDCConfig - } - type res struct { - result *model.OIDCConfig - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change oidc config secret, ok", - args: args{ - es: GetMockManipulateProjectWithOIDCApp(ctrl, model.OIDCAuthMethodTypeBasic), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - }, - }, - res: res{ - result: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - ResponseTypes: []model.OIDCResponseType{model.OIDCResponseTypeCode}, - GrantTypes: []model.OIDCGrantType{model.OIDCGrantTypeAuthorizationCode}, - AuthMethodType: model.OIDCAuthMethodTypeBasic, - }, - }, - }, - { - name: "auth method none, error", - args: args{ - es: GetMockManipulateProjectWithOIDCApp(ctrl, model.OIDCAuthMethodTypeNone), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no appID", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app is not oidc", - args: args{ - es: GetMockManipulateProjectWithSAMLApp(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - config: &model.OIDCConfig{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 0}, - AppID: "AppID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeOIDCConfigSecret(tt.args.ctx, tt.args.config.AggregateID, tt.args.config.AppID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.AppID != tt.res.result.AppID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.AppID, result.AppID) - } - if !tt.res.wantErr && result.ClientSecretString == "" { - t.Errorf("got wrong result must have client secret") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - grant *model.ProjectGrant - } - type res struct { - grant *model.ProjectGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get grant", - args: args{ - es: GetMockProjectGrantByIDsOK(ctrl), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID"}, - }, - res: res{ - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"Key"}, - }, - }, - }, - { - name: "no events for project", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "grant has no id", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: func(err error) bool { - return caos_errs.IsPreconditionFailed(err) - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ProjectGrantByIDs(nil, tt.args.grant.AggregateID, tt.args.grant.GrantID) - if !tt.res.wantErr && result.AggregateID != tt.res.grant.AggregateID { - t.Errorf("got wrong result id: expected: %v, actual: %v ", tt.res.grant.AggregateID, result.AggregateID) - } - if !tt.res.wantErr && result.GrantID != tt.res.grant.GrantID { - t.Errorf("got wrong result grantid: expected: %v, actual: %v ", tt.res.grant.GrantID, result.GrantID) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddProjectGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - grant *model.ProjectGrant - } - type res struct { - result *model.ProjectGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add grant, ok", - args: args{ - es: GetMockManipulateProjectWithRole(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"Key"}, - }, - }, - res: res{ - result: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"Key"}, - }, - }, - }, - { - name: "invalid grant", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant for org already exists", - args: args{ - es: GetMockManipulateProjectWithGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "role not existing on project", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"Key"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"Key"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddProjectGrant(tt.args.ctx, tt.args.grant) - - if !tt.res.wantErr && result.GrantID == "" { - t.Errorf("result has no id") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveProjectGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - grant *model.ProjectGrant - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove app, ok", - args: args{ - es: GetMockManipulateProjectWithGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - }, - { - name: "no grantID", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveProjectGrant(tt.args.ctx, tt.args.grant) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestDeactivateProjectGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - grant *model.ProjectGrant - } - type res struct { - result *model.ProjectGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate, ok", - args: args{ - es: GetMockManipulateProjectWithGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - result: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - State: model.ProjectGrantStateInactive, - }, - }, - }, - { - name: "no grant id", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.DeactivateProjectGrant(tt.args.ctx, tt.args.grant.AggregateID, tt.args.grant.GrantID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.GrantID != tt.res.result.GrantID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.GrantID, result.GrantID) - } - if !tt.res.wantErr && result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestReactivateProjectGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - grant *model.ProjectGrant - } - type res struct { - result *model.ProjectGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate, ok", - args: args{ - es: GetMockManipulateProjectWithGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - result: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - State: model.ProjectGrantStateActive, - }, - }, - }, - { - name: "no grant id", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant not existing", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ReactivateProjectGrant(tt.args.ctx, tt.args.grant.AggregateID, tt.args.grant.GrantID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.GrantID != tt.res.result.GrantID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.GrantID, result.GrantID) - } - if !tt.res.wantErr && result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantMemberByIDs(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - member *model.ProjectGrantMember - } - type res struct { - member *model.ProjectGrantMember - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "projectgrant member from events, ok", - args: args{ - es: GetMockProjectGrantMemberByIDsOK(ctrl), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID", UserID: "UserID"}, - }, - res: res{ - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}, - }, - }, - { - name: "no project events", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID", UserID: "UserID"}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "member id missing", - args: args{ - es: GetMockProjectByIDNoEvents(ctrl), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: func(err error) bool { - return caos_errs.IsPreconditionFailed(err) - }, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ProjectGrantMemberByIDs(nil, tt.args.member) - if !tt.res.wantErr && result.AggregateID != tt.res.member.AggregateID { - t.Errorf("got wrong result id: expected: %v, actual: %v ", tt.res.member.AggregateID, result.AggregateID) - } - if !tt.res.wantErr && result.UserID != tt.res.member.UserID { - t.Errorf("got wrong result userid: expected: %v, actual: %v ", tt.res.member.UserID, result.UserID) - } - if !tt.res.wantErr && len(result.Roles) != len(tt.res.member.Roles) { - t.Errorf("got wrong result roles: expected: %v, actual: %v ", tt.res.member.Roles, result.Roles) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddProjectGrantMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - member *model.ProjectGrantMember - } - type res struct { - result *model.ProjectGrantMember - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add project grant member", - args: args{ - es: GetMockManipulateProjectWithGrantExistingRole(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"Role"}, - }, - }, - res: res{ - result: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"Role"}, - }, - }, - }, - { - name: "invalid member", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "member already existing", - args: args{ - es: GetMockManipulateProjectWithGrantMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsErrorAlreadyExists, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddProjectGrantMember(tt.args.ctx, tt.args.member) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.GrantID != tt.res.result.GrantID { - t.Errorf("got wrong result ProjectGrantID: expected: %v, actual: %v ", tt.res.result.GrantID, result.GrantID) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeProjectGrantMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - member *model.ProjectGrantMember - } - type res struct { - result *model.ProjectGrantMember - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change project grant member", - args: args{ - es: GetMockManipulateProjectWithGrantMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"RoleChanged"}, - }, - }, - res: res{ - result: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"RoleChanged"}, - }, - }, - }, - { - name: "invalid member", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "user not member of grant", - args: args{ - es: GetMockManipulateProjectWithGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeProjectGrantMember(tt.args.ctx, tt.args.member) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.GrantID != tt.res.result.GrantID { - t.Errorf("got wrong result ProjectGrantID: expected: %v, actual: %v ", tt.res.result.GrantID, result.GrantID) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveProjectGrantMember(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - ctx context.Context - member *model.ProjectGrantMember - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove project grant member", - args: args{ - es: GetMockManipulateProjectWithGrantMember(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"RoleChanged"}, - }, - }, - }, - { - name: "invalid member", - args: args{ - es: GetMockManipulateProject(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing project not found", - args: args{ - es: GetMockManipulateProjectNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "user not member of grant", - args: args{ - es: GetMockManipulateProjectWithGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "ProjectGrantID", - UserID: "UserID", - Roles: []string{"Role"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveProjectGrantMember(tt.args.ctx, tt.args.member) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} -func TestChangesProject(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - id string - lastSequence uint64 - limit uint64 - } - type res struct { - changes *model.ProjectChanges - project *model.Project - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "changes from events, ok", - args: args{ - es: GetMockChangesProjectOK(ctrl), - id: "1", - lastSequence: 0, - limit: 0, - }, - res: res{ - changes: &model.ProjectChanges{ - Changes: []*model.ProjectChange{ - {EventType: "", Sequence: 1, ModifierId: ""}, - }, - LastSequence: 1, - }, - project: &model.Project{Name: "MusterProject"}, - }, - }, - { - name: "changes from events, no events", - args: args{ - es: GetMockChangesProjectNoEvents(ctrl), - id: "2", - lastSequence: 0, - limit: 0, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ProjectChanges(nil, tt.args.id, tt.args.lastSequence, tt.args.limit, false) - - project := &model.Project{} - if result != nil && len(result.Changes) > 0 { - b, err := json.Marshal(result.Changes[0].Data) - json.Unmarshal(b, project) - if err != nil { - } - } - if !tt.res.wantErr && result.LastSequence != tt.res.changes.LastSequence && project.Name != tt.res.project.Name { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.changes.LastSequence, result.LastSequence) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangesApplication(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *ProjectEventstore - id string - secID string - lastSequence uint64 - limit uint64 - } - type res struct { - changes *model.ApplicationChanges - app *model.Application - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "changes from events, ok", - args: args{ - es: GetMockChangesApplicationOK(ctrl), - id: "1", - secID: "AppId", - lastSequence: 0, - limit: 0, - }, - res: res{ - changes: &model.ApplicationChanges{ - Changes: []*model.ApplicationChange{ - {EventType: "", Sequence: 1, ModifierId: ""}, - }, - LastSequence: 1, - }, - app: &model.Application{Name: "MusterApp", AppID: "AppId", Type: 3}, - }, - }, - { - name: "changes from events, no events", - args: args{ - es: GetMockChangesApplicationNoEvents(ctrl), - id: "2", - secID: "2", - lastSequence: 0, - limit: 0, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ApplicationChanges(nil, tt.args.id, tt.args.secID, tt.args.lastSequence, tt.args.limit, false) - - app := &model.Application{} - if result != nil && len(result.Changes) > 0 { - b, err := json.Marshal(result.Changes[0].Data) - json.Unmarshal(b, app) - if err != nil { - } - } - if !tt.res.wantErr && result.LastSequence != tt.res.changes.LastSequence && app.Name != tt.res.app.Name { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.changes.LastSequence, result.LastSequence) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/project/repository/eventsourcing/model/project_role_test.go b/internal/project/repository/eventsourcing/model/project_role_test.go deleted file mode 100644 index 30bf26e3ef..0000000000 --- a/internal/project/repository/eventsourcing/model/project_role_test.go +++ /dev/null @@ -1,118 +0,0 @@ -package model - -import ( - "encoding/json" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "testing" -) - -func TestAppendAddRoleEvent(t *testing.T) { - type args struct { - project *Project - role *ProjectRole - event *es_models.Event - } - tests := []struct { - name string - args args - result *Project - }{ - { - name: "append add role event", - args: args{ - project: &Project{}, - role: &ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}, - event: &es_models.Event{}, - }, - result: &Project{Roles: []*ProjectRole{&ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}}}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.args.role != nil { - data, _ := json.Marshal(tt.args.role) - tt.args.event.Data = data - } - tt.args.project.appendAddRoleEvent(tt.args.event) - if len(tt.args.project.Roles) != 1 { - t.Errorf("got wrong result should have one role actual: %v ", len(tt.args.project.Roles)) - } - if tt.args.project.Roles[0] == tt.result.Roles[0] { - t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Roles[0], tt.args.project.Roles[0]) - } - }) - } -} - -func TestAppendChangeRoleEvent(t *testing.T) { - type args struct { - project *Project - role *ProjectRole - event *es_models.Event - } - tests := []struct { - name string - args args - result *Project - }{ - { - name: "append change role event", - args: args{ - project: &Project{Roles: []*ProjectRole{&ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}}}, - role: &ProjectRole{Key: "Key", DisplayName: "DisplayNameChanged", Group: "Group"}, - event: &es_models.Event{}, - }, - result: &Project{Roles: []*ProjectRole{&ProjectRole{Key: "Key", DisplayName: "DisplayNameChanged", Group: "Group"}}}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.args.role != nil { - data, _ := json.Marshal(tt.args.role) - tt.args.event.Data = data - } - tt.args.project.appendChangeRoleEvent(tt.args.event) - if len(tt.args.project.Roles) != 1 { - t.Errorf("got wrong result should have one role actual: %v ", len(tt.args.project.Roles)) - } - if tt.args.project.Roles[0] == tt.result.Roles[0] { - t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Roles[0], tt.args.project.Roles[0]) - } - }) - } -} - -func TestAppendRemoveRoleEvent(t *testing.T) { - type args struct { - project *Project - role *ProjectRole - event *es_models.Event - } - tests := []struct { - name string - args args - result *Project - }{ - { - name: "append remove role event", - args: args{ - project: &Project{Roles: []*ProjectRole{&ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}}}, - role: &ProjectRole{Key: "Key"}, - event: &es_models.Event{}, - }, - result: &Project{Roles: []*ProjectRole{}}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if tt.args.role != nil { - data, _ := json.Marshal(tt.args.role) - tt.args.event.Data = data - } - tt.args.project.appendRemoveRoleEvent(tt.args.event) - if len(tt.args.project.Roles) != 0 { - t.Errorf("got wrong result should have no role actual: %v ", len(tt.args.project.Roles)) - } - }) - } -} diff --git a/internal/project/repository/eventsourcing/project.go b/internal/project/repository/eventsourcing/project.go index 363231612b..c7655b1b97 100644 --- a/internal/project/repository/eventsourcing/project.go +++ b/internal/project/repository/eventsourcing/project.go @@ -3,16 +3,11 @@ package eventsourcing import ( "context" - "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" es_models "github.com/caos/zitadel/internal/eventstore/models" es_sdk "github.com/caos/zitadel/internal/eventstore/sdk" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - usr_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" ) func ProjectByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) { @@ -36,194 +31,6 @@ func ProjectAggregate(ctx context.Context, aggCreator *es_models.AggregateCreato return aggCreator.NewAggregate(ctx, project.AggregateID, model.ProjectAggregate, model.ProjectVersion, project.Sequence) } -func ProjectAggregateOverwriteContext(ctx context.Context, aggCreator *es_models.AggregateCreator, project *model.Project, resourceOwnerID string, userID string) (*es_models.Aggregate, error) { - if project == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ADv2r", "Errors.Internal") - } - - return aggCreator.NewAggregate(ctx, project.AggregateID, model.ProjectAggregate, model.ProjectVersion, project.Sequence, es_models.OverwriteResourceOwner(resourceOwnerID), es_models.OverwriteEditorUser(userID)) -} - -func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if project == nil || member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kdie6", "Errors.Internal") - } - - agg, err := ProjectAggregate(ctx, aggCreator, project) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.ProjectAggregate). - ResourceOwnerFilter(authz.GetCtxData(ctx).OrgID). - EventTypesFilter(model.ProjectAdded, model.ProjectChanged, model.ProjectRemoved) - - validation := addProjectValidation(project.Name) - agg, err = agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectAdded, project) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.ProjectMemberAdded, member) - } -} - -func ProjectUpdateAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, newProject *model.Project) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if newProject == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - changes := existingProject.Changes(newProject) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-9soPE", "Errors.NoChangesFound") - } - if existingProject.Name != newProject.Name { - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(model.ProjectAggregate). - EventTypesFilter(model.ProjectAdded, model.ProjectChanged, model.ProjectRemoved) - - validation := addProjectValidation(newProject.Name) - agg.SetPrecondition(validationQuery, validation) - } - return agg.AppendEvent(model.ProjectChanged, changes) - } -} - -func ProjectDeactivateAggregate(aggCreator *es_models.AggregateCreator, project *model.Project) func(ctx context.Context) (*es_models.Aggregate, error) { - return projectStateAggregate(aggCreator, project, model.ProjectDeactivated) -} - -func ProjectReactivateAggregate(aggCreator *es_models.AggregateCreator, project *model.Project) func(ctx context.Context) (*es_models.Aggregate, error) { - return projectStateAggregate(aggCreator, project, model.ProjectReactivated) -} - -func projectStateAggregate(aggCreator *es_models.AggregateCreator, project *model.Project, state models.EventType) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := ProjectAggregate(ctx, aggCreator, project) - if err != nil { - return nil, err - } - return agg.AppendEvent(state, nil) - } -} - -func ProjectRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingProject *model.Project) (*es_models.Aggregate, error) { - if existingProject == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Cj7lb", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.ProjectRemoved, existingProject) -} - -func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ie34f", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(usr_model.UserAggregate). - AggregateIDFilter(member.UserID) - - validation := addProjectMemberValidation() - return agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectMemberAdded, member) - } -} - -func ProjectMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d34fs", "Errors.Internal") - } - - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.ProjectMemberChanged, member) - } -} - -func ProjectMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dieu7", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.ProjectMemberRemoved, member) - } -} - -func ProjectRoleAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, roles ...*model.ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if roles == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sleo9", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - for _, role := range roles { - agg, err = agg.AppendEvent(model.ProjectRoleAdded, role) - if err != nil { - return nil, err - } - } - return agg, nil - } -} - -func ProjectRoleChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, role *model.ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if role == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-oe8sf", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.ProjectRoleChanged, role) - } -} - -func ProjectRoleRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingProject *model.Project, role *model.ProjectRole, grants []*model.ProjectGrant) (*es_models.Aggregate, error) { - if role == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d8eis", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.ProjectRoleRemoved, role) - if err != nil { - return nil, err - } - for _, grant := range grants { - var changes map[string]interface{} - if _, g := model.GetProjectGrant(existingProject.Grants, grant.GrantID); grant != nil { - changes = g.Changes(grant) - agg, err = agg.AppendEvent(model.ProjectGrantCascadeChanged, changes) - if err != nil { - return nil, err - } - } - } - return agg, nil -} - func ApplicationAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) (*es_models.Aggregate, error) { if app == nil { @@ -244,95 +51,6 @@ func ApplicationAddedAggregate(aggCreator *es_models.AggregateCreator, existingP } } -func ApplicationChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if app == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sleo9", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - var changes map[string]interface{} - for _, a := range existingProject.Applications { - if a.AppID == app.AppID { - changes = a.Changes(app) - } - } - agg.AppendEvent(model.ApplicationChanged, changes) - - return agg, nil - } -} - -func ApplicationRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if app == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-se23g", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - agg.AppendEvent(model.ApplicationRemoved, &model.ApplicationID{AppID: app.AppID}) - - return agg, nil - } -} - -func ApplicationDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if app == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slfi3", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - agg.AppendEvent(model.ApplicationDeactivated, &model.ApplicationID{AppID: app.AppID}) - - return agg, nil - } -} - -func ApplicationReactivatedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, app *model.Application) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if app == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - agg.AppendEvent(model.ApplicationReactivated, &model.ApplicationID{AppID: app.AppID}) - - return agg, nil - } -} - -func OIDCConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, config *model.OIDCConfig) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if config == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - var changes map[string]interface{} - for _, a := range existingProject.Applications { - if a.AppID == config.AppID { - if a.OIDCConfig != nil { - changes = a.OIDCConfig.Changes(config) - } - } - } - agg.AppendEvent(model.OIDCConfigChanged, changes) - - return agg, nil - } -} - func APIConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, config *model.APIConfig) func(ctx context.Context) (*es_models.Aggregate, error) { return func(ctx context.Context) (*es_models.Aggregate, error) { if config == nil { @@ -444,219 +162,3 @@ func OIDCApplicationKeyRemovedAggregate(aggCreator *es_models.AggregateCreator, return agg, nil } } - -func ProjectGrantAddedAggregate(aggCreator *es_models.AggregateCreator, project *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kd89w", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, project) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(org_es_model.OrgAggregate). - AggregateIDFilter(grant.GrantedOrgID) - - validation := addProjectGrantValidation() - agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectGrantAdded, grant) - return agg, nil - } -} - -func ProjectGrantChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d9ie2", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - var changes map[string]interface{} - for _, g := range existingProject.Grants { - if g.GrantID == grant.GrantID { - changes = g.Changes(grant) - } - } - agg.AppendEvent(model.ProjectGrantChanged, changes) - - return agg, nil - } -} - -func ProjectGrantRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kci8d", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - agg.AppendEvent(model.ProjectGrantRemoved, &model.ProjectGrantID{GrantID: grant.GrantID}) - - return agg, nil - } -} - -func ProjectGrantDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-id832", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - agg.AppendEvent(model.ProjectGrantDeactivated, &model.ProjectGrantID{GrantID: grant.GrantID}) - - return agg, nil - } -} - -func ProjectGrantReactivatedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, grant *model.ProjectGrant) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-8diw2", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.ProjectGrantReactivated, &model.ProjectGrantID{GrantID: grant.GrantID}) - } -} - -func ProjectGrantMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectGrantMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4ufh6", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(usr_model.UserAggregate). - AggregateIDFilter(member.UserID) - - validation := addProjectGrantMemberValidation() - return agg.SetPrecondition(validationQuery, validation).AppendEvent(model.ProjectGrantMemberAdded, member) - } -} - -func ProjectGrantMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectGrantMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d8i4h", "Errors.Internal") - } - - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - changes := make(map[string]interface{}, 1) - changes["grantId"] = member.GrantID - changes["userId"] = member.UserID - changes["roles"] = member.Roles - - return agg.AppendEvent(model.ProjectGrantMemberChanged, changes) - } -} - -func ProjectGrantMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existingProject *model.Project, member *model.ProjectGrantMember) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if member == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slp0r", "Errors.Internal") - } - agg, err := ProjectAggregate(ctx, aggCreator, existingProject) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.ProjectGrantMemberRemoved, member) - } -} - -func addProjectValidation(projectName string) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - projects := make([]*model.Project, 0) - for _, event := range events { - switch event.Type { - case model.ProjectAdded: - project := &model.Project{ObjectRoot: es_models.ObjectRoot{AggregateID: event.AggregateID}} - project.AppendAddProjectEvent(event) - projects = append(projects, project) - case model.ProjectChanged: - _, project := model.GetProject(projects, event.AggregateID) - project.AppendAddProjectEvent(event) - case model.ProjectRemoved: - for i := len(projects) - 1; i >= 0; i-- { - if projects[i].AggregateID == event.AggregateID { - projects[i] = projects[len(projects)-1] - projects[len(projects)-1] = nil - projects = projects[:len(projects)-1] - } - } - } - } - for _, p := range projects { - if p.Name == projectName { - return errors.ThrowPreconditionFailed(nil, "EVENT-s9oPw", "Errors.Project.AlreadyExists") - } - } - return nil - } -} - -func addProjectMemberValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - return checkExistsUser(events...) - } -} - -func addProjectGrantValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existsOrg := false - for _, event := range events { - switch event.AggregateType { - case org_es_model.OrgAggregate: - switch event.Type { - case org_es_model.OrgAdded: - existsOrg = true - case org_es_model.OrgRemoved: - existsOrg = false - } - } - } - if existsOrg { - return nil - } - return errors.ThrowPreconditionFailed(nil, "EVENT-3OfIm", "Errors.Project.OrgNotExisting") - } -} - -func addProjectGrantMemberValidation() func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - return checkExistsUser(events...) - } -} - -func checkExistsUser(events ...*es_models.Event) error { - existsUser := false - for _, event := range events { - switch event.AggregateType { - case usr_model.UserAggregate: - switch event.Type { - case usr_model.UserAdded, usr_model.UserRegistered, usr_model.HumanRegistered, usr_model.MachineAdded, usr_model.HumanAdded: - existsUser = true - case usr_model.UserRemoved: - existsUser = false - } - } - } - if existsUser { - return nil - } - return errors.ThrowPreconditionFailed(nil, "EVENT-3OfIm", "Errors.Project.UserNotExisting") -} diff --git a/internal/project/repository/eventsourcing/project_test.go b/internal/project/repository/eventsourcing/project_test.go deleted file mode 100644 index 8d6ebf2b1e..0000000000 --- a/internal/project/repository/eventsourcing/project_test.go +++ /dev/null @@ -1,2277 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - - "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/crypto" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - proj_model "github.com/caos/zitadel/internal/project/model" - "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" -) - -func TestProjectByIDQuery(t *testing.T) { - type args struct { - id string - sequence uint64 - } - type res struct { - filterLen int - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project by id query ok", - args: args{ - id: "AggregateID", - sequence: 1, - }, - res: res{ - filterLen: 3, - }, - }, - { - name: "project by id query, no id", - args: args{ - sequence: 1, - }, - res: res{ - filterLen: 3, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - query, err := ProjectByIDQuery(tt.args.id, tt.args.sequence) - if !tt.res.wantErr && query == nil { - t.Errorf("query should not be nil") - } - if !tt.res.wantErr && len(query.Filters) != tt.res.filterLen { - t.Errorf("got wrong filter len: expected: %v, actual: %v ", tt.res.filterLen, len(query.Filters)) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectQuery(t *testing.T) { - type args struct { - sequence uint64 - } - type res struct { - filterLen int - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project query ok", - args: args{ - sequence: 1, - }, - res: res{ - filterLen: 2, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - query := ProjectQuery(tt.args.sequence) - if query == nil { - t.Errorf("query should not be nil") - } - if len(query.Filters) != tt.res.filterLen { - t.Errorf("got wrong filter len: expected: %v, actual: %v ", tt.res.filterLen, len(query.Filters)) - } - }) - } -} - -func TestProjectAggregate(t *testing.T) { - type args struct { - ctx context.Context - aggCreator *models.AggregateCreator - project *model.Project - } - type res struct { - eventLen int - aggType models.AggregateType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "create aggregate", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - aggCreator: models.NewAggregateCreator("Test"), - project: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - eventLen: 0, - aggType: model.ProjectAggregate, - }, - }, - { - name: "project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 0, - aggType: model.ProjectAggregate, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.project) - - if !tt.res.wantErr && agg == nil { - t.Errorf("agg should not be nil") - } - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectCreateAggregate(t *testing.T) { - type args struct { - ctx context.Context - new *model.Project - member *model.ProjectMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project update aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - new: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - member: &model.ProjectMember{UserID: "UserID"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventType: []models.EventType{model.ProjectAdded, model.ProjectMemberAdded}, - }, - }, - { - name: "new project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - new: nil, - member: &model.ProjectMember{UserID: "UserID"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "new member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - new: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - member: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectCreateAggregate(tt.args.aggCreator, tt.args.new, tt.args.member)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - - if !tt.res.wantErr { - for i := range agg.Events { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventType[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectUpdateAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.Project - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project update aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName_Changed", State: int32(proj_model.ProjectStateActive)}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectChanged, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "new project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectUpdateAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectDeactivateAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project deactivate aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectDeactivated, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectDeactivated, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectDeactivateAggregate(tt.args.aggCreator, tt.args.existingProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectReactivateAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project reactivate aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateInactive)}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectReactivated, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectReactivated, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectReactivateAggregate(tt.args.aggCreator, tt.args.existingProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectMemberAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - new *model.ProjectMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "projectmember added ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - new: &model.ProjectMember{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, UserID: "UserID", Roles: []string{"Roles"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberAdded, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberAdded, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - new: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberAdded, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectMemberAddedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.new)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectMemberChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "projectmember changed ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectMember{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, UserID: "UserID", Roles: []string{"Roles"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberChanged, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectMemberChangedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectMemberRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "projectmember removed ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectMember{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, UserID: "UserID", Roles: []string{"Roles"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberRemoved, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberRemoved, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectMemberRemoved, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectMemberRemovedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectRoleAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject []*model.ProjectRole - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "projectrole added ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: []*model.ProjectRole{{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Key: "Key"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectRoleAdded, - }, - }, - { - name: "projectrole multiple added ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: []*model.ProjectRole{ - {ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Key: "Key"}, - {ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Key: "Key2"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventType: model.ProjectRoleAdded, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectRoleAdded, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectRoleAdded, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectRoleAddedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject...)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectRoleChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectRole - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "projectmember changed ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectRole{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Key: "Key"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectRoleChanged, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectRoleChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectRoleChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectRoleChangedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectRoleRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectRole - grants []*model.ProjectGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "projectrole changed ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectRole{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Key: "Key"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ProjectRoleRemoved}, - }, - }, - { - name: "projectrole changed with grant", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Grants: []*model.ProjectGrant{{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"ROLE"}}}, - }, - newProject: &model.ProjectRole{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Key: "Key"}, - grants: []*model.ProjectGrant{{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{}}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.ProjectRoleRemoved, model.ProjectGrantCascadeChanged}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectRoleRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingProject, tt.args.newProject, tt.args.grants) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if agg != nil { - for i := range agg.Events { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectAppAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.Application - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add oidc application", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.Application{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AppID: "AppId", - Name: "Name", - OIDCConfig: &model.OIDCConfig{AppID: "AppID", ClientID: "ClientID"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.ApplicationAdded, model.OIDCConfigAdded}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ApplicationAddedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectAppChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.Application - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Applications: []*model.Application{ - {AppID: "AppID", Name: "Name"}, - }}, - newProject: &model.Application{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AppID: "AppId", - Name: "NameChanged", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ApplicationChanged}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ApplicationChangedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectAppRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.Application - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Applications: []*model.Application{ - {AppID: "AppID", Name: "Name"}, - }}, - newProject: &model.Application{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AppID: "AppId", - Name: "Name", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ApplicationRemoved}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ApplicationRemovedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectAppDeactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.Application - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Applications: []*model.Application{ - {AppID: "AppID", Name: "Name"}, - }}, - newProject: &model.Application{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AppID: "AppId", - Name: "Name", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ApplicationDeactivated}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ApplicationDeactivatedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectAppReactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.Application - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Applications: []*model.Application{ - {AppID: "AppID", Name: "Name"}, - }}, - newProject: &model.Application{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AppID: "AppId", - Name: "Name", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ApplicationReactivated}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ApplicationReactivatedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOIDCConfigchangAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.OIDCConfig - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Applications: []*model.Application{ - {AppID: "AppID", Name: "Name", OIDCConfig: &model.OIDCConfig{AppID: "AppID", AuthMethodType: 1}}, - }}, - newProject: &model.OIDCConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AppID: "AppID", - AuthMethodType: 2, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.OIDCConfigChanged}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "app nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := OIDCConfigChangedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOIDCConfigSecretChangeAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.OIDCConfig - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change client secret", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Applications: []*model.Application{ - {AppID: "AppID", Name: "Name", OIDCConfig: &model.OIDCConfig{AppID: "AppID", AuthMethodType: 1}}, - }}, - newProject: &model.OIDCConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AppID: "AppID", - ClientSecret: &crypto.CryptoValue{}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.OIDCConfigSecretChanged}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - newProject: &model.OIDCConfig{ - ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, - AppID: "AppID", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := OIDCConfigSecretChangedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject.AppID, tt.args.newProject.ClientSecret)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "projectgrant added ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectGrant{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "ProjectGrantID", GrantedOrgID: "OrgID"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantAdded, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantAdded, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantAdded, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectGrantAddedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change project grant", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Grants: []*model.ProjectGrant{ - {GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}, - }}, - newProject: &model.ProjectGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"KeyChanged"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ProjectGrantChanged}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "projectgrant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectGrantChangedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Grants: []*model.ProjectGrant{ - {GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID"}, - }}, - newProject: &model.ProjectGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"KeyChanged"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ProjectGrantRemoved}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "projectgrant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectGrantRemovedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantDeactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate project grant", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateActive), - Grants: []*model.ProjectGrant{ - {GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID"}, - }}, - newProject: &model.ProjectGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"KeyChanged"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ProjectGrantDeactivated}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectGrantDeactivatedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantReactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate project grant", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Name: "ProjectName", - State: int32(proj_model.ProjectStateInactive), - Grants: []*model.ProjectGrant{ - {GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID"}, - }}, - newProject: &model.ProjectGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - GrantID: "ProjectGrantID", - GrantedOrgID: "GrantedOrgID", - RoleKeys: []string{"KeyChanged"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.ProjectGrantReactivated}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateInactive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectGrantReactivatedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if !tt.res.wantErr && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantMemberAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectGrantMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project grant member added ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectGrantMember{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Roles"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberAdded, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberAdded, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberAdded, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectGrantMemberAddedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantMemberChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectGrantMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project grant member changed ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectGrantMember{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", Roles: []string{"RolesChanged"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberChanged, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberChanged, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectGrantMemberChangedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProjectGrantMemberRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingProject *model.Project - newProject *model.ProjectGrantMember - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "project grant member removed ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectGrantMember{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", Roles: []string{"Roles"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberRemoved, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberRemoved, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "member nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.ProjectGrantMemberRemoved, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProjectGrantMemberRemovedAggregate(tt.args.aggCreator, tt.args.existingProject, tt.args.newProject)(tt.args.ctx) - - if !tt.res.wantErr && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if !tt.res.wantErr && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if !tt.res.wantErr && agg.Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/user/repository/eventsourcing/codes.go b/internal/user/repository/eventsourcing/codes.go deleted file mode 100644 index 9d57db2904..0000000000 --- a/internal/user/repository/eventsourcing/codes.go +++ /dev/null @@ -1,18 +0,0 @@ -package eventsourcing - -import ( - "github.com/caos/zitadel/internal/crypto" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -func (es *UserEventstore) generatePasswordCode(passwordCode *model.PasswordCode, notifyType usr_model.NotificationType) error { - passwordCodeCrypto, _, err := crypto.NewCode(es.PasswordVerificationCode) - if err != nil { - return err - } - passwordCode.Code = passwordCodeCrypto - passwordCode.Expiry = es.PasswordVerificationCode.Expiry() - passwordCode.NotificationType = int32(notifyType) - return nil -} diff --git a/internal/user/repository/eventsourcing/eventstore.go b/internal/user/repository/eventsourcing/eventstore.go index 7beeef6b1c..6ff897b525 100644 --- a/internal/user/repository/eventsourcing/eventstore.go +++ b/internal/user/repository/eventsourcing/eventstore.go @@ -2,47 +2,22 @@ package eventsourcing import ( "context" - "fmt" - "time" - "github.com/caos/logging" - "github.com/golang/protobuf/ptypes" - "github.com/pquerna/otp/totp" - - req_model "github.com/caos/zitadel/internal/auth_request/model" "github.com/caos/zitadel/internal/cache/config" sd "github.com/caos/zitadel/internal/config/systemdefaults" - "github.com/caos/zitadel/internal/crypto" "github.com/caos/zitadel/internal/errors" caos_errs "github.com/caos/zitadel/internal/errors" es_int "github.com/caos/zitadel/internal/eventstore" es_models "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" - "github.com/caos/zitadel/internal/id" - key_model "github.com/caos/zitadel/internal/key/model" - global_model "github.com/caos/zitadel/internal/model" - "github.com/caos/zitadel/internal/telemetry/tracing" usr_model "github.com/caos/zitadel/internal/user/model" "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - webauthn_helper "github.com/caos/zitadel/internal/webauthn" + "github.com/golang/protobuf/ptypes" ) type UserEventstore struct { es_int.Eventstore - userCache *UserCache - idGenerator id.Generator - domain string - PasswordAlg crypto.HashAlgorithm - InitializeUserCode crypto.Generator - EmailVerificationCode crypto.Generator - PhoneVerificationCode crypto.Generator - PasswordVerificationCode crypto.Generator - MachineKeyAlg crypto.EncryptionAlgorithm - MachineKeySize int - Multifactors global_model.Multifactors - validateTOTP func(string, string) bool - webauthn *webauthn_helper.WebAuthN + userCache *UserCache } type UserConfig struct { @@ -56,40 +31,9 @@ func StartUser(conf UserConfig, systemDefaults sd.SystemDefaults) (*UserEventsto if err != nil { return nil, err } - aesCrypto, err := crypto.NewAESCrypto(systemDefaults.UserVerificationKey) - if err != nil { - return nil, err - } - initCodeGen := crypto.NewEncryptionGenerator(systemDefaults.SecretGenerators.InitializeUserCode, aesCrypto) - emailVerificationCode := crypto.NewEncryptionGenerator(systemDefaults.SecretGenerators.EmailVerificationCode, aesCrypto) - phoneVerificationCode := crypto.NewEncryptionGenerator(systemDefaults.SecretGenerators.PhoneVerificationCode, aesCrypto) - passwordVerificationCode := crypto.NewEncryptionGenerator(systemDefaults.SecretGenerators.PasswordVerificationCode, aesCrypto) - aesOTPCrypto, err := crypto.NewAESCrypto(systemDefaults.Multifactors.OTP.VerificationKey) - passwordAlg := crypto.NewBCrypt(systemDefaults.SecretGenerators.PasswordSaltCost) - web, err := webauthn_helper.StartServer(systemDefaults.WebAuthN) - if err != nil { - return nil, err - } return &UserEventstore{ - Eventstore: conf.Eventstore, - userCache: userCache, - idGenerator: id.SonyFlakeGenerator, - domain: systemDefaults.Domain, - InitializeUserCode: initCodeGen, - EmailVerificationCode: emailVerificationCode, - PhoneVerificationCode: phoneVerificationCode, - PasswordVerificationCode: passwordVerificationCode, - Multifactors: global_model.Multifactors{ - OTP: global_model.OTP{ - CryptoMFA: aesOTPCrypto, - Issuer: systemDefaults.Multifactors.OTP.Issuer, - }, - }, - PasswordAlg: passwordAlg, - validateTOTP: totp.Validate, - MachineKeyAlg: aesCrypto, - MachineKeySize: int(systemDefaults.SecretGenerators.MachineKeySize), - webauthn: web, + Eventstore: conf.Eventstore, + userCache: userCache, }, nil } @@ -133,235 +77,6 @@ func (es *UserEventstore) UserEventsByID(ctx context.Context, id string, sequenc return es.FilterEvents(ctx, query) } -func (es *UserEventstore) prepareCreateMachine(ctx context.Context, user *usr_model.User, orgIamPolicy *iam_model.OrgIAMPolicyView, resourceOwner string) (*model.User, []*es_models.Aggregate, error) { - machine := model.UserFromModel(user) - - if !orgIamPolicy.UserLoginMustBeDomain { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-cJlnI", "Errors.User.Invalid") - } - - createAggregates, err := MachineCreateAggregate(ctx, es.AggregateCreator(), machine, resourceOwner, true) - - return machine, createAggregates, err -} - -func (es *UserEventstore) prepareCreateHuman(ctx context.Context, user *usr_model.User, pwPolicy *iam_model.PasswordComplexityPolicyView, orgIAMPolicy *iam_model.OrgIAMPolicyView, resourceOwner string) (*model.User, []*es_models.Aggregate, error) { - err := user.CheckOrgIAMPolicy(orgIAMPolicy) - if err != nil { - return nil, nil, err - } - user.SetNamesAsDisplayname() - if !user.IsValid() { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-LoIxJ", "Errors.User.Invalid") - } - - err = user.HashPasswordIfExisting(pwPolicy, es.PasswordAlg, true) - if err != nil { - return nil, nil, err - } - err = user.GenerateInitCodeIfNeeded(es.InitializeUserCode) - if err != nil { - return nil, nil, err - } - err = user.GeneratePhoneCodeIfNeeded(es.PhoneVerificationCode) - if err != nil { - return nil, nil, err - } - - repoUser := model.UserFromModel(user) - repoInitCode := model.InitCodeFromModel(user.InitCode) - repoPhoneCode := model.PhoneCodeFromModel(user.PhoneCode) - - createAggregates, err := HumanCreateAggregate(ctx, es.AggregateCreator(), repoUser, repoInitCode, repoPhoneCode, resourceOwner, orgIAMPolicy.UserLoginMustBeDomain) - - return repoUser, createAggregates, err -} - -func (es *UserEventstore) PrepareCreateUser(ctx context.Context, user *usr_model.User, pwPolicy *iam_model.PasswordComplexityPolicyView, orgIAMPolicy *iam_model.OrgIAMPolicyView, resourceOwner string) (*model.User, []*es_models.Aggregate, error) { - id, err := es.idGenerator.Next() - if err != nil { - return nil, nil, err - } - user.AggregateID = id - - if user.Human != nil { - return es.prepareCreateHuman(ctx, user, pwPolicy, orgIAMPolicy, resourceOwner) - } else if user.Machine != nil { - return es.prepareCreateMachine(ctx, user, orgIAMPolicy, resourceOwner) - } - return nil, nil, errors.ThrowInvalidArgument(nil, "EVENT-Q29tp", "Errors.User.TypeUndefined") -} - -func (es *UserEventstore) CreateUser(ctx context.Context, user *usr_model.User, pwPolicy *iam_model.PasswordComplexityPolicyView, orgIAMPolicy *iam_model.OrgIAMPolicyView) (*usr_model.User, error) { - repoUser, aggregates, err := es.PrepareCreateUser(ctx, user, pwPolicy, orgIAMPolicy, "") - if err != nil { - return nil, err - } - - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, aggregates...) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - return model.UserToModel(repoUser), nil -} - -func (es *UserEventstore) PrepareRegisterUser(ctx context.Context, user *usr_model.User, externalIDP *usr_model.ExternalIDP, policy *iam_model.PasswordComplexityPolicyView, orgIAMPolicy *iam_model.OrgIAMPolicyView, resourceOwner string) (*model.User, []*es_models.Aggregate, error) { - if user.Human == nil { - return nil, nil, caos_errs.ThrowInvalidArgument(nil, "EVENT-ht8Ux", "Errors.User.Invalid") - } - - err := user.CheckOrgIAMPolicy(orgIAMPolicy) - if err != nil { - return nil, nil, err - } - user.SetNamesAsDisplayname() - if !user.IsValid() || externalIDP == nil && (user.Password == nil || user.SecretString == "") { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Errors.User.Invalid") - } - id, err := es.idGenerator.Next() - if err != nil { - return nil, nil, err - } - user.AggregateID = id - if externalIDP != nil { - externalIDP.AggregateID = id - if !externalIDP.IsValid() { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-4Dj9s", "Errors.User.ExternalIDP.Invalid") - } - user.ExternalIDPs = append(user.ExternalIDPs, externalIDP) - } - err = user.HashPasswordIfExisting(policy, es.PasswordAlg, false) - if err != nil { - return nil, nil, err - } - err = user.GenerateInitCodeIfNeeded(es.InitializeUserCode) - if err != nil { - return nil, nil, err - } - - repoUser := model.UserFromModel(user) - repoExternalIDP := model.ExternalIDPFromModel(externalIDP) - repoInitCode := model.InitCodeFromModel(user.InitCode) - - aggregates, err := UserRegisterAggregate(ctx, es.AggregateCreator(), repoUser, repoExternalIDP, resourceOwner, repoInitCode, orgIAMPolicy.UserLoginMustBeDomain) - return repoUser, aggregates, err -} - -func (es *UserEventstore) RegisterUser(ctx context.Context, user *usr_model.User, pwPolicy *iam_model.PasswordComplexityPolicyView, orgIAMPolicy *iam_model.OrgIAMPolicyView, resourceOwner string) (*usr_model.User, error) { - repoUser, createAggregates, err := es.PrepareRegisterUser(ctx, user, nil, pwPolicy, orgIAMPolicy, resourceOwner) - if err != nil { - return nil, err - } - - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, createAggregates...) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - return model.UserToModel(repoUser), nil -} - -func (es *UserEventstore) DeactivateUser(ctx context.Context, id string) (*usr_model.User, error) { - user, err := es.UserByID(ctx, id) - if err != nil { - return nil, err - } - if user.IsInactive() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die45", "Errors.User.AlreadyInactive") - } - - repoUser := model.UserFromModel(user) - aggregate := UserDeactivateAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, aggregate) - if err != nil { - return nil, err - } - es.userCache.cacheUser(repoUser) - return model.UserToModel(repoUser), nil -} - -func (es *UserEventstore) ReactivateUser(ctx context.Context, id string) (*usr_model.User, error) { - user, err := es.UserByID(ctx, id) - if err != nil { - return nil, err - } - if !user.IsInactive() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-do94s", "Errors.User.NotInactive") - } - - repoUser := model.UserFromModel(user) - aggregate := UserReactivateAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, aggregate) - if err != nil { - return nil, err - } - es.userCache.cacheUser(repoUser) - return model.UserToModel(repoUser), nil -} - -func (es *UserEventstore) LockUser(ctx context.Context, id string) (*usr_model.User, error) { - user, err := es.UserByID(ctx, id) - if err != nil { - return nil, err - } - if !user.IsActive() && !user.IsInitial() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83s", "Errors.User.ShouldBeActiveOrInitial") - } - - repoUser := model.UserFromModel(user) - aggregate := UserLockAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, aggregate) - if err != nil { - return nil, err - } - es.userCache.cacheUser(repoUser) - return model.UserToModel(repoUser), nil -} - -func (es *UserEventstore) UnlockUser(ctx context.Context, id string) (*usr_model.User, error) { - user, err := es.UserByID(ctx, id) - if err != nil { - return nil, err - } - if !user.IsLocked() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dks83", "Errors.User.NotLocked") - } - - repoUser := model.UserFromModel(user) - aggregate := UserUnlockAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, aggregate) - if err != nil { - return nil, err - } - es.userCache.cacheUser(repoUser) - return model.UserToModel(repoUser), nil -} - -func (es *UserEventstore) PrepareRemoveUser(ctx context.Context, id string, orgIamPolicy *iam_model.OrgIAMPolicyView) (*model.User, []*es_models.Aggregate, error) { - user, err := es.UserByID(ctx, id) - if err != nil { - return nil, nil, err - } - - repoUser := model.UserFromModel(user) - aggregate, err := UserRemoveAggregate(ctx, es.AggregateCreator(), repoUser, orgIamPolicy.UserLoginMustBeDomain) - if err != nil { - return nil, nil, err - } - return repoUser, aggregate, nil -} - -func (es *UserEventstore) RemoveUser(ctx context.Context, id string, orgIamPolicy *iam_model.OrgIAMPolicyView) error { - repoUser, aggregate, err := es.PrepareRemoveUser(ctx, id, orgIamPolicy) - if err != nil { - return err - } - return es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, aggregate...) -} - func (es *UserEventstore) UserChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*usr_model.UserChanges, error) { query := ChangesQuery(id, lastSequence, limit, sortAscending) @@ -419,997 +134,6 @@ func ChangesQuery(userID string, latestSequence, limit uint64, sortAscending boo return query } -func (es *UserEventstore) InitializeUserCodeByID(ctx context.Context, userID string) (*usr_model.InitUserCode, error) { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - if user.InitCode != nil { - return user.InitCode, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-d8e2", "Erorrs.User.InitCodeNotFound") -} - -func (es *UserEventstore) CreateInitializeUserCodeByID(ctx context.Context, userID string) (*usr_model.InitUserCode, error) { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - - initCode := new(usr_model.InitUserCode) - err = initCode.GenerateInitUserCode(es.InitializeUserCode) - if err != nil { - return nil, err - } - - repoUser := model.UserFromModel(user) - repoInitCode := model.InitCodeFromModel(initCode) - - agg := UserInitCodeAggregate(es.AggregateCreator(), repoUser, repoInitCode) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return nil, err - } - es.userCache.cacheUser(repoUser) - return model.InitCodeToModel(repoUser.InitCode), nil -} - -func (es *UserEventstore) InitCodeSent(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - agg := UserInitCodeSentAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) VerifyInitCode(ctx context.Context, policy *iam_model.PasswordComplexityPolicyView, userID, verificationCode, password string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if verificationCode == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-lo9fd", "Errors.User.Code.Empty") - } - pw := &usr_model.Password{SecretString: password} - err = pw.HashPasswordIfExisting(policy, es.PasswordAlg, false) - if err != nil { - return err - } - if user.InitCode == nil { - return caos_errs.ThrowNotFound(nil, "EVENT-spo9W", "Errors.User.Code.NotFound") - } - repoPassword := model.PasswordFromModel(pw) - repoUser := model.UserFromModel(user) - var updateAggregate func(ctx context.Context) (*es_models.Aggregate, error) - if err := crypto.VerifyCode(user.InitCode.CreationDate, user.InitCode.Expiry, user.InitCode.Code, verificationCode, es.InitializeUserCode); err != nil { - updateAggregate = InitCodeCheckFailedAggregate(es.AggregateCreator(), repoUser) - es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - return err - } else { - updateAggregate = InitCodeVerifiedAggregate(es.AggregateCreator(), repoUser, repoPassword) - } - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return err - } - - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) SkipMFAInit(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - agg := SkipMFAAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) UserPasswordByID(ctx context.Context, userID string) (*usr_model.Password, error) { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - - if user.Password != nil { - return user.Password, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-d8e2", "Errors.User.Password.NotFound") -} - -func (es *UserEventstore) CheckPassword(ctx context.Context, userID, password string, authRequest *req_model.AuthRequest) (err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if user.Password == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-s35Fa", "Errors.User.Password.Empty") - } - ctx, spanPasswordComparison := tracing.NewNamedSpan(ctx, "crypto.CompareHash") - err = crypto.CompareHash(user.Password.SecretCrypto, []byte(password), es.PasswordAlg) - spanPasswordComparison.EndWithError(err) - if err == nil { - return es.setPasswordCheckResult(ctx, user, authRequest, PasswordCheckSucceededAggregate) - } - if err := es.setPasswordCheckResult(ctx, user, authRequest, PasswordCheckFailedAggregate); err != nil { - return err - } - return caos_errs.ThrowInvalidArgument(nil, "EVENT-452ad", "Errors.User.Password.Invalid") -} - -func (es *UserEventstore) setPasswordCheckResult(ctx context.Context, user *usr_model.User, authRequest *req_model.AuthRequest, check func(*es_models.AggregateCreator, *model.User, *model.AuthRequest) es_sdk.AggregateFunc) (err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - repoUser := model.UserFromModel(user) - repoAuthRequest := model.AuthRequestFromModel(authRequest) - agg := check(es.AggregateCreator(), repoUser, repoAuthRequest) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) SetOneTimePassword(ctx context.Context, policy *iam_model.PasswordComplexityPolicyView, password *usr_model.Password) (*usr_model.Password, error) { - user, err := es.HumanByID(ctx, password.AggregateID) - if err != nil { - return nil, err - } - return es.changedPassword(ctx, user, policy, password.SecretString, true, "") -} - -func (es *UserEventstore) SetPassword(ctx context.Context, policy *iam_model.PasswordComplexityPolicyView, userID, code, password, userAgentID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if user.PasswordCode == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-65sdr", "Errors.User.Code.NotFound") - } - if err := crypto.VerifyCode(user.PasswordCode.CreationDate, user.PasswordCode.Expiry, user.PasswordCode.Code, code, es.PasswordVerificationCode); err != nil { - return err - } - _, err = es.changedPassword(ctx, user, policy, password, false, userAgentID) - return err -} - -func (es *UserEventstore) ExternalLoginChecked(ctx context.Context, userID string, authRequest *req_model.AuthRequest) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - repoUser := model.UserFromModel(user) - repoAuthRequest := model.AuthRequestFromModel(authRequest) - agg := ExternalLoginCheckSucceededAggregate(es.AggregateCreator(), repoUser, repoAuthRequest) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) TokenAdded(ctx context.Context, token *usr_model.Token) (*usr_model.Token, error) { - user, err := es.UserByID(ctx, token.AggregateID) - if err != nil { - return nil, err - } - id, err := es.idGenerator.Next() - if err != nil { - return nil, err - } - token.TokenID = id - repoUser := model.UserFromModel(user) - repoToken := model.TokenFromModel(token) - agg := TokenAddedAggregate(es.AggregateCreator(), repoUser, repoToken) - err = es_sdk.Push(ctx, es.PushAggregates, repoToken.AppendEvents, agg) - if err != nil { - return nil, err - } - es.userCache.cacheUser(repoUser) - return model.TokenToModel(repoToken), nil -} - -func (es *UserEventstore) ChangeMachine(ctx context.Context, machine *usr_model.Machine) (*usr_model.Machine, error) { - user, err := es.UserByID(ctx, machine.AggregateID) - if err != nil { - return nil, err - } - if user.Machine == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-OGUoz", "Errors.User.NotMachine") - } - - repoUser := model.UserFromModel(user) - repoMachine := model.MachineFromModel(machine) - - updateAggregate := MachineChangeAggregate(es.AggregateCreator(), repoUser, repoMachine) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - return model.MachineToModel(repoUser.Machine), nil -} - -func (es *UserEventstore) ChangePassword(ctx context.Context, policy *iam_model.PasswordComplexityPolicyView, userID, old, new, userAgentID string) (_ *usr_model.Password, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - if user.Password == nil { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Fds3s", "Errors.User.Password.Empty") - } - ctx, spanPasswordComparison := tracing.NewNamedSpan(ctx, "crypto.CompareHash") - err = crypto.CompareHash(user.Password.SecretCrypto, []byte(old), es.PasswordAlg) - spanPasswordComparison.EndWithError(err) - if err != nil { - return nil, caos_errs.ThrowInvalidArgument(nil, "EVENT-s56a3", "Errors.User.Password.Invalid") - } - return es.changedPassword(ctx, user, policy, new, false, userAgentID) -} - -func (es *UserEventstore) changedPassword(ctx context.Context, user *usr_model.User, policy *iam_model.PasswordComplexityPolicyView, password string, onetime bool, userAgentID string) (_ *usr_model.Password, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - pw := &usr_model.Password{SecretString: password} - err = pw.HashPasswordIfExisting(policy, es.PasswordAlg, onetime) - if err != nil { - return nil, err - } - repoPassword := model.PasswordChangeFromModel(pw, userAgentID) - repoUser := model.UserFromModel(user) - agg := PasswordChangeAggregate(es.AggregateCreator(), repoUser, repoPassword) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return nil, err - } - es.userCache.cacheUser(repoUser) - - return model.PasswordToModel(repoUser.Password), nil -} - -func (es *UserEventstore) RequestSetPassword(ctx context.Context, userID string, notifyType usr_model.NotificationType) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if user.State == usr_model.UserStateInitial { - return errors.ThrowPreconditionFailed(nil, "EVENT-Hs11s", "Errors.User.NotInitialised") - } - - passwordCode := new(model.PasswordCode) - err = es.generatePasswordCode(passwordCode, notifyType) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - agg := RequestSetPassword(es.AggregateCreator(), repoUser, passwordCode) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) ResendInitialMail(ctx context.Context, userID, email string) error { - if userID == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-G4bmn", "Errors.User.UserIDMissing") - } - user, err := es.UserByID(ctx, userID) - if err != nil { - return err - } - if user.Human == nil { - return errors.ThrowPreconditionFailed(nil, "EVENT-Hfsww", "Errors.User.NotHuman") - } - if user.State != usr_model.UserStateInitial { - return errors.ThrowPreconditionFailed(nil, "EVENT-BGbbe", "Errors.User.AlreadyInitialised") - } - err = user.GenerateInitCodeIfNeeded(es.InitializeUserCode) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - agg := ResendInitialPasswordAggregate(es.AggregateCreator(), repoUser, user.InitCode, email) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) PasswordCodeSent(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - agg := PasswordCodeSentAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) AddExternalIDP(ctx context.Context, externalIDP *usr_model.ExternalIDP) (*usr_model.ExternalIDP, error) { - if externalIDP == nil || !externalIDP.IsValid() { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Ek9s", "Errors.User.ExternalIDP.Invalid") - } - existingUser, err := es.HumanByID(ctx, externalIDP.AggregateID) - if err != nil { - return nil, err - } - repoUser := model.UserFromModel(existingUser) - repoExternalIDP := model.ExternalIDPFromModel(externalIDP) - aggregates, err := ExternalIDPAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoUser, repoExternalIDP) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, aggregates...) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - if _, idp := model.GetExternalIDP(repoUser.ExternalIDPs, externalIDP.UserID); idp != nil { - return model.ExternalIDPToModel(idp), nil - } - return nil, errors.ThrowInternal(nil, "EVENT-Msi9d", "Errors.Internal") -} - -func (es *UserEventstore) BulkAddExternalIDPs(ctx context.Context, userID string, externalIDPs []*usr_model.ExternalIDP) error { - if externalIDPs == nil || len(externalIDPs) == 0 { - return errors.ThrowPreconditionFailed(nil, "EVENT-Ek9s", "Errors.User.ExternalIDP.MinimumExternalIDPNeeded") - } - for _, externalIDP := range externalIDPs { - if !externalIDP.IsValid() { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-idue3", "Errors.User.ExternalIDP.Invalid") - } - } - existingUser, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - repoUser := model.UserFromModel(existingUser) - repoExternalIDPs := model.ExternalIDPsFromModel(externalIDPs) - aggregates, err := ExternalIDPAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoUser, repoExternalIDPs...) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, aggregates...) - if err != nil { - return err - } - - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) PrepareRemoveExternalIDP(ctx context.Context, externalIDP *usr_model.ExternalIDP, cascade bool) (*model.User, []*es_models.Aggregate, error) { - if externalIDP == nil || !externalIDP.IsValid() { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-Cm8sj", "Errors.User.ExternalIDP.Invalid") - } - existingUser, err := es.HumanByID(ctx, externalIDP.AggregateID) - if err != nil { - return nil, nil, err - } - _, existingIDP := existingUser.GetExternalIDP(externalIDP) - if existingIDP == nil { - return nil, nil, errors.ThrowPreconditionFailed(nil, "EVENT-3Dh7s", "Errors.User.ExternalIDP.NotOnUser") - } - repoUser := model.UserFromModel(existingUser) - repoExternalIDP := model.ExternalIDPFromModel(externalIDP) - agg, err := ExternalIDPRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoUser, repoExternalIDP, cascade) - if err != nil { - return nil, nil, err - } - return repoUser, agg, err -} - -func (es *UserEventstore) RemoveExternalIDP(ctx context.Context, externalIDP *usr_model.ExternalIDP) error { - repoUser, aggregates, err := es.PrepareRemoveExternalIDP(ctx, externalIDP, false) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, aggregates...) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) ProfileByID(ctx context.Context, userID string) (*usr_model.Profile, error) { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - - if user.Profile != nil { - return user.Profile, nil - } - 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.Profile.Invalid") - } - user, err := es.HumanByID(ctx, profile.AggregateID) - if err != nil { - return nil, err - } - - repoUser := model.UserFromModel(user) - repoProfile := model.ProfileFromModel(profile) - - updateAggregate := ProfileChangeAggregate(es.AggregateCreator(), repoUser, repoProfile) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - return model.ProfileToModel(repoUser.Profile), nil -} - -func (es *UserEventstore) EmailByID(ctx context.Context, userID string) (*usr_model.Email, error) { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - - if user.Email != nil { - return user.Email, nil - } - 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.Email.Invalid") - } - user, err := es.HumanByID(ctx, email.AggregateID) - if err != nil { - return nil, err - } - if user.State == usr_model.UserStateInitial { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-3H4q", "Errors.User.NotInitialised") - } - - emailCode, err := email.GenerateEmailCodeIfNeeded(es.EmailVerificationCode) - if err != nil { - return nil, err - } - - repoUser := model.UserFromModel(user) - repoEmail := model.EmailFromModel(email) - repoEmailCode := model.EmailCodeFromModel(emailCode) - - updateAggregate, err := EmailChangeAggregate(ctx, es.AggregateCreator(), repoUser, repoEmail, repoEmailCode) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - return model.EmailToModel(repoUser.Email), nil -} - -func (es *UserEventstore) VerifyEmail(ctx context.Context, userID, verificationCode string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if verificationCode == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-skDws", "Errors.User.Code.Empty") - } - if user.EmailCode == nil { - return caos_errs.ThrowNotFound(nil, "EVENT-lso9w", "Errors.User.Code.NotFound") - } - - err = crypto.VerifyCode(user.EmailCode.CreationDate, user.EmailCode.Expiry, user.EmailCode.Code, verificationCode, es.EmailVerificationCode) - if err == nil { - return es.setEmailVerifyResult(ctx, user, EmailVerifiedAggregate) - } - if err := es.setEmailVerifyResult(ctx, user, EmailVerificationFailedAggregate); err != nil { - return err - } - return caos_errs.ThrowInvalidArgument(err, "EVENT-dtGaa", "Errors.User.Code.Invalid") -} - -func (es *UserEventstore) setEmailVerifyResult(ctx context.Context, user *usr_model.User, check func(aggCreator *es_models.AggregateCreator, user *model.User) es_sdk.AggregateFunc) error { - repoUser := model.UserFromModel(user) - err := es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, check(es.AggregateCreator(), repoUser)) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) CreateEmailVerificationCode(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if user.State == usr_model.UserStateInitial { - return errors.ThrowPreconditionFailed(nil, "EVENT-E3fbw", "Errors.User.NotInitialised") - } - if user.Email == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.Email.NotFound") - } - if user.IsEmailVerified { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-pdo9s", "Errors.User.Email.AlreadyVerified") - } - - emailCode := new(usr_model.EmailCode) - err = emailCode.GenerateEmailCode(es.EmailVerificationCode) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - repoEmailCode := model.EmailCodeFromModel(emailCode) - updateAggregate := EmailVerificationCodeAggregate(es.AggregateCreator(), repoUser, repoEmailCode) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return err - } - - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) EmailVerificationCodeSent(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - agg := EmailCodeSentAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) PhoneByID(ctx context.Context, userID string) (*usr_model.Phone, error) { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - - if user.Phone != nil { - return user.Phone, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-pos9e", "Errors.User.Phone.NotFound") -} - -func (es *UserEventstore) ChangePhone(ctx context.Context, phone *usr_model.Phone) (*usr_model.Phone, error) { - if !phone.IsValid() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-do9s4", "Errors.User.Phone.Invalid") - } - user, err := es.HumanByID(ctx, phone.AggregateID) - if err != nil { - return nil, err - } - - phoneCode, err := phone.GeneratePhoneCodeIfNeeded(es.PhoneVerificationCode) - if err != nil { - return nil, err - } - - repoUser := model.UserFromModel(user) - repoPhone := model.PhoneFromModel(phone) - repoPhoneCode := model.PhoneCodeFromModel(phoneCode) - - updateAggregate := PhoneChangeAggregate(es.AggregateCreator(), repoUser, repoPhone, repoPhoneCode) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - return model.PhoneToModel(repoUser.Phone), nil -} - -func (es *UserEventstore) VerifyPhone(ctx context.Context, userID, verificationCode string) error { - if userID == "" || verificationCode == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-dsi8s", "Errors.User.UserIDMissing") - } - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if user.PhoneCode == nil { - return caos_errs.ThrowNotFound(nil, "EVENT-slp0s", "Errors.User.Code.NotFound") - } - - err = crypto.VerifyCode(user.PhoneCode.CreationDate, user.PhoneCode.Expiry, user.PhoneCode.Code, verificationCode, es.PhoneVerificationCode) - if err == nil { - return es.setPhoneVerifyResult(ctx, user, PhoneVerifiedAggregate) - } - if err := es.setPhoneVerifyResult(ctx, user, PhoneVerificationFailedAggregate); err != nil { - return err - } - return caos_errs.ThrowInvalidArgument(err, "EVENT-dsf4G", "Errors.User.Code.Invalid") -} - -func (es *UserEventstore) setPhoneVerifyResult(ctx context.Context, user *usr_model.User, check func(aggCreator *es_models.AggregateCreator, user *model.User) es_sdk.AggregateFunc) error { - repoUser := model.UserFromModel(user) - err := es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, check(es.AggregateCreator(), repoUser)) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) CreatePhoneVerificationCode(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if user.Phone == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-sp9fs", "Errors.User.Phone.NotFound") - } - if user.IsPhoneVerified { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-sleis", "Errors.User.Phone.AlreadyVerified") - } - - phoneCode := new(usr_model.PhoneCode) - err = phoneCode.GeneratePhoneCode(es.PhoneVerificationCode) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - repoPhoneCode := model.PhoneCodeFromModel(phoneCode) - updateAggregate := PhoneVerificationCodeAggregate(es.AggregateCreator(), repoUser, repoPhoneCode) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return err - } - - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) PhoneVerificationCodeSent(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - agg := PhoneCodeSentAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) RemovePhone(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - repoUser := model.UserFromModel(user) - removeAggregate := PhoneRemovedAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, removeAggregate) - if err != nil { - return err - } - - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) AddressByID(ctx context.Context, userID string) (*usr_model.Address, error) { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - - if user.Address != nil { - return user.Address, nil - } - 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) { - user, err := es.HumanByID(ctx, address.AggregateID) - if err != nil { - return nil, err - } - repoUser := model.UserFromModel(user) - repoAddress := model.AddressFromModel(address) - - updateAggregate := AddressChangeAggregate(es.AggregateCreator(), repoUser, repoAddress) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - return model.AddressToModel(repoUser.Address), nil -} - -func (es *UserEventstore) AddOTP(ctx context.Context, userID, accountName string) (*usr_model.OTP, error) { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return nil, err - } - if user.IsOTPReady() { - return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-do9se", "Errors.User.MFA.OTP.AlreadyReady") - } - if accountName == "" { - accountName = user.UserName - if user.Email != nil { - accountName = user.EmailAddress - } - } - key, err := totp.Generate(totp.GenerateOpts{Issuer: es.Multifactors.OTP.Issuer, AccountName: accountName}) - if err != nil { - return nil, err - } - encryptedSecret, err := crypto.Encrypt([]byte(key.Secret()), es.Multifactors.OTP.CryptoMFA) - if err != nil { - return nil, err - } - repoOTP := &model.OTP{Secret: encryptedSecret} - repoUser := model.UserFromModel(user) - updateAggregate := MFAOTPAddAggregate(es.AggregateCreator(), repoUser, repoOTP) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return nil, err - } - - es.userCache.cacheUser(repoUser) - otp := model.OTPToModel(repoUser.OTP) - otp.Url = key.URL() - otp.SecretString = key.Secret() - return otp, nil -} - -func (es *UserEventstore) RemoveOTP(ctx context.Context, userID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if user.OTP == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-sp0de", "Errors.User.MFA.OTP.NotExisting") - } - repoUser := model.UserFromModel(user) - updateAggregate := MFAOTPRemoveAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, updateAggregate) - if err != nil { - return err - } - - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) CheckMFAOTPSetup(ctx context.Context, userID, code, userAgentID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if user.OTP == nil { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-yERHV", "Errors.Users.MFA.OTP.NotExisting") - } - if user.IsOTPReady() { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-qx4ls", "Errors.Users.MFA.OTP.AlreadyReady") - } - if err := es.verifyMFAOTP(user.OTP, code); err != nil { - return err - } - repoUser := model.UserFromModel(user) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAOTPVerifyAggregate(es.AggregateCreator(), repoUser, userAgentID)) - if err != nil { - return err - } - - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) CheckMFAOTP(ctx context.Context, userID, code string, authRequest *req_model.AuthRequest) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if !user.IsOTPReady() { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-sd5NJ", "Errors.User.MFA.OTP.NotReady") - } - - repoUser := model.UserFromModel(user) - repoAuthReq := model.AuthRequestFromModel(authRequest) - var aggregate func(*es_models.AggregateCreator, *model.User, *model.AuthRequest) es_sdk.AggregateFunc - var checkErr error - if checkErr = es.verifyMFAOTP(user.OTP, code); checkErr != nil { - aggregate = MFAOTPCheckFailedAggregate - } else { - aggregate = MFAOTPCheckSucceededAggregate - } - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, aggregate(es.AggregateCreator(), repoUser, repoAuthReq)) - if checkErr != nil { - return checkErr - } - if err != nil { - return err - } - - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) verifyMFAOTP(otp *usr_model.OTP, code string) error { - decrypt, err := crypto.DecryptString(otp.Secret, es.Multifactors.OTP.CryptoMFA) - if err != nil { - return err - } - - valid := es.validateTOTP(code, decrypt) - if !valid { - return caos_errs.ThrowInvalidArgument(nil, "EVENT-8isk2", "Errors.User.MFA.OTP.InvalidCode") - } - return nil -} - -func (es *UserEventstore) AddU2F(ctx context.Context, userID string, accountName string, isLoginUI bool) (*usr_model.WebAuthNToken, error) { - //user, err := es.HumanByID(ctx, userID) - //if err != nil { - // return nil, err - //} - //webAuthN, err := es.webauthn.BeginRegistration(user, accountName, usr_model.AuthenticatorAttachmentUnspecified, usr_model.UserVerificationRequirementDiscouraged, isLoginUI, user.U2FTokens...) - //if err != nil { - // return nil, err - //} - //tokenID, err := es.idGenerator.Next() - //if err != nil { - // return nil, err - //} - //webAuthN.WebAuthNTokenID = tokenID - //webAuthN.State = usr_model.MFAStateNotReady - //repoUser := model.UserFromModel(user) - //repoWebAuthN := model.WebAuthNFromModel(webAuthN) - // - //err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAU2FAddAggregate(es.AggregateCreator(), repoUser, repoWebAuthN)) - //if err != nil { - // return nil, err - //} - //return webAuthN, nil - return nil, nil -} - -func (es *UserEventstore) VerifyU2FSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error { - //user, err := es.HumanByID(ctx, userID) - //if err != nil { - // return err - //} - //_, token := user.Human.GetU2FToVerify() - //webAuthN, err := es.webauthn.FinishRegistration(user, token, tokenName, credentialData, userAgentID != "") - //if err != nil { - // return err - //} - //repoUser := model.UserFromModel(user) - //repoWebAuthN := model.WebAuthNVerifyFromModel(webAuthN, userAgentID) - //err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAU2FVerifyAggregate(es.AggregateCreator(), repoUser, repoWebAuthN)) - //if err != nil { - // return err - //} - //es.userCache.cacheUser(repoUser) - //return nil - return nil -} - -func (es *UserEventstore) RemoveU2FToken(ctx context.Context, userID, webAuthNTokenID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if _, token := user.Human.GetU2F(webAuthNTokenID); token == nil { - return errors.ThrowPreconditionFailed(nil, "EVENT-2M9ds", "Errors.User.MFA.U2F.NotExisting") - } - repoUser := model.UserFromModel(user) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAU2FRemoveAggregate(es.AggregateCreator(), repoUser, &model.WebAuthNTokenID{webAuthNTokenID})) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) BeginU2FLogin(ctx context.Context, userID string, authRequest *req_model.AuthRequest, isLoginUI bool) (*usr_model.WebAuthNLogin, error) { - //user, err := es.HumanByID(ctx, userID) - //if err != nil { - // return nil, err - //} - //if user.U2FTokens == nil { - // return nil, errors.ThrowPreconditionFailed(nil, "EVENT-5Mk8s", "Errors.User.MFA.U2F.NotExisting") - //} - // - //webAuthNLogin, err := es.webauthn.BeginLogin(user, usr_model.UserVerificationRequirementDiscouraged, isLoginUI, user.U2FTokens...) - //if err != nil { - // return nil, err - //} - //webAuthNLogin.AuthRequest = authRequest - //repoUser := model.UserFromModel(user) - //repoWebAuthNLogin := model.WebAuthNLoginFromModel(webAuthNLogin) - //err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAU2FBeginLoginAggregate(es.AggregateCreator(), repoUser, repoWebAuthNLogin)) - //if err != nil { - // return nil, err - //} - //return webAuthNLogin, nil - return nil, nil -} - -func (es *UserEventstore) VerifyMFAU2F(ctx context.Context, userID string, credentialData []byte, authRequest *req_model.AuthRequest, isLoginUI bool) error { - //user, err := es.HumanByID(ctx, userID) - //if err != nil { - // return err - //} - //_, u2f := user.GetU2FLogin(authRequest.ID) - //keyID, signCount, finishErr := es.webauthn.FinishLogin(user, u2f, credentialData, isLoginUI, user.U2FTokens...) - //if finishErr != nil && keyID == nil { - // return finishErr - //} - // - //_, token := user.GetU2FByKeyID(keyID) - //repoUser := model.UserFromModel(user) - //repoAuthRequest := model.AuthRequestFromModel(authRequest) - // - //signAgg := MFAU2FSignCountAggregate(es.AggregateCreator(), repoUser, &model.WebAuthNSignCount{WebauthNTokenID: token.WebAuthNTokenID, SignCount: signCount}, repoAuthRequest, finishErr == nil) - //err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, signAgg) - //if err != nil { - // return err - //} - //return finishErr - return nil -} - func (es *UserEventstore) GetPasswordless(ctx context.Context, userID string) ([]*usr_model.WebAuthNToken, error) { user, err := es.HumanByID(ctx, userID) if err != nil { @@ -1417,278 +141,3 @@ func (es *UserEventstore) GetPasswordless(ctx context.Context, userID string) ([ } return user.PasswordlessTokens, nil } - -func (es *UserEventstore) AddPasswordless(ctx context.Context, userID, accountName string, isLoginUI bool) (*usr_model.WebAuthNToken, error) { - //user, err := es.HumanByID(ctx, userID) - //if err != nil { - // return nil, err - //} - //webAuthN, err := es.webauthn.BeginRegistration(user, accountName, usr_model.AuthenticatorAttachmentUnspecified, usr_model.UserVerificationRequirementRequired, isLoginUI, user.PasswordlessTokens...) - //if err != nil { - // return nil, err - //} - //tokenID, err := es.idGenerator.Next() - //if err != nil { - // return nil, err - //} - //webAuthN.WebAuthNTokenID = tokenID - //repoUser := model.UserFromModel(user) - //repoWebAuthN := model.WebAuthNFromModel(webAuthN) - //err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAPasswordlessAddAggregate(es.AggregateCreator(), repoUser, repoWebAuthN)) - //if err != nil { - // return nil, err - //} - //return webAuthN, nil - return nil, nil -} - -func (es *UserEventstore) VerifyPasswordlessSetup(ctx context.Context, userID, tokenName, userAgentID string, credentialData []byte) error { - //user, err := es.HumanByID(ctx, userID) - //if err != nil { - // return err - //} - //_, token := user.Human.GetPasswordlessToVerify() - //webAuthN, err := es.webauthn.FinishRegistration(user, token, tokenName, credentialData, userAgentID != "") - //if err != nil { - // return err - //} - //repoUser := model.UserFromModel(user) - //repoWebAuthN := model.WebAuthNVerifyFromModel(webAuthN, userAgentID) - //err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAPasswordlessVerifyAggregate(es.AggregateCreator(), repoUser, repoWebAuthN)) - //if err != nil { - // return err - //} - //es.userCache.cacheUser(repoUser) - //return nil - return nil -} - -func (es *UserEventstore) RemovePasswordlessToken(ctx context.Context, userID, webAuthNTokenID string) error { - user, err := es.HumanByID(ctx, userID) - if err != nil { - return err - } - if _, token := user.Human.GetPasswordless(webAuthNTokenID); token == nil { - return errors.ThrowPreconditionFailed(nil, "EVENT-5M0sw", "Errors.User.NotHuman") - } - repoUser := model.UserFromModel(user) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAPasswordlessRemoveAggregate(es.AggregateCreator(), repoUser, &model.WebAuthNTokenID{webAuthNTokenID})) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) BeginPasswordlessLogin(ctx context.Context, userID string, authRequest *req_model.AuthRequest, isLoginUI bool) (*usr_model.WebAuthNLogin, error) { - //user, err := es.HumanByID(ctx, userID) - //if err != nil { - // return nil, err - //} - //if user.PasswordlessTokens == nil { - // return nil, errors.ThrowPreconditionFailed(nil, "EVENT-5M9sd", "Errors.User.MFA.Passwordless.NotExisting") - //} - //webAuthNLogin, err := es.webauthn.BeginLogin(user, usr_model.UserVerificationRequirementRequired, isLoginUI, user.PasswordlessTokens...) - //if err != nil { - // return nil, err - //} - //webAuthNLogin.AuthRequest = authRequest - //repoUser := model.UserFromModel(user) - //repoWebAuthNLogin := model.WebAuthNLoginFromModel(webAuthNLogin) - //err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, MFAPasswordlessBeginLoginAggregate(es.AggregateCreator(), repoUser, repoWebAuthNLogin)) - //if err != nil { - // return nil, err - //} - //return webAuthNLogin, nil - return nil, nil -} - -func (es *UserEventstore) VerifyPasswordless(ctx context.Context, userID string, credentialData []byte, authRequest *req_model.AuthRequest, isLoginUI bool) error { - //user, err := es.HumanByID(ctx, userID) - //if err != nil { - // return err - //} - //_, passwordless := user.GetPasswordlessLogin(authRequest.ID) - //keyID, signCount, finishErr := es.webauthn.FinishLogin(user, passwordless, credentialData, isLoginUI, user.PasswordlessTokens...) - //if finishErr != nil && keyID == nil { - // return finishErr - //} - //_, token := user.GetPasswordlessByKeyID(keyID) - //repoUser := model.UserFromModel(user) - //repoAuthRequest := model.AuthRequestFromModel(authRequest) - // - //signAgg := MFAPasswordlessSignCountAggregate(es.AggregateCreator(), repoUser, &model.WebAuthNSignCount{WebauthNTokenID: token.WebAuthNTokenID, SignCount: signCount}, repoAuthRequest, finishErr == nil) - //err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, signAgg) - //if err != nil { - // return err - //} - //return finishErr - return nil -} - -func (es *UserEventstore) SignOut(ctx context.Context, agentID string, userIDs []string) error { - users := make([]*model.User, len(userIDs)) - for i, id := range userIDs { - user, err := es.UserByID(ctx, id) - if err != nil { - return err - } - users[i] = model.UserFromModel(user) - } - - aggFunc := SignOutAggregates(es.AggregateCreator(), users, agentID) - aggregates, err := aggFunc(ctx) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, nil, aggregates...) - if err != nil { - return err - } - return nil -} - -func (es *UserEventstore) PrepareDomainClaimed(ctx context.Context, userIDs []string) ([]*es_models.Aggregate, error) { - aggregates := make([]*es_models.Aggregate, 0) - for _, userID := range userIDs { - user, err := es.UserByID(ctx, userID) - if err != nil { - return nil, err - } - repoUser := model.UserFromModel(user) - name, err := es.generateTemporaryLoginName() - if err != nil { - return nil, err - } - userAgg, err := DomainClaimedAggregate(ctx, es.AggregateCreator(), repoUser, name) - if err != nil { - return nil, err - } - aggregates = append(aggregates, userAgg...) - } - return aggregates, nil -} - -func (es *UserEventstore) DomainClaimedSent(ctx context.Context, userID string) error { - if userID == "" { - return caos_errs.ThrowPreconditionFailed(nil, "EVENT-0posw", "Errors.User.UserIDMissing") - } - user, err := es.UserByID(ctx, userID) - if err != nil { - return err - } - - repoUser := model.UserFromModel(user) - agg := DomainClaimedSentAggregate(es.AggregateCreator(), repoUser) - err = es_sdk.Push(ctx, es.PushAggregates, repoUser.AppendEvents, agg) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) ChangeUsername(ctx context.Context, userID, username string, orgIamPolicy *iam_model.OrgIAMPolicyView) error { - user, err := es.UserByID(ctx, userID) - if err != nil { - return err - } - oldUsername := user.UserName - user.UserName = username - if err := user.CheckOrgIAMPolicy(orgIamPolicy); err != nil { - return err - } - repoUser := model.UserFromModel(user) - aggregates, err := UsernameChangedAggregates(ctx, es.AggregateCreator(), repoUser, oldUsername, orgIamPolicy.UserLoginMustBeDomain) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoUser.AppendEvents, aggregates...) - if err != nil { - return err - } - es.userCache.cacheUser(repoUser) - return nil -} - -func (es *UserEventstore) generateTemporaryLoginName() (string, error) { - id, err := es.idGenerator.Next() - if err != nil { - return "", err - } - return fmt.Sprintf("%s@temporary.%s", id, es.domain), nil -} - -func (es *UserEventstore) AddMachineKey(ctx context.Context, key *usr_model.MachineKey) (*usr_model.MachineKey, error) { - user, err := es.UserByID(ctx, key.AggregateID) - if err != nil { - return nil, err - } - if user.Machine == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-5ROh4", "Errors.User.NotMachine") - } - - key.KeyID, err = es.idGenerator.Next() - if err != nil { - return nil, err - } - - if key.ExpirationDate.IsZero() { - key.ExpirationDate, err = key_model.DefaultExpiration() - if err != nil { - logging.Log("EVENT-vzibi").WithError(err).Warn("unable to set default date") - return nil, errors.ThrowInternal(err, "EVENT-j68fg", "Errors.Internal") - } - } - if key.ExpirationDate.Before(time.Now()) { - return nil, errors.ThrowInvalidArgument(nil, "EVENT-C6YV5", "Errors.MachineKey.ExpireBeforeNow") - } - - repoUser := model.UserFromModel(user) - repoKey := model.MachineKeyFromModel(key) - err = repoKey.GenerateMachineKeyPair(es.MachineKeySize, es.MachineKeyAlg) - if err != nil { - return nil, err - } - - userAggregate, err := UserAggregate(ctx, es.AggregateCreator(), repoUser) - if err != nil { - return nil, err - } - keyAggregate, err := userAggregate.AppendEvent(model.MachineKeyAdded, repoKey) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoKey.AppendEvents, keyAggregate) - if err != nil { - return nil, err - } - - return model.MachineKeyToModel(repoKey), nil -} - -func (es *UserEventstore) RemoveMachineKey(ctx context.Context, userID, keyID string) error { - user, err := es.UserByID(ctx, userID) - if err != nil { - return err - } - if user.Machine == nil { - return errors.ThrowPreconditionFailed(nil, "EVENT-h5Qtd", "Errors.User.NotMachine") - } - - repoUser := model.UserFromModel(user) - userAggregate, err := UserAggregate(ctx, es.AggregateCreator(), repoUser) - if err != nil { - return err - } - - keyIDPayload := struct { - KeyID string `json:"keyId"` - }{KeyID: keyID} - - keyAggregate, err := userAggregate.AppendEvent(model.MachineKeyRemoved, &keyIDPayload) - if err != nil { - return err - } - return es.PushAggregates(ctx, keyAggregate) -} diff --git a/internal/user/repository/eventsourcing/eventstore_mock_test.go b/internal/user/repository/eventsourcing/eventstore_mock_test.go deleted file mode 100644 index 2ea1f973f0..0000000000 --- a/internal/user/repository/eventsourcing/eventstore_mock_test.go +++ /dev/null @@ -1,545 +0,0 @@ -package eventsourcing - -import ( - "encoding/json" - "time" - - "github.com/golang/mock/gomock" - - mock_cache "github.com/caos/zitadel/internal/cache/mock" - "github.com/caos/zitadel/internal/crypto" - "github.com/caos/zitadel/internal/eventstore/mock" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/id" - global_model "github.com/caos/zitadel/internal/model" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -func GetMockedEventstore(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *UserEventstore { - return &UserEventstore{ - Eventstore: mockEs, - userCache: GetMockCache(ctrl), - idGenerator: GetSonyFlacke(), - } -} - -func GetMockedEventstoreWithPw(ctrl *gomock.Controller, mockEs *mock.MockEventstore, init, email, phone, password bool) *UserEventstore { - es := &UserEventstore{ - Eventstore: mockEs, - userCache: GetMockCache(ctrl), - idGenerator: GetSonyFlacke(), - } - if init { - es.InitializeUserCode = GetMockPwGenerator(ctrl) - } - if email { - es.EmailVerificationCode = GetMockPwGenerator(ctrl) - } - if phone { - es.PhoneVerificationCode = GetMockPwGenerator(ctrl) - } - if password { - es.PasswordVerificationCode = GetMockPwGenerator(ctrl) - es.PasswordAlg = crypto.CreateMockHashAlg(ctrl) - } - return es -} - -func GetMockCache(ctrl *gomock.Controller) *UserCache { - mockCache := mock_cache.NewMockCache(ctrl) - mockCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - mockCache.EXPECT().Set(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - return &UserCache{userCache: mockCache} -} - -func GetSonyFlacke() id.Generator { - return id.SonyFlakeGenerator -} - -func GetMockPwGenerator(ctrl *gomock.Controller) crypto.Generator { - alg := crypto.CreateMockEncryptionAlg(ctrl) - generator := crypto.NewMockGenerator(ctrl) - generator.EXPECT().Length().Return(uint(10)) - generator.EXPECT().Runes().Return([]rune("abcdefghijklmnopqrstuvwxyz")) - generator.EXPECT().Alg().AnyTimes().Return(alg) - generator.EXPECT().Expiry().Return(time.Hour * 1) - return generator -} - -func GetMockUserByIDOK(ctrl *gomock.Controller, user model.User) *UserEventstore { - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockUserByIDNoEvents(ctrl *gomock.Controller) *UserEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUser(ctrl *gomock.Controller) *UserEventstore { - user := model.User{ - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - }, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserWithPWGenerator(ctrl *gomock.Controller, init, email, phone, password bool) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - Phone: &model.Phone{ - PhoneNumber: "PhoneNumber", - }, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, init, email, phone, password) -} - -func GetMockManipulateUserWithInitCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore { - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, true, false, false, false) -} - -func GetMockManipulateUserWithPasswordInitCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore { - data, _ := json.Marshal(user) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, true, false, false, true) -} - -func GetMockManipulateUserWithPasswordAndEmailCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore { - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, false, true, false, true) -} - -func GetMockManipulateUserWithEmailCodeGen(ctrl *gomock.Controller, user model.User, verified bool) *UserEventstore { - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - if verified { - email, _ := json.Marshal(model.Email{EmailAddress: "address"}) - events = append(events, - &es_models.Event{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 2, Type: model.HumanEmailVerified}, - &es_models.Event{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 3, Type: model.HumanEmailChanged, Data: email}, - ) - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, false, true, false, false) -} - -func GetMockManipulateUserWithPhoneCodeGen(ctrl *gomock.Controller, user model.User) *UserEventstore { - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, false, false, true, false) -} - -func GetMockManipulateUserWithPasswordCodeGen(ctrl *gomock.Controller, user model.User, verified bool) *UserEventstore { - data, _ := json.Marshal(user) - code, _ := json.Marshal(user.PasswordCode) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 2, Type: model.UserPasswordCodeAdded, Data: code}, - } - if verified { - events = append(events, &es_models.Event{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 3, Type: model.HumanEmailVerified}) - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, false, false, false, true) -} - -func GetMockManipulateUserWithOTPGen(ctrl *gomock.Controller) *UserEventstore { - user := model.User{ - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - }, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - es := GetMockedEventstore(ctrl, mockEs) - hash := crypto.NewMockEncryptionAlgorithm(ctrl) - hash.EXPECT().Algorithm().Return("aes") - hash.EXPECT().Encrypt(gomock.Any()).Return(nil, nil) - hash.EXPECT().EncryptionKeyID().Return("id") - es.Multifactors = global_model.Multifactors{OTP: global_model.OTP{ - Issuer: "Issuer", - CryptoMFA: hash, - }} - return es -} - -func GetMockManipulateInactiveUser(ctrl *gomock.Controller) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 2, Type: model.UserDeactivated}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateLockedUser(ctrl *gomock.Controller) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: data}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserLocked}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserWithInitCode(ctrl *gomock.Controller, user model.User) *UserEventstore { - code := model.InitUserCode{Code: &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc", - KeyID: "id", - Crypted: []byte("code"), - }} - dataUser, _ := json.Marshal(user) - dataCode, _ := json.Marshal(code) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.InitializedUserCodeAdded, Data: dataCode}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, true, false, false, true) -} - -func GetMockManipulateUserWithEmailCode(ctrl *gomock.Controller) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - } - code := model.EmailCode{Code: &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc", - KeyID: "id", - Crypted: []byte("code"), - }} - dataUser, _ := json.Marshal(user) - dataCode, _ := json.Marshal(code) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserEmailCodeAdded, Data: dataCode}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, false, true, false, false) -} -func GetMockManipulateUserVerifiedEmail(ctrl *gomock.Controller) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - } - dataUser, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserEmailVerified}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserWithPhoneCode(ctrl *gomock.Controller) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - Phone: &model.Phone{ - PhoneNumber: "PhoneNumber", - }, - } - code := model.PhoneCode{Code: &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc", - KeyID: "id", - Crypted: []byte("code"), - }} - dataUser, _ := json.Marshal(user) - dataCode, _ := json.Marshal(code) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserPhoneCodeAdded, Data: dataCode}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, false, false, true, false) -} - -func GetMockManipulateUserVerifiedPhone(ctrl *gomock.Controller) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - Phone: &model.Phone{ - PhoneNumber: "PhoneNumber", - }, - } - dataUser, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserPhoneVerified}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserFull(ctrl *gomock.Controller, verified bool) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - FirstName: "FirstName", - LastName: "LastName", - }, - Password: &model.Password{ - Secret: &crypto.CryptoValue{Algorithm: "bcrypt", KeyID: "KeyID"}, - ChangeRequired: true, - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - Phone: &model.Phone{ - PhoneNumber: "PhoneNumber", - }, - Address: &model.Address{ - Country: "Country", - }, - } - dataUser, _ := json.Marshal(user) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser}, - } - if verified { - events = append(events, &es_models.Event{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 2, Type: model.HumanEmailVerified}) - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserWithOTP(ctrl *gomock.Controller, decrypt, verified bool) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - } - otp := model.OTP{ - Secret: &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc", - KeyID: "id", - Crypted: []byte("code"), - }, - } - dataUser, _ := json.Marshal(user) - dataOTP, _ := json.Marshal(otp) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.MFAOTPAdded, Data: dataOTP}, - } - if verified { - events = append(events, &es_models.Event{AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.MFAOTPVerified}) - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - es := GetMockedEventstore(ctrl, mockEs) - if !decrypt { - return es - } - enc := crypto.NewMockEncryptionAlgorithm(ctrl) - enc.EXPECT().Algorithm().Return("enc") - enc.EXPECT().Encrypt(gomock.Any()).Return(nil, nil) - enc.EXPECT().EncryptionKeyID().Return("id") - enc.EXPECT().DecryptionKeyIDs().Return([]string{"id"}) - enc.EXPECT().DecryptString(gomock.Any(), gomock.Any()).Return("code", nil) - es.Multifactors = global_model.Multifactors{OTP: global_model.OTP{ - Issuer: "Issuer", - CryptoMFA: enc, - }} - return es -} - -func GetMockManipulateUserWithExternalIDP(ctrl *gomock.Controller) *UserEventstore { - user := model.Human{ - Profile: &model.Profile{ - DisplayName: "DisplayName", - }, - } - externalIDP := model.ExternalIDP{ - IDPConfigID: "IDPConfigID", - UserID: "UserID", - DisplayName: "DisplayName", - } - dataUser, _ := json.Marshal(user) - dataIDP, _ := json.Marshal(externalIDP) - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.UserAdded, Data: dataUser, ResourceOwner: "ResourceOwner"}, - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, Type: model.HumanExternalIDPAdded, Data: dataIDP, ResourceOwner: "ResourceOwner"}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserNoEvents(ctrl *gomock.Controller) *UserEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserNoEventsWithPw(ctrl *gomock.Controller) *UserEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstoreWithPw(ctrl, mockEs, false, false, false, true) -} - -func GetMockedEventstoreComplexity(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *UserEventstore { - return &UserEventstore{ - Eventstore: mockEs, - } -} - -func GetMockChangesUserOK(ctrl *gomock.Controller) *UserEventstore { - user := model.Profile{ - FirstName: "Hans", - LastName: "Muster", - DisplayName: "DisplayName", - } - data, err := json.Marshal(user) - if err != nil { - - } - events := []*es_models.Event{ - {AggregateID: "AggregateID", AggregateVersion: "v1", Sequence: 1, AggregateType: model.UserAggregate, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstoreComplexity(ctrl, mockEs) -} - -func GetMockChangesUserNoEvents(ctrl *gomock.Controller) *UserEventstore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstoreComplexity(ctrl, mockEs) -} diff --git a/internal/user/repository/eventsourcing/eventstore_test.go b/internal/user/repository/eventsourcing/eventstore_test.go deleted file mode 100644 index 5d4caf081c..0000000000 --- a/internal/user/repository/eventsourcing/eventstore_test.go +++ /dev/null @@ -1,3860 +0,0 @@ -package eventsourcing - -import ( - "context" - "encoding/json" - "net" - "testing" - "time" - - "github.com/golang/mock/gomock" - - "github.com/caos/zitadel/internal/api/authz" - req_model "github.com/caos/zitadel/internal/auth_request/model" - "github.com/caos/zitadel/internal/crypto" - caos_errs "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/user/model" - repo_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -func TestUserByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - user *model.User - } - type res struct { - user *model.User - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user from events, ok", - args: args{ - es: GetMockUserByIDOK(ctrl, repo_model.User{Human: &repo_model.Human{Profile: &repo_model.Profile{DisplayName: "DisplayName"}}, UserName: "UserName"}), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - user: &model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - }, - }, - { - name: "no events found", - args: args{ - es: GetMockUserByIDNoEvents(ctrl), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "no id", - args: args{ - es: GetMockUserByIDNoEvents(ctrl), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.UserByID(nil, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID != tt.res.user.AggregateID { - t.Errorf("got wrong result aggregateID: expected: %v, actual: %v ", tt.res.user.AggregateID, result.AggregateID) - } - if tt.res.errFunc == nil && result.UserName != tt.res.user.UserName { - t.Errorf("got wrong result userName: expected: %v, actual: %v ", tt.res.user.UserName, result.UserName) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCreateUser(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - policy *iam_model.PasswordComplexityPolicyView - orgPolicy *iam_model.OrgIAMPolicyView - } - type res struct { - user *model.User - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "init mail because no pw", - args: args{ - es: GetMockManipulateUserWithInitCodeGen(ctrl, repo_model.User{ - UserName: "", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName", FirstName: "FirstName", LastName: "LastName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress", IsEmailVerified: true}, - }, - }), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - IsEmailVerified: true, - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - }, - res: res{ - user: &model.User{ - ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - IsEmailVerified: true, - }, - }, - }, - }, - }, - { - name: "email as username", - args: args{ - es: GetMockManipulateUserWithInitCodeGen(ctrl, repo_model.User{ - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName", FirstName: "FirstName", LastName: "LastName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress", IsEmailVerified: true}, - }, - }), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - IsEmailVerified: true, - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{UserLoginMustBeDomain: false}, - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "EmailAddress", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - IsEmailVerified: true, - }, - }, - }, - }, - }, - { - name: "with verified phone number", - args: args{ - es: GetMockManipulateUserWithInitCodeGen(ctrl, repo_model.User{ - UserName: "EmailAddress", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName", FirstName: "FirstName", LastName: "LastName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress", IsEmailVerified: true}, - Phone: &repo_model.Phone{PhoneNumber: "+41711234567", IsPhoneVerified: true}, - }, - }), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "UserName", - IsEmailVerified: true, - }, - Phone: &model.Phone{ - PhoneNumber: "+41711234567", - IsPhoneVerified: true, - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - IsEmailVerified: true, - }, - Phone: &model.Phone{ - PhoneNumber: "+41711234567", - IsPhoneVerified: true, - }, - }, - }, - }, - }, - { - name: "with password", - args: args{ - es: GetMockManipulateUserWithPasswordAndEmailCodeGen(ctrl, repo_model.User{ - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName", FirstName: "FirstName", LastName: "LastName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress", IsEmailVerified: true}}, - }), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Password: &model.Password{SecretString: "Password"}, - Email: &model.Email{ - EmailAddress: "UserName", - IsEmailVerified: true, - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - IsEmailVerified: true, - }, - }, - }, - }, - }, - { - name: "create user invalid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Human: &model.Human{}}, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "create user pw policy nil", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Human: &model.Human{}}, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "create user org policy nil", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Human: &model.Human{}}, - policy: &iam_model.PasswordComplexityPolicyView{}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.CreateUser(tt.args.ctx, tt.args.user, tt.args.policy, tt.args.orgPolicy) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.UserName != tt.res.user.UserName { - t.Errorf("got wrong result username: expected: %v, actual: %v ", tt.res.user.UserName, result.UserName) - } - if tt.res.errFunc == nil && tt.res.user.Email != nil { - if result.IsEmailVerified != tt.res.user.IsEmailVerified { - t.Errorf("got wrong result IsEmailVerified: expected: %v, actual: %v ", tt.res.user.IsEmailVerified, result.IsEmailVerified) - } - } - if tt.res.errFunc == nil && tt.res.user.Phone != nil { - if result.IsPhoneVerified != tt.res.user.IsPhoneVerified { - t.Errorf("got wrong result IsPhoneVerified: expected: %v, actual: %v ", tt.res.user.IsPhoneVerified, result.IsPhoneVerified) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRegisterUser(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - resourceOwner string - policy *iam_model.PasswordComplexityPolicyView - orgPolicy *iam_model.OrgIAMPolicyView - } - type res struct { - user *model.User - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "register user, ok", - args: args{ - es: GetMockManipulateUserWithPasswordInitCodeGen(ctrl, repo_model.User{ - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName", FirstName: "FirstName", LastName: "LastName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress"}}}, - ), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - Password: &model.Password{ - SecretString: "Password", - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{UserLoginMustBeDomain: true}, - resourceOwner: "ResourceOwner", - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - }, - }, - }, - }, - { - name: "email as username", - args: args{ - es: GetMockManipulateUserWithPasswordInitCodeGen(ctrl, repo_model.User{ - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName", FirstName: "FirstName", LastName: "LastName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress"}}}, - ), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - Password: &model.Password{ - SecretString: "Password", - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{UserLoginMustBeDomain: false}, - resourceOwner: "ResourceOwner", - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "EmailAddress", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - }, - }, - }, - }, - { - name: "invalid user", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, Human: &model.Human{}}, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - resourceOwner: "ResourceOwner", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "register user no password", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "EmailAddress", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - resourceOwner: "ResourceOwner", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no resourceowner", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "EmailAddress", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no pw policy", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "EmailAddress", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - }, - }, - orgPolicy: &iam_model.OrgIAMPolicyView{}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "no org policy", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{Sequence: 1}, - UserName: "EmailAddress", - Human: &model.Human{ - Profile: &model.Profile{ - FirstName: "FirstName", - LastName: "LastName", - DisplayName: "DisplayName", - }, - Email: &model.Email{ - EmailAddress: "EmailAddress", - }, - }, - }, - policy: &iam_model.PasswordComplexityPolicyView{}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.RegisterUser(tt.args.ctx, tt.args.user, tt.args.policy, tt.args.orgPolicy, tt.args.resourceOwner) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.UserName != tt.res.user.UserName { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.user.UserName, result.UserName) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestDeactivateUser(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - user *model.User - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate user, ok", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, State: model.UserStateInactive}, - }, - }, - { - name: "deactivate user with inactive state", - args: args{ - es: GetMockManipulateInactiveUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.DeactivateUser(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.State != tt.res.user.State { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.user.State, result.State) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestReactivateUser(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - user *model.User - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate user, ok", - args: args{ - es: GetMockManipulateInactiveUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, State: model.UserStateActive}, - }, - }, - { - name: "reactivate user with inital state", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ReactivateUser(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.State != tt.res.user.State { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.user.State, result.State) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestLockUser(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - user *model.User - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "lock user, ok", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, State: model.UserStateLocked}, - }, - }, - { - name: "lock user with locked state", - args: args{ - es: GetMockManipulateLockedUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.LockUser(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.State != tt.res.user.State { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.user.State, result.State) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUnlockUser(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - user *model.User - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "unlock user, ok", - args: args{ - es: GetMockManipulateLockedUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, State: model.UserStateActive}, - }, - }, - { - name: "unlock user not locked state", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.UnlockUser(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.State != tt.res.user.State { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.user.State, result.State) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestGetInitCodeByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - code *model.InitUserCode - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get by id, ok", - args: args{ - es: GetMockManipulateUserWithInitCode(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{ - DisplayName: "DisplayName", - }, - }, - }), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - code: &model.InitUserCode{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Expiry: time.Hour * 30}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.InitializeUserCodeByID(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result == nil { - t.Error("got wrong result code should not be nil", result) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCreateInitCode(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - code *model.InitUserCode - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "create init code", - args: args{ - es: GetMockManipulateUserWithPasswordInitCodeGen(ctrl, repo_model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Human: &model.Human{}}, - }, - res: res{ - code: &model.InitUserCode{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Expiry: time.Hour * 1}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}, Human: &model.Human{}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Human: &model.Human{}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.CreateInitializeUserCodeByID(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result == nil { - t.Errorf("got wrong result code is nil") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestInitCodeSent(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "sent init", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{}, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.InitCodeSent(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("rshould not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestInitCodeVerify(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicyView - userID string - verifyCode string - password string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "verify init code, no pw", - args: args{ - es: GetMockManipulateUserWithInitCode(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Email: &repo_model.Email{ - EmailAddress: "EmailAddress", - }, - }, - }, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - verifyCode: "code", - userID: "userID", - }, - }, - { - name: "verify init code, pw", - args: args{ - es: GetMockManipulateUserWithInitCode(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Email: &repo_model.Email{ - EmailAddress: "EmailAddress", - IsEmailVerified: true, - }, - }, - }, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - verifyCode: "code", - password: "password", - }, - }, - { - name: "verify init code, email and pw", - args: args{ - es: GetMockManipulateUserWithInitCode(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Email: &repo_model.Email{ - EmailAddress: "EmailAddress", - }, - }, - }, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - verifyCode: "code", - password: "password", - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "", - verifyCode: "code", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "password policy not matched", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{HasNumber: true}, - userID: "userID", - verifyCode: "code", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEventsWithPw(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - password: "password", - verifyCode: "code", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.VerifyInitCode(tt.args.ctx, tt.args.policy, tt.args.userID, tt.args.verifyCode, tt.args.password) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not have err: %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v", err) - } - }) - } -} - -func TestSkipMFAInit(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "skip mfa init", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{}, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.SkipMFAInit(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("rshould not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPasswordID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - password *model.Password - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get by id, ok", - args: args{ - es: GetMockManipulateUserFull(ctrl, false), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - password: &model.Password{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, ChangeRequired: true}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "existing pw not found", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.UserPasswordByID(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.ChangeRequired != tt.res.password.ChangeRequired { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.password.ChangeRequired, result.ChangeRequired) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestSetOneTimePassword(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicyView - password *model.Password - } - type res struct { - password *model.Password - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "create one time pw", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, repo_model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Human: &repo_model.Human{Email: &repo_model.Email{EmailAddress: "email"}}}, true), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - password: &model.Password{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, SecretString: "Password"}, - }, - res: res{ - password: &model.Password{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, ChangeRequired: true}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - password: &model.Password{ObjectRoot: es_models.ObjectRoot{AggregateID: ""}, SecretString: "Password"}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - password: &model.Password{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, SecretString: "Password"}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.SetOneTimePassword(tt.args.ctx, tt.args.policy, tt.args.password) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.ChangeRequired != true { - t.Errorf("should be one time") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCheckPassword(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - password string - authRequest *req_model.AuthRequest - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "check pw ok", - args: args{ - es: GetMockManipulateUserWithPasswordAndEmailCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Password: &repo_model.Password{Secret: &crypto.CryptoValue{ - CryptoType: crypto.TypeHash, - Algorithm: "hash", - Crypted: []byte("password"), - }}, - }, - }, - ), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - password: "password", - authRequest: &req_model.AuthRequest{ - ID: "id", - AgentID: "agentID", - BrowserInfo: &req_model.BrowserInfo{ - UserAgent: "user agent", - AcceptLanguage: "accept langugage", - RemoteIP: net.IPv4(29, 4, 20, 19), - }, - }, - }, - res: res{}, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "no password", - args: args{ - es: GetMockUserByIDOK(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - }, - ), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "invalid password", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Password: &repo_model.Password{Secret: &crypto.CryptoValue{ - CryptoType: crypto.TypeHash, - Algorithm: "hash", - Crypted: []byte("password"), - }}, - Email: &repo_model.Email{EmailAddress: "email"}, - }, - }, - true, - ), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - password: "wrong password", - authRequest: &req_model.AuthRequest{ - ID: "id", - AgentID: "agentID", - BrowserInfo: &req_model.BrowserInfo{ - UserAgent: "user agent", - AcceptLanguage: "accept langugage", - RemoteIP: net.IPv4(29, 4, 20, 19), - }, - }, - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.CheckPassword(tt.args.ctx, tt.args.userID, tt.args.password, tt.args.authRequest) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("result has error: %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v", err) - } - }) - } -} - -func TestSetPassword(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicyView - userID string - code string - password string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "create pw", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - PasswordCode: &repo_model.PasswordCode{Code: &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc", - KeyID: "id", - Crypted: []byte("code"), - }}, - Email: &repo_model.Email{EmailAddress: "email"}, - }, - }, - true, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - code: "code", - password: "password", - }, - res: res{}, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "", - code: "code", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - code: "code", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "no passcode", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Email: &repo_model.Email{EmailAddress: "email"}, - }, - }, - true, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - code: "code", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "invalid passcode", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - PasswordCode: &repo_model.PasswordCode{Code: &crypto.CryptoValue{ - CryptoType: crypto.TypeEncryption, - Algorithm: "enc2", - KeyID: "id", - Crypted: []byte("code2"), - }}, - Email: &repo_model.Email{EmailAddress: "email"}, - }, - }, - true, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - code: "code", - password: "password", - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.SetPassword(tt.args.ctx, tt.args.policy, tt.args.userID, tt.args.code, tt.args.password, "") - - if tt.res.errFunc == nil && err != nil { - t.Errorf("result has error: %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v", err) - } - }) - } -} - -func TestChangePassword(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - policy *iam_model.PasswordComplexityPolicyView - userID string - old string - new string - } - type res struct { - password string - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change pw", - args: args{ - es: GetMockManipulateUserWithPasswordAndEmailCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Password: &repo_model.Password{Secret: &crypto.CryptoValue{ - CryptoType: crypto.TypeHash, - Algorithm: "hash", - Crypted: []byte("old"), - }}, - }, - }, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - old: "old", - new: "new", - }, - res: res{ - password: "new", - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "", - old: "old", - new: "new", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - old: "old", - new: "new", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "no password", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Email: &repo_model.Email{EmailAddress: "email"}, - }, - }, - true, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - old: "old", - new: "new", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "invalid password", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Password: &repo_model.Password{Secret: &crypto.CryptoValue{ - CryptoType: crypto.TypeHash, - Algorithm: "hash", - Crypted: []byte("older"), - }}, - Email: &repo_model.Email{EmailAddress: "email"}, - }, - }, - true, - ), - ctx: authz.NewMockContext("orgID", "userID"), - policy: &iam_model.PasswordComplexityPolicyView{}, - userID: "userID", - old: "old", - new: "new", - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "no policy", - args: args{ - es: GetMockManipulateUserWithPasswordAndEmailCodeGen(ctrl, - repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Password: &repo_model.Password{Secret: &crypto.CryptoValue{ - CryptoType: crypto.TypeHash, - Algorithm: "hash", - Crypted: []byte("old"), - }}, - }, - }, - ), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - old: "old", - new: "new", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangePassword(tt.args.ctx, tt.args.policy, tt.args.userID, tt.args.old, tt.args.new, "") - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && string(result.SecretCrypto.Crypted) != tt.res.password { - t.Errorf("got wrong result crypted: expected: %v, actual: %v ", tt.res.password, result.SecretString) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v", err) - } - }) - } -} - -func TestRequestSetPassword(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - notifyType model.NotificationType - } - type res struct { - password *model.Password - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "create pw", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, - Human: &repo_model.Human{ - Email: &repo_model.Email{EmailAddress: "email"}, - }}, - true), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - notifyType: model.NotificationTypeEmail, - }, - res: res{ - password: &model.Password{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, ChangeRequired: false}, - }, - }, - { - name: "initial state", - args: args{ - es: GetMockManipulateUserWithPasswordCodeGen(ctrl, repo_model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Human: &repo_model.Human{}}, false), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - notifyType: model.NotificationTypeEmail, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - notifyType: model.NotificationTypeEmail, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - notifyType: model.NotificationTypeEmail, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RequestSetPassword(tt.args.ctx, tt.args.userID, tt.args.notifyType) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestResendInitialMail(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - mail string - } - type res struct { - password *model.Password - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "resend ok", - args: args{ - es: GetMockManipulateUserWithInitCode(ctrl, repo_model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Human: &repo_model.Human{}}), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - mail: "", - }, - res: res{ - password: &model.Password{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, ChangeRequired: false}, - }, - }, - { - name: "resend with email ok", - args: args{ - es: GetMockManipulateUserWithInitCode(ctrl, repo_model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, Human: &repo_model.Human{}}), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - mail: "email", - }, - res: res{ - password: &model.Password{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, ChangeRequired: false}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - mail: "", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - mail: "", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.ResendInitialMail(tt.args.ctx, tt.args.userID, tt.args.mail) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPasswordCodeSent(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "sent password code", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Human: &model.Human{}}, - }, - res: res{}, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.PasswordCodeSent(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("rshould not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddExternalIDP(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - externalIDP *model.ExternalIDP - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add ok", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - externalIDP: &model.ExternalIDP{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "AggregateID", - }, - IDPConfigID: "IDPConfigID", - UserID: "UserID", - DisplayName: "DisplayName", - }, - }, - }, - { - name: "invalid idp", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - externalIDP: &model.ExternalIDP{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "AggregateID", - }, - UserID: "UserID", - DisplayName: "DisplayName", - }, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - externalIDP: &model.ExternalIDP{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "AggregateID", - }, - IDPConfigID: "IDPConfigID", - UserID: "UserID", - DisplayName: "DisplayName", - }, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddExternalIDP(tt.args.ctx, tt.args.externalIDP) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.IDPConfigID == "" { - t.Errorf("result has no idpconfig") - } - if tt.res.errFunc == nil && result.UserID == "" { - t.Errorf("result has no UserID") - } - if tt.res.errFunc == nil && result == nil { - t.Errorf("got wrong result change required: actual: %v ", result) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveExternalIDP(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - externalIDP *model.ExternalIDP - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove ok", - args: args{ - es: GetMockManipulateUserWithExternalIDP(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - externalIDP: &model.ExternalIDP{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "AggregateID", - }, - IDPConfigID: "IDPConfigID", - UserID: "UserID", - }, - }, - }, - { - name: "invalid idp", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - externalIDP: &model.ExternalIDP{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "AggregateID", - }, - UserID: "UserID", - DisplayName: "DisplayName", - }, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "remove external idp not existing", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - externalIDP: &model.ExternalIDP{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "AggregateID", - }, - IDPConfigID: "IDPConfigID", - UserID: "UserID", - }, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - externalIDP: &model.ExternalIDP{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: "AggregateID", - }, - IDPConfigID: "IDPConfigID", - UserID: "UserID", - DisplayName: "DisplayName", - }, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveExternalIDP(tt.args.ctx, tt.args.externalIDP) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not get err, %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestProfileByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - profile *model.Profile - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get by id, ok", - args: args{ - es: GetMockManipulateUserFull(ctrl, false), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Human: &model.Human{}}, - }, - res: res{ - profile: &model.Profile{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, DisplayName: "DisplayName"}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - profile, err := tt.args.es.ProfileByID(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && profile.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && profile.DisplayName != tt.res.profile.DisplayName { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.profile.DisplayName, profile.DisplayName) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeProfile(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - profile *model.Profile - } - type res struct { - profile *model.Profile - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get by id, ok", - args: args{ - es: GetMockManipulateUserFull(ctrl, false), - ctx: authz.NewMockContext("orgID", "userID"), - profile: &model.Profile{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, FirstName: "FirstName Changed", LastName: "LastName Changed"}, - }, - res: res{ - profile: &model.Profile{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, FirstName: "FirstName Changed", LastName: "LastName Changed"}, - }, - }, - { - name: "invalid profile", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - profile: &model.Profile{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - profile: &model.Profile{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, FirstName: "FirstName Changed", LastName: "LastName Changed"}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeProfile(tt.args.ctx, tt.args.profile) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.FirstName != tt.res.profile.FirstName { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.profile.FirstName, result.FirstName) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestEmailByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - email *model.Email - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get by id, ok", - args: args{ - es: GetMockManipulateUserFull(ctrl, false), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - email: &model.Email{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, EmailAddress: "EmailAddress"}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.EmailByID(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.EmailAddress != tt.res.email.EmailAddress { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.email.EmailAddress, result.EmailAddress) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeEmail(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - email *model.Email - } - type res struct { - email *model.Email - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change email address, verified", - args: args{ - es: GetMockManipulateUserFull(ctrl, true), - ctx: authz.NewMockContext("orgID", "userID"), - email: &model.Email{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, EmailAddress: "EmailAddressChanged", IsEmailVerified: true}, - }, - res: res{ - email: &model.Email{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, EmailAddress: "EmailAddressChanged", IsEmailVerified: true}, - }, - }, - { - name: "change email not verified, getting code", - args: args{ - es: GetMockManipulateUserWithEmailCodeGen(ctrl, repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress"}, - }, - }, true), - ctx: authz.NewMockContext("orgID", "userID"), - email: &model.Email{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, EmailAddress: "EmailAddressChanged", IsEmailVerified: false}, - }, - res: res{ - email: &model.Email{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, EmailAddress: "EmailAddressChanged", IsEmailVerified: false}, - }, - }, - { - name: "user state initial", - args: args{ - es: GetMockManipulateUserWithEmailCodeGen(ctrl, repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress"}, - }, - }, false), - ctx: authz.NewMockContext("orgID", "userID"), - email: &model.Email{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, EmailAddress: "EmailAddressChanged", IsEmailVerified: false}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - email: &model.Email{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}, EmailAddress: "EmailAddressChanged", IsEmailVerified: true}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - email: &model.Email{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, EmailAddress: "EmailAddressChanged", IsEmailVerified: true}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeEmail(tt.args.ctx, tt.args.email) - if (tt.res.errFunc != nil && !tt.res.errFunc(err)) || (tt.res.errFunc == nil && err != nil) { - t.Errorf("got wrong err: %v ", err) - } - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.EmailAddress != tt.res.email.EmailAddress { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.email.EmailAddress, result.EmailAddress) - } - if tt.res.errFunc == nil && result.IsEmailVerified != tt.res.email.IsEmailVerified { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.email.IsEmailVerified, result.IsEmailVerified) - } - }) - } -} - -func TestVerifyEmail(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - code string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "verify email code ok", - args: args{ - es: GetMockManipulateUserWithEmailCode(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - code: "code", - }, - res: res{}, - }, - { - name: "verify email code wrong", - args: args{ - es: GetMockManipulateUserWithEmailCode(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - code: "wrong", - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - code: "code", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "empty code", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - code: "code", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.VerifyEmail(tt.args.ctx, tt.args.userID, tt.args.code) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not get err %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCreateEmailVerificationCode(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "create email verification code ok", - args: args{ - es: GetMockManipulateUserWithEmailCodeGen(ctrl, repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress"}, - }}, true), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{}, - }, - { - name: "initial state", - args: args{ - es: GetMockManipulateUserWithEmailCodeGen(ctrl, repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName"}, - Email: &repo_model.Email{EmailAddress: "EmailAddress"}, - }, - }, false), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "no email found", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "already verified", - args: args{ - es: GetMockManipulateUserVerifiedEmail(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.CreateEmailVerificationCode(tt.args.ctx, tt.args.userID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not get err, got: %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestEmailVerificationCodeSent(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "sent email verify code", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{}, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.EmailVerificationCodeSent(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("rshould not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPhoneByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - phone *model.Phone - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get by id, ok", - args: args{ - es: GetMockManipulateUserFull(ctrl, false), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - phone: &model.Phone{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, PhoneNumber: "PhoneNumber"}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.PhoneByID(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.PhoneNumber != tt.res.phone.PhoneNumber { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.phone.PhoneNumber, result.PhoneNumber) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangePhone(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - phone *model.Phone - } - type res struct { - phone *model.Phone - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change phone, verified", - args: args{ - es: GetMockManipulateUserFull(ctrl, false), - ctx: authz.NewMockContext("orgID", "userID"), - phone: &model.Phone{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, PhoneNumber: "0711234567", IsPhoneVerified: true}, - }, - res: res{ - phone: &model.Phone{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, PhoneNumber: "+41711234567", IsPhoneVerified: true}, - }, - }, - { - name: "change phone not verified, getting code", - args: args{ - es: GetMockManipulateUserWithPhoneCodeGen(ctrl, repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName"}, - Phone: &repo_model.Phone{PhoneNumber: "PhoneNumber"}}, - }), - ctx: authz.NewMockContext("orgID", "userID"), - phone: &model.Phone{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, PhoneNumber: "+41711234567", IsPhoneVerified: false}, - }, - res: res{ - phone: &model.Phone{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, PhoneNumber: "+41711234567", IsPhoneVerified: false}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - phone: &model.Phone{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}, PhoneNumber: "PhoneNumberChanged", IsPhoneVerified: true}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - phone: &model.Phone{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, PhoneNumber: "+41711234567", IsPhoneVerified: true}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangePhone(tt.args.ctx, tt.args.phone) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.PhoneNumber != tt.res.phone.PhoneNumber { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.phone.PhoneNumber, result.PhoneNumber) - } - if tt.res.errFunc == nil && result.IsPhoneVerified != tt.res.phone.IsPhoneVerified { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.phone.IsPhoneVerified, result.IsPhoneVerified) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestVerifyPhone(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - code string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "verify code ok", - args: args{ - es: GetMockManipulateUserWithPhoneCode(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - code: "code", - }, - res: res{}, - }, - { - name: "verify code wrong", - args: args{ - es: GetMockManipulateUserWithPhoneCode(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - code: "wrong", - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - code: "Code", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "empty code", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - code: "Code", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.VerifyPhone(tt.args.ctx, tt.args.userID, tt.args.code) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not get err %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemovePhone(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - code string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove phone ok", - args: args{ - es: GetMockManipulateUserVerifiedPhone(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - code: "code", - }, - res: res{}, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - code: "Code", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - code: "Code", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemovePhone(tt.args.ctx, tt.args.userID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not get err %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCreatePhoneVerificationCode(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "create phone verification code okk", - args: args{ - es: GetMockManipulateUserWithPhoneCodeGen(ctrl, repo_model.User{ - ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - UserName: "UserName", - Human: &repo_model.Human{ - Profile: &repo_model.Profile{DisplayName: "DisplayName"}, - Phone: &repo_model.Phone{PhoneNumber: "PhoneNumber"}, - }}), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{}, - }, - { - name: "no userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "no phone found", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "already verified", - args: args{ - es: GetMockManipulateUserVerifiedPhone(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.CreatePhoneVerificationCode(tt.args.ctx, tt.args.userID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("should not ger err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPhoneVerificationCodeSent(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "sent phone verification code", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{}, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.PhoneVerificationCodeSent(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("rshould not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddressByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - address *model.Address - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "get by id, ok", - args: args{ - es: GetMockManipulateUserFull(ctrl, false), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - address: &model.Address{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Country: "Country"}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddressByID(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.Country != tt.res.address.Country { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.address.Country, result.Country) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeAddress(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - address *model.Address - } - type res struct { - address *model.Address - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change address ok", - args: args{ - es: GetMockManipulateUserFull(ctrl, false), - ctx: authz.NewMockContext("orgID", "userID"), - address: &model.Address{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Country: "CountryChanged"}, - }, - res: res{ - address: &model.Address{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Country: "CountryChanged"}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - address: &model.Address{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}, Country: "CountryChanged"}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - address: &model.Address{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, Country: "CountryCountry"}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeAddress(tt.args.ctx, tt.args.address) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.Country != tt.res.address.Country { - t.Errorf("got wrong result change required: expected: %v, actual: %v ", tt.res.address.Country, result.Country) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddOTP(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - accountName string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add ok", - args: args{ - es: GetMockManipulateUserWithOTPGen(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - accountName: "AccountName", - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "AggregateID", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddOTP(tt.args.ctx, tt.args.userID, tt.args.accountName) - - if tt.res.errFunc == nil && result.AggregateID == "" { - t.Errorf("result has no id") - } - if tt.res.errFunc == nil && result.Url == "" { - t.Errorf("result has no url") - } - if tt.res.errFunc == nil && result.SecretString == "" { - t.Errorf("result has no url") - } - if tt.res.errFunc == nil && result == nil { - t.Errorf("got wrong result change required: actual: %v ", result) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCheckMFAOTPSetup(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - code string - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "setup ok", - args: args{ - es: func() *UserEventstore { - es := GetMockManipulateUserWithOTP(ctrl, true, false) - es.validateTOTP = func(string, string) bool { - return true - } - return es - }(), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "id", - code: "code", - }, - res: res{}, - }, - { - name: "wrong code", - args: args{ - es: func() *UserEventstore { - es := GetMockManipulateUserWithOTP(ctrl, true, false) - es.validateTOTP = func(string, string) bool { - return false - } - return es - }(), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "id", - code: "code", - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - code: "code", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "empty code", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - code: "code", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "user has no otp", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - code: "code", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.CheckMFAOTPSetup(tt.args.ctx, tt.args.userID, tt.args.code, "") - - if tt.res.errFunc == nil && err != nil { - t.Errorf("result should not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCheckMFAOTP(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - userID string - code string - authRequest *req_model.AuthRequest - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "check ok", - args: args{ - es: func() *UserEventstore { - es := GetMockManipulateUserWithOTP(ctrl, true, true) - es.validateTOTP = func(string, string) bool { - return true - } - return es - }(), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "id", - code: "code", - authRequest: &req_model.AuthRequest{ - ID: "id", - AgentID: "agentID", - BrowserInfo: &req_model.BrowserInfo{ - UserAgent: "user agent", - AcceptLanguage: "accept langugage", - RemoteIP: net.IPv4(29, 4, 20, 19), - }, - }, - }, - res: res{}, - }, - { - name: "wrong code", - args: args{ - es: func() *UserEventstore { - es := GetMockManipulateUserWithOTP(ctrl, true, true) - es.validateTOTP = func(string, string) bool { - return false - } - return es - }(), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "id", - code: "code", - authRequest: &req_model.AuthRequest{ - ID: "id", - AgentID: "agentID", - BrowserInfo: &req_model.BrowserInfo{ - UserAgent: "user agent", - AcceptLanguage: "accept langugage", - RemoteIP: net.IPv4(29, 4, 20, 19), - }, - }, - }, - res: res{ - errFunc: caos_errs.IsErrorInvalidArgument, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - code: "code", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "empty code", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - code: "code", - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "user has no otp", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - userID: "userID", - code: "code", - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.CheckMFAOTP(tt.args.ctx, tt.args.userID, tt.args.code, tt.args.authRequest) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("result should not get err, got : %v", err) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveOTP(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - ctx context.Context - user *model.User - } - type res struct { - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove ok", - args: args{ - es: GetMockManipulateUserWithOTP(ctrl, false, true), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - }, - { - name: "empty userid", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "user has no otp", - args: args{ - es: GetMockManipulateUser(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveOTP(tt.args.ctx, tt.args.user.AggregateID) - - if tt.res.errFunc == nil && err != nil { - t.Errorf("result should not get err") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangesUser(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserEventstore - id string - secID string - lastSequence uint64 - limit uint64 - } - type res struct { - changes *model.UserChanges - profile *model.Profile - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "changes from events, ok", - args: args{ - es: GetMockChangesUserOK(ctrl), - id: "1", - lastSequence: 0, - limit: 0, - }, - res: res{ - changes: &model.UserChanges{Changes: []*model.UserChange{{EventType: "", Sequence: 1, ModifierID: ""}}, LastSequence: 1}, - profile: &model.Profile{FirstName: "Hans", LastName: "Muster"}, - }, - }, - { - name: "changes from events, no events", - args: args{ - es: GetMockChangesUserNoEvents(ctrl), - id: "2", - lastSequence: 0, - limit: 0, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.UserChanges(nil, tt.args.id, tt.args.lastSequence, tt.args.limit, false) - - profile := &model.Profile{} - if result != nil && len(result.Changes) > 0 { - b, err := json.Marshal(result.Changes[0].Data) - json.Unmarshal(b, profile) - if err != nil { - } - } - if !tt.res.wantErr && result.LastSequence != tt.res.changes.LastSequence && profile.DisplayName != tt.res.profile.DisplayName { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.changes.LastSequence, result.LastSequence) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/user/repository/eventsourcing/user.go b/internal/user/repository/eventsourcing/user.go index 67369de704..063f0f934d 100644 --- a/internal/user/repository/eventsourcing/user.go +++ b/internal/user/repository/eventsourcing/user.go @@ -2,15 +2,8 @@ package eventsourcing import ( "context" - "strings" - - "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/errors" es_models "github.com/caos/zitadel/internal/eventstore/models" - es_sdk "github.com/caos/zitadel/internal/eventstore/sdk" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - usr_model "github.com/caos/zitadel/internal/user/model" "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" ) @@ -28,1223 +21,9 @@ func UserQuery(latestSequence uint64) *es_models.SearchQuery { LatestSequenceFilter(latestSequence) } -func UserUserNameUniqueQuery(userName string) *es_models.SearchQuery { - return es_models.NewSearchQuery(). - AggregateTypeFilter(model.UserUserNameAggregate). - AggregateIDFilter(userName). - OrderDesc(). - SetLimit(1) -} - -func UserExternalIDPUniqueQuery(externalIDPUserID string) *es_models.SearchQuery { - return es_models.NewSearchQuery(). - AggregateTypeFilter(model.UserExternalIDPAggregate). - AggregateIDFilter(externalIDPUserID). - OrderDesc(). - SetLimit(1) -} - func UserAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User) (*es_models.Aggregate, error) { if user == nil { return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dis83", "Errors.Internal") } return aggCreator.NewAggregate(ctx, user.AggregateID, model.UserAggregate, model.UserVersion, user.Sequence) } - -func UserAggregateOverwriteContext(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, resourceOwnerID string, userID string) (*es_models.Aggregate, error) { - if user == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dis83", "Errors.Internal") - } - - return aggCreator.NewAggregate(ctx, user.AggregateID, model.UserAggregate, model.UserVersion, user.Sequence, es_models.OverwriteResourceOwner(resourceOwnerID), es_models.OverwriteEditorUser(userID)) -} - -func MachineCreateAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, resourceOwner string, userLoginMustBeDomain bool) (_ []*es_models.Aggregate, err error) { - if user == nil || user.Machine == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-duxk2", "Errors.Internal") - } - - var agg *es_models.Aggregate - if resourceOwner != "" { - agg, err = UserAggregateOverwriteContext(ctx, aggCreator, user, resourceOwner, user.AggregateID) - } else { - resourceOwner = authz.GetCtxData(ctx).OrgID - agg, err = UserAggregate(ctx, aggCreator, user) - } - if err != nil { - return nil, err - } - if !userLoginMustBeDomain { - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(org_es_model.OrgAggregate). - AggregateIDsFilter() - - validation := addUserNameValidation(user.UserName) - agg.SetPrecondition(validationQuery, validation) - } - - agg, err = agg.AppendEvent(model.MachineAdded, user) - if err != nil { - return nil, err - } - - userNameAggregate, err := reservedUniqueUserNameAggregate(ctx, aggCreator, resourceOwner, user.UserName, userLoginMustBeDomain) - if err != nil { - return nil, err - } - return []*es_models.Aggregate{ - agg, - userNameAggregate, - }, nil -} - -func HumanCreateAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, initCode *model.InitUserCode, phoneCode *model.PhoneCode, resourceOwner string, userLoginMustBeDomain bool) (_ []*es_models.Aggregate, err error) { - if user == nil || user.Human == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-duxk2", "Errors.Internal") - } - - var agg *es_models.Aggregate - if resourceOwner != "" { - agg, err = UserAggregateOverwriteContext(ctx, aggCreator, user, resourceOwner, user.AggregateID) - } else { - resourceOwner = authz.GetCtxData(ctx).OrgID - agg, err = UserAggregate(ctx, aggCreator, user) - } - if err != nil { - return nil, err - } - if !userLoginMustBeDomain { - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(org_es_model.OrgAggregate). - AggregateIDsFilter() - - validation := addUserNameValidation(user.UserName) - agg.SetPrecondition(validationQuery, validation) - } - - agg, err = agg.AppendEvent(model.HumanAdded, user) - if err != nil { - return nil, err - } - if user.Email != nil && user.EmailAddress != "" && user.IsEmailVerified { - agg, err = agg.AppendEvent(model.UserEmailVerified, nil) - if err != nil { - return nil, err - } - } - if user.Phone != nil && user.PhoneNumber != "" && user.IsPhoneVerified { - agg, err = agg.AppendEvent(model.UserPhoneVerified, nil) - if err != nil { - return nil, err - } - } - if initCode != nil { - agg, err = agg.AppendEvent(model.InitializedUserCodeAdded, initCode) - if err != nil { - return nil, err - } - } - if phoneCode != nil { - agg, err = agg.AppendEvent(model.UserPhoneCodeAdded, phoneCode) - if err != nil { - return nil, err - } - } - - uniqueAggregates, err := getUniqueUserAggregates(ctx, aggCreator, user.UserName, user.EmailAddress, resourceOwner, userLoginMustBeDomain) - if err != nil { - return nil, err - } - return append(uniqueAggregates, agg), nil -} - -func UserRegisterAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, externalIDP *model.ExternalIDP, resourceOwner string, initCode *model.InitUserCode, userLoginMustBeDomain bool) ([]*es_models.Aggregate, error) { - if user == nil || resourceOwner == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-duxk2", "user, resourceowner, initcode must be set") - } - - if user.Human == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ekuEA", "user must be type human") - } - - aggregates := make([]*es_models.Aggregate, 0) - agg, err := UserAggregateOverwriteContext(ctx, aggCreator, user, resourceOwner, user.AggregateID) - if err != nil { - return nil, err - } - - agg, err = agg.AppendEvent(model.HumanRegistered, user) - if err != nil { - return nil, err - } - if initCode != nil { - agg, err = agg.AppendEvent(model.InitializedHumanCodeAdded, initCode) - if err != nil { - return nil, err - } - } - if user.Email != nil && user.EmailAddress != "" && user.IsEmailVerified { - agg, err = agg.AppendEvent(model.HumanEmailVerified, nil) - if err != nil { - return nil, err - } - } - - if externalIDP != nil { - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(org_es_model.OrgAggregate, iam_es_model.IAMAggregate). - AggregateIDsFilter() - - if !userLoginMustBeDomain { - validation := addUserNameAndIDPConfigExistingValidation(user.UserName, externalIDP) - agg.SetPrecondition(validationQuery, validation) - } else { - validation := addIDPConfigExistingValidation(externalIDP) - agg.SetPrecondition(validationQuery, validation) - } - - agg, err = agg.AppendEvent(model.HumanExternalIDPAdded, externalIDP) - uniqueExternalIDPAggregate, err := reservedUniqueExternalIDPAggregate(ctx, aggCreator, resourceOwner, externalIDP) - if err != nil { - return nil, err - } - aggregates = append(aggregates, uniqueExternalIDPAggregate) - } else if !userLoginMustBeDomain { - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(org_es_model.OrgAggregate). - AggregateIDsFilter() - validation := addUserNameValidation(user.UserName) - agg.SetPrecondition(validationQuery, validation) - } - - uniqueAggregates, err := getUniqueUserAggregates(ctx, aggCreator, user.UserName, user.EmailAddress, resourceOwner, userLoginMustBeDomain) - if err != nil { - return nil, err - } - aggregates = append(aggregates, uniqueAggregates...) - return append(aggregates, agg), nil -} - -func getUniqueUserAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, userName, emailAddress, resourceOwner string, userLoginMustBeDomain bool) ([]*es_models.Aggregate, error) { - userNameAggregate, err := reservedUniqueUserNameAggregate(ctx, aggCreator, resourceOwner, userName, userLoginMustBeDomain) - if err != nil { - return nil, err - } - - return []*es_models.Aggregate{ - userNameAggregate, - }, nil -} - -func reservedUniqueUserNameAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, resourceOwner, userName string, userLoginMustBeDomain bool) (*es_models.Aggregate, error) { - if userLoginMustBeDomain && resourceOwner == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-wWfgH", "Errors.Internal") - } - - uniqueUserName := userName - if userLoginMustBeDomain { - uniqueUserName = userName + resourceOwner - } - - aggregate, err := aggCreator.NewAggregate(ctx, uniqueUserName, model.UserUserNameAggregate, model.UserVersion, 0) - if resourceOwner != "" { - aggregate, err = aggCreator.NewAggregate(ctx, uniqueUserName, model.UserUserNameAggregate, model.UserVersion, 0, es_models.OverwriteResourceOwner(resourceOwner)) - } - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.UserUserNameReserved, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(UserUserNameUniqueQuery(uniqueUserName), isEventValidation(aggregate, model.UserUserNameReserved)), nil -} - -func releasedUniqueUserNameAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, resourceOwner, userName string, userLoginMustBeDomain bool) (aggregate *es_models.Aggregate, err error) { - if userLoginMustBeDomain && resourceOwner == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sK9Kg", "Errors.Internal") - } - - uniqueUserName := userName - if userLoginMustBeDomain { - uniqueUserName = userName + resourceOwner - } - - aggregate, err = aggCreator.NewAggregate(ctx, uniqueUserName, model.UserUserNameAggregate, model.UserVersion, 0) - if resourceOwner != "" { - aggregate, err = aggCreator.NewAggregate(ctx, uniqueUserName, model.UserUserNameAggregate, model.UserVersion, 0, es_models.OverwriteResourceOwner(resourceOwner)) - } - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.UserUserNameReleased, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(UserUserNameUniqueQuery(uniqueUserName), isEventValidation(aggregate, model.UserUserNameReleased)), nil -} - -func changeUniqueUserNameAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, resourceOwner, oldUsername, username string, userLoginMustBeDomain bool) ([]*es_models.Aggregate, error) { - aggregates := make([]*es_models.Aggregate, 2) - var err error - aggregates[0], err = releasedUniqueUserNameAggregate(ctx, aggCreator, resourceOwner, oldUsername, userLoginMustBeDomain) - if err != nil { - return nil, err - } - aggregates[1], err = reservedUniqueUserNameAggregate(ctx, aggCreator, resourceOwner, username, userLoginMustBeDomain) - if err != nil { - return nil, err - } - return aggregates, nil -} - -func UserDeactivateAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return userStateAggregate(aggCreator, user, model.UserDeactivated) -} - -func UserReactivateAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return userStateAggregate(aggCreator, user, model.UserReactivated) -} - -func UserLockAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return userStateAggregate(aggCreator, user, model.UserLocked) -} - -func UserUnlockAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return userStateAggregate(aggCreator, user, model.UserUnlocked) -} - -func UserRemoveAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, userLoginMustBeDomain bool) ([]*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.UserRemoved, nil) - if err != nil { - return nil, err - } - uniqueAgg, err := releasedUniqueUserNameAggregate(ctx, aggCreator, user.ResourceOwner, user.UserName, userLoginMustBeDomain) - if err != nil { - return nil, err - } - return []*es_models.Aggregate{ - agg, - uniqueAgg, - }, nil -} - -func userStateAggregate(aggCreator *es_models.AggregateCreator, user *model.User, state es_models.EventType) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(state, nil) - } -} - -func UserInitCodeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, code *model.InitUserCode) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if code == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d8i23", "code should not be nil") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.InitializedHumanCodeAdded, code) - } -} - -func UserInitCodeSentAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.InitializedHumanCodeSent, nil) - } -} - -func InitCodeVerifiedAggregate(aggCreator *es_models.AggregateCreator, user *model.User, password *model.Password) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - if user.Email != nil && !user.Email.IsEmailVerified { - agg, err = agg.AppendEvent(model.HumanEmailVerified, nil) - if err != nil { - return nil, err - } - } - if password != nil && password.Secret != nil { - agg, err = agg.AppendEvent(model.HumanPasswordChanged, password) - if err != nil { - return nil, err - } - } - return agg.AppendEvent(model.InitializedHumanCheckSucceeded, nil) - } -} - -func InitCodeCheckFailedAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.InitializedHumanCheckFailed, nil) - } -} - -func SkipMFAAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanMFAInitSkipped, nil) - } -} - -func PasswordChangeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, passwordChange *model.PasswordChange) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if passwordChange == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d9832", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPasswordChanged, passwordChange) - } -} - -func PasswordCheckSucceededAggregate(aggCreator *es_models.AggregateCreator, user *model.User, check *model.AuthRequest) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPasswordCheckSucceeded, check) - } -} -func PasswordCheckFailedAggregate(aggCreator *es_models.AggregateCreator, user *model.User, check *model.AuthRequest) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPasswordCheckFailed, check) - } -} - -func RequestSetPassword(aggCreator *es_models.AggregateCreator, user *model.User, request *model.PasswordCode) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if request == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d8ei2", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPasswordCodeAdded, request) - } -} - -func ResendInitialPasswordAggregate(aggCreator *es_models.AggregateCreator, user *model.User, code *usr_model.InitUserCode, email string) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if code == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dfs3q", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - if email != "" && user.Email != nil && email != user.Email.EmailAddress { - agg, err = agg.AppendEvent(model.HumanEmailChanged, map[string]interface{}{"email": email}) - if err != nil { - return nil, err - } - } - return agg.AppendEvent(model.InitializedHumanCodeAdded, code) - } -} - -func PasswordCodeSentAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPasswordCodeSent, nil) - } -} - -func ExternalLoginCheckSucceededAggregate(aggCreator *es_models.AggregateCreator, user *model.User, check *model.AuthRequest) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregateOverwriteContext(ctx, aggCreator, user, user.ResourceOwner, user.AggregateID) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanExternalLoginCheckSucceeded, check) - } -} - -func TokenAddedAggregate(aggCreator *es_models.AggregateCreator, user *model.User, token *model.Token) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregateOverwriteContext(ctx, aggCreator, user, user.ResourceOwner, user.AggregateID) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.UserTokenAdded, token) - } -} - -func MachineChangeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, machine *model.Machine) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if machine == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - changes := user.Machine.Changes(machine) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-0spow", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.MachineChanged, changes) - } -} - -func ProfileChangeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, profile *model.Profile) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if profile == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - changes := user.Profile.Changes(profile) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-0spow", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.HumanProfileChanged, changes) - } -} - -func EmailChangeAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, email *model.Email, code *model.EmailCode) (*es_models.Aggregate, error) { - if email == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dki8s", "Errors.Internal") - } - if (!email.IsEmailVerified && code == nil) || (email.IsEmailVerified && code != nil) { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-id934", "Errors.Internal") - } - changes := user.Email.Changes(email) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-s90pw", "Errors.NoChangesFound") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.HumanEmailChanged, changes) - if err != nil { - return nil, err - } - if user.Email == nil { - user.Email = new(model.Email) - } - if email.IsEmailVerified { - agg, err = agg.AppendEvent(model.HumanEmailVerified, code) - if err != nil { - return nil, err - } - } - if code != nil { - agg, err = agg.AppendEvent(model.HumanEmailCodeAdded, code) - if err != nil { - return nil, err - } - } - return agg, nil -} - -func EmailVerifiedAggregate(aggCreator *es_models.AggregateCreator, user *model.User) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanEmailVerified, nil) - } -} - -func EmailVerificationFailedAggregate(aggCreator *es_models.AggregateCreator, user *model.User) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanEmailVerificationFailed, nil) - } -} - -func EmailVerificationCodeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, code *model.EmailCode) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if code == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dki8s", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanEmailCodeAdded, code) - } -} - -func EmailCodeSentAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanEmailCodeSent, nil) - } -} - -func PhoneChangeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, phone *model.Phone, code *model.PhoneCode) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if phone == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dkso3", "Errors.Internal") - } - if (!phone.IsPhoneVerified && code == nil) || (phone.IsPhoneVerified && code != nil) { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dksi8", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - if user.Phone == nil { - user.Phone = new(model.Phone) - } - changes := user.Phone.Changes(phone) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sp0oc", "Errors.NoChangesFound") - } - agg, err = agg.AppendEvent(model.HumanPhoneChanged, changes) - if err != nil { - return nil, err - } - if phone.IsPhoneVerified { - return agg.AppendEvent(model.HumanPhoneVerified, code) - } - if code != nil { - return agg.AppendEvent(model.HumanPhoneCodeAdded, code) - } - return agg, nil - } -} - -func PhoneRemovedAggregate(aggCreator *es_models.AggregateCreator, user *model.User) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPhoneRemoved, nil) - } -} - -func PhoneVerifiedAggregate(aggCreator *es_models.AggregateCreator, user *model.User) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPhoneVerified, nil) - } -} - -func PhoneVerificationFailedAggregate(aggCreator *es_models.AggregateCreator, user *model.User) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPhoneVerificationFailed, nil) - } -} - -func PhoneVerificationCodeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, code *model.PhoneCode) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if code == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dsue2", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPhoneCodeAdded, code) - } -} - -func PhoneCodeSentAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanPhoneCodeSent, nil) - } -} - -func AddressChangeAggregate(aggCreator *es_models.AggregateCreator, user *model.User, address *model.Address) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if address == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dkx9s", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - if user.Address == nil { - user.Address = new(model.Address) - } - changes := user.Address.Changes(address) - if len(changes) == 0 { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-2tszw", "Errors.NoChangesFound") - } - return agg.AppendEvent(model.HumanAddressChanged, changes) - } -} - -func MFAOTPAddAggregate(aggCreator *es_models.AggregateCreator, user *model.User, otp *model.OTP) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if otp == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dkx9s", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanMFAOTPAdded, otp) - } -} - -func MFAOTPVerifyAggregate(aggCreator *es_models.AggregateCreator, user *model.User, userAgentID string) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanMFAOTPVerified, &model.OTPVerified{UserAgentID: userAgentID}) - } -} - -func MFAOTPCheckSucceededAggregate(aggCreator *es_models.AggregateCreator, user *model.User, authReq *model.AuthRequest) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if authReq == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sd5DA", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanMFAOTPCheckSucceeded, authReq) - } -} - -func MFAOTPCheckFailedAggregate(aggCreator *es_models.AggregateCreator, user *model.User, authReq *model.AuthRequest) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if authReq == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-64sd6", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanMFAOTPCheckFailed, authReq) - } -} - -func MFAOTPRemoveAggregate(aggCreator *es_models.AggregateCreator, user *model.User) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.HumanMFAOTPRemoved, nil) - } -} - -func MFAU2FAddAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNToken) es_sdk.AggregateFunc { - return MFAWebauthNAddAggregate(aggCreator, user, webauthN, model.HumanMFAU2FTokenAdded) -} - -func MFAPasswordlessAddAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNToken) es_sdk.AggregateFunc { - return MFAWebauthNAddAggregate(aggCreator, user, webauthN, model.HumanPasswordlessTokenAdded) -} - -func MFAWebauthNAddAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNToken, event es_models.EventType) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if webauthN == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4N90s", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(event, webauthN) - } -} - -func MFAU2FVerifyAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNVerify) es_sdk.AggregateFunc { - return MFAWebauthNVerifyAggregate(aggCreator, user, webauthN, model.HumanMFAU2FTokenVerified) -} - -func MFAPasswordlessVerifyAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNVerify) es_sdk.AggregateFunc { - return MFAWebauthNVerifyAggregate(aggCreator, user, webauthN, model.HumanPasswordlessTokenVerified) -} - -func MFAWebauthNVerifyAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNVerify, event es_models.EventType) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if webauthN == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4N90s", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(event, webauthN) - } -} - -func MFAU2FSignCountAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNSignCount, check *model.AuthRequest, checkSucceeded bool) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if webauthN == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4N90s", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.HumanMFAU2FTokenSignCountChanged, webauthN) - if err != nil { - return nil, err - } - if checkSucceeded { - return agg.AppendEvent(model.HumanMFAU2FTokenCheckSucceeded, check) - } else { - return agg.AppendEvent(model.HumanMFAU2FTokenCheckFailed, check) - } - } -} - -func MFAPasswordlessSignCountAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNSignCount, check *model.AuthRequest, checkSucceeded bool) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if webauthN == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4N90s", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - agg, err = agg.AppendEvent(model.HumanPasswordlessTokenChangeSignCount, webauthN) - if err != nil { - return nil, err - } - if checkSucceeded { - return agg.AppendEvent(model.HumanPasswordlessTokenCheckSucceeded, check) - } else { - return agg.AppendEvent(model.HumanPasswordlessTokenCheckFailed, check) - } - } -} - -func MFAU2FRemoveAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNTokenID) es_sdk.AggregateFunc { - return MFAWebauthNRemoveAggregate(aggCreator, user, webauthN, model.HumanMFAU2FTokenRemoved) -} - -func MFAPasswordlessRemoveAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNTokenID) es_sdk.AggregateFunc { - return MFAWebauthNRemoveAggregate(aggCreator, user, webauthN, model.HumanPasswordlessTokenRemoved) -} - -func MFAWebauthNRemoveAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNTokenID, event es_models.EventType) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if webauthN == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4Ms9l", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(event, webauthN) - } -} - -func MFAU2FBeginLoginAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNLogin) es_sdk.AggregateFunc { - return MFAWebauthNBeginLoginAggregate(aggCreator, user, webauthN, model.HumanMFAU2FTokenBeginLogin) -} - -func MFAPasswordlessBeginLoginAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNLogin) es_sdk.AggregateFunc { - return MFAWebauthNBeginLoginAggregate(aggCreator, user, webauthN, model.HumanPasswordlessTokenBeginLogin) -} - -func MFAWebauthNBeginLoginAggregate(aggCreator *es_models.AggregateCreator, user *model.User, webauthN *model.WebAuthNLogin, event es_models.EventType) es_sdk.AggregateFunc { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if webauthN == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-4N90s", "Errors.Internal") - } - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(event, webauthN) - } -} - -func SignOutAggregates(aggCreator *es_models.AggregateCreator, users []*model.User, agentID string) func(ctx context.Context) ([]*es_models.Aggregate, error) { - return func(ctx context.Context) ([]*es_models.Aggregate, error) { - aggregates := make([]*es_models.Aggregate, len(users)) - for i, user := range users { - agg, err := UserAggregateOverwriteContext(ctx, aggCreator, user, user.ResourceOwner, user.AggregateID) - if err != nil { - return nil, err - } - agg.AppendEvent(model.HumanSignedOut, map[string]interface{}{"userAgentID": agentID}) - aggregates[i] = agg - } - return aggregates, nil - } -} - -func DomainClaimedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, tempName string) ([]*es_models.Aggregate, error) { - aggregates, err := changeUniqueUserNameAggregate(ctx, aggCreator, user.ResourceOwner, user.UserName, tempName, false) - if err != nil { - return nil, err - } - userAggregate, err := UserAggregateOverwriteContext(ctx, aggCreator, user, user.ResourceOwner, user.AggregateID) - if err != nil { - return nil, err - } - userAggregate, err = userAggregate.AppendEvent(model.DomainClaimed, map[string]interface{}{"userName": tempName}) - if err != nil { - return nil, err - } - return append(aggregates, userAggregate), nil -} - -func DomainClaimedSentAggregate(aggCreator *es_models.AggregateCreator, user *model.User) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.DomainClaimedSent, nil) - } -} - -func ExternalIDPAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, externalIDPs ...*model.ExternalIDP) ([]*es_models.Aggregate, error) { - if externalIDPs == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Di9os", "Errors.Internal") - } - aggregates := make([]*es_models.Aggregate, 0) - agg, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(org_es_model.OrgAggregate, iam_es_model.IAMAggregate). - AggregateIDsFilter() - - validation := addIDPConfigExistingValidation(externalIDPs...) - agg.SetPrecondition(validationQuery, validation) - for _, externalIDP := range externalIDPs { - agg, err = agg.AppendEvent(model.HumanExternalIDPAdded, externalIDP) - uniqueAggregate, err := reservedUniqueExternalIDPAggregate(ctx, aggCreator, "", externalIDP) - if err != nil { - return nil, err - } - aggregates = append(aggregates, uniqueAggregate) - } - return append(aggregates, agg), nil -} - -func ExternalIDPRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, externalIDP *model.ExternalIDP, cascade bool) ([]*es_models.Aggregate, error) { - if externalIDP == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-Mlo0s", "Errors.Internal") - } - - aggregates := make([]*es_models.Aggregate, 0) - agg, err := UserAggregateOverwriteContext(ctx, aggCreator, user, user.ResourceOwner, authz.GetCtxData(ctx).UserID) - if err != nil { - return nil, err - } - if cascade { - agg, err = agg.AppendEvent(model.HumanExternalIDPCascadeRemoved, externalIDP) - } else { - agg, err = agg.AppendEvent(model.HumanExternalIDPRemoved, externalIDP) - } - uniqueReleasedAggregate, err := releasedUniqueExternalIDPAggregate(ctx, aggCreator, externalIDP, user.ResourceOwner) - if err != nil { - return nil, err - } - aggregates = append(aggregates, uniqueReleasedAggregate) - return append(aggregates, agg), nil -} - -func reservedUniqueExternalIDPAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, resourceOwner string, externalIDP *model.ExternalIDP) (*es_models.Aggregate, error) { - uniqueExternlIDP := externalIDP.IDPConfigID + externalIDP.UserID - aggregate, err := aggCreator.NewAggregate(ctx, uniqueExternlIDP, model.UserExternalIDPAggregate, model.UserVersion, 0) - if resourceOwner != "" { - aggregate, err = aggCreator.NewAggregate(ctx, uniqueExternlIDP, model.UserExternalIDPAggregate, model.UserVersion, 0, es_models.OverwriteResourceOwner(resourceOwner)) - } - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.HumanExternalIDPReserved, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(UserExternalIDPUniqueQuery(uniqueExternlIDP), isEventValidation(aggregate, model.HumanExternalIDPReserved)), nil -} - -func releasedUniqueExternalIDPAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, externalIDP *model.ExternalIDP, resourceOwnerID string) (aggregate *es_models.Aggregate, err error) { - uniqueExternlIDP := externalIDP.IDPConfigID + externalIDP.UserID - aggregate, err = aggCreator.NewAggregate(ctx, uniqueExternlIDP, model.UserExternalIDPAggregate, model.UserVersion, 0, es_models.OverwriteResourceOwner(resourceOwnerID), es_models.OverwriteEditorUser(authz.GetCtxData(ctx).UserID)) - - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.HumanExternalIDPReleased, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(UserExternalIDPUniqueQuery(uniqueExternlIDP), isEventValidation(aggregate, model.HumanExternalIDPReleased)), nil -} - -func UsernameChangedAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, user *model.User, oldUsername string, userLoginMustBeDomain bool) ([]*es_models.Aggregate, error) { - aggregates, err := changeUniqueUserNameAggregate(ctx, aggCreator, user.ResourceOwner, oldUsername, user.UserName, userLoginMustBeDomain) - if err != nil { - return nil, err - } - userAggregate, err := UserAggregate(ctx, aggCreator, user) - if err != nil { - return nil, err - } - userAggregate, err = userAggregate.AppendEvent(model.UserUserNameChanged, map[string]interface{}{"userName": user.UserName}) - if err != nil { - return nil, err - } - if !userLoginMustBeDomain { - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(org_es_model.OrgAggregate). - AggregateIDsFilter() - - validation := addUserNameValidation(user.UserName) - userAggregate.SetPrecondition(validationQuery, validation) - } - return append(aggregates, userAggregate), nil -} - -func isEventValidation(aggregate *es_models.Aggregate, eventType es_models.EventType) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - if len(events) == 0 { - aggregate.PreviousSequence = 0 - return nil - } - if events[0].Type == eventType { - return errors.ThrowPreconditionFailedf(nil, "EVENT-eJQqe", "user is already %v", eventType) - } - aggregate.PreviousSequence = events[0].Sequence - return nil - } -} - -func addUserNameValidation(userName string) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - domains := make([]*org_es_model.OrgDomain, 0) - for _, event := range events { - domains = handleDomainEvents(domains, event) - } - return handleCheckDomainAllowedAsUsername(domains, userName) - } -} - -func handleDomainEvents(domains []*org_es_model.OrgDomain, event *es_models.Event) []*org_es_model.OrgDomain { - switch event.Type { - case org_es_model.OrgDomainAdded: - domain := new(org_es_model.OrgDomain) - domain.SetData(event) - domains = append(domains, domain) - case org_es_model.OrgDomainVerified: - domain := new(org_es_model.OrgDomain) - domain.SetData(event) - for _, d := range domains { - if d.Domain == domain.Domain { - d.Verified = true - } - } - case org_es_model.OrgDomainRemoved: - domain := new(org_es_model.OrgDomain) - domain.SetData(event) - for i, d := range domains { - if d.Domain == domain.Domain { - domains[i] = domains[len(domains)-1] - domains[len(domains)-1] = nil - domains = domains[:len(domains)-1] - break - } - } - } - return domains -} - -func handleCheckDomainAllowedAsUsername(domains []*org_es_model.OrgDomain, userName string) error { - split := strings.Split(userName, "@") - if len(split) != 2 { - return nil - } - for _, d := range domains { - if d.Verified && d.Domain == split[1] { - return errors.ThrowPreconditionFailed(nil, "EVENT-us5Zw", "Errors.User.DomainNotAllowedAsUsername") - } - } - return nil -} - -func addIDPConfigExistingValidation(externalIDPs ...*model.ExternalIDP) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - iamLoginPolicy := new(iam_es_model.LoginPolicy) - orgPolicyExisting := false - orgLoginPolicy := new(iam_es_model.LoginPolicy) - for _, event := range events { - switch event.AggregateType { - case org_es_model.OrgAggregate: - orgPolicyExisting = handleOrgLoginPolicy(event, orgPolicyExisting, orgLoginPolicy) - case iam_es_model.IAMAggregate: - handleIAMLoginPolicy(event, iamLoginPolicy) - } - } - return handleIDPConfigExisting(iamLoginPolicy, orgLoginPolicy, orgPolicyExisting, externalIDPs...) - } -} - -func handleIDPConfigExisting(iamLoginPolicy, orgLoginPolicy *iam_es_model.LoginPolicy, orgPolicyExisting bool, externalIDPs ...*model.ExternalIDP) error { - if orgPolicyExisting { - if !orgLoginPolicy.AllowExternalIdp { - return errors.ThrowPreconditionFailed(nil, "EVENT-Wmi9s", "Errors.User.ExternalIDP.NotAllowed") - } - for _, externalIDP := range externalIDPs { - existing := false - for _, provider := range orgLoginPolicy.IDPProviders { - if provider.IDPConfigID == externalIDP.IDPConfigID { - existing = true - break - } - } - if !existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-Ms9it", "Errors.User.ExternalIDP.IDPConfigNotExisting") - } - } - } - if !iamLoginPolicy.AllowExternalIdp { - return errors.ThrowPreconditionFailed(nil, "EVENT-Ns7uf", "Errors.User.ExternalIDP.NotAllowed") - } - for _, externalIDP := range externalIDPs { - existing := false - for _, provider := range iamLoginPolicy.IDPProviders { - if provider.IDPConfigID == externalIDP.IDPConfigID { - existing = true - break - } - } - if !existing { - return errors.ThrowPreconditionFailed(nil, "EVENT-Ms9it", "Errors.User.ExternalIDP.IDPConfigNotExisting") - } - } - return nil -} - -func addUserNameAndIDPConfigExistingValidation(userName string, externalIDP *model.ExternalIDP) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - domains := make([]*org_es_model.OrgDomain, 0) - iamLoginPolicy := new(iam_es_model.LoginPolicy) - orgPolicyExisting := false - orgLoginPolicy := new(iam_es_model.LoginPolicy) - - for _, event := range events { - domains = handleDomainEvents(domains, event) - - switch event.AggregateType { - case org_es_model.OrgAggregate: - orgPolicyExisting = handleOrgLoginPolicy(event, orgPolicyExisting, orgLoginPolicy) - case iam_es_model.IAMAggregate: - handleIAMLoginPolicy(event, iamLoginPolicy) - } - } - err := handleCheckDomainAllowedAsUsername(domains, userName) - if err != nil { - return err - } - return handleIDPConfigExisting(iamLoginPolicy, orgLoginPolicy, orgPolicyExisting, externalIDP) - } -} - -func handleOrgLoginPolicy(event *es_models.Event, orgPolicyExisting bool, orgLoginPolicy *iam_es_model.LoginPolicy) bool { - switch event.Type { - case org_es_model.LoginPolicyAdded: - orgPolicyExisting = true - orgLoginPolicy.SetData(event) - case org_es_model.LoginPolicyChanged: - orgLoginPolicy.SetData(event) - case org_es_model.LoginPolicyRemoved: - orgPolicyExisting = false - case org_es_model.LoginPolicyIDPProviderAdded: - idp := new(iam_es_model.IDPProvider) - idp.SetData(event) - orgLoginPolicy.IDPProviders = append(orgLoginPolicy.IDPProviders, idp) - case org_es_model.LoginPolicyIDPProviderRemoved, org_es_model.LoginPolicyIDPProviderCascadeRemoved: - idp := new(iam_es_model.IDPProvider) - idp.SetData(event) - for i, provider := range orgLoginPolicy.IDPProviders { - if provider.IDPConfigID == idp.IDPConfigID { - orgLoginPolicy.IDPProviders[i] = orgLoginPolicy.IDPProviders[len(orgLoginPolicy.IDPProviders)-1] - orgLoginPolicy.IDPProviders[len(orgLoginPolicy.IDPProviders)-1] = nil - orgLoginPolicy.IDPProviders = orgLoginPolicy.IDPProviders[:len(orgLoginPolicy.IDPProviders)-1] - break - } - } - } - return orgPolicyExisting -} - -func handleIAMLoginPolicy(event *es_models.Event, iamLoginPolicy *iam_es_model.LoginPolicy) { - switch event.Type { - case iam_es_model.LoginPolicyAdded, iam_es_model.LoginPolicyChanged: - iamLoginPolicy.SetData(event) - case iam_es_model.LoginPolicyIDPProviderAdded: - idp := new(iam_es_model.IDPProvider) - idp.SetData(event) - iamLoginPolicy.IDPProviders = append(iamLoginPolicy.IDPProviders, idp) - case iam_es_model.LoginPolicyIDPProviderRemoved, iam_es_model.LoginPolicyIDPProviderCascadeRemoved: - idp := new(iam_es_model.IDPProvider) - idp.SetData(event) - for i, provider := range iamLoginPolicy.IDPProviders { - if provider.IDPConfigID == idp.IDPConfigID { - iamLoginPolicy.IDPProviders[i] = iamLoginPolicy.IDPProviders[len(iamLoginPolicy.IDPProviders)-1] - iamLoginPolicy.IDPProviders[len(iamLoginPolicy.IDPProviders)-1] = nil - iamLoginPolicy.IDPProviders = iamLoginPolicy.IDPProviders[:len(iamLoginPolicy.IDPProviders)-1] - break - } - } - } -} diff --git a/internal/user/repository/eventsourcing/user_test.go b/internal/user/repository/eventsourcing/user_test.go deleted file mode 100644 index e4ba6c34b7..0000000000 --- a/internal/user/repository/eventsourcing/user_test.go +++ /dev/null @@ -1,2529 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - "time" - - "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/crypto" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -func TestUserByIDQuery(t *testing.T) { - type args struct { - id string - sequence uint64 - } - type res struct { - filterLen int - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user by id query ok", - args: args{ - id: "ID", - sequence: 1, - }, - res: res{ - filterLen: 3, - }, - }, - { - name: "no id", - args: args{ - sequence: 1, - }, - res: res{ - filterLen: 3, - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - query, err := UserByIDQuery(tt.args.id, tt.args.sequence) - if !tt.res.wantErr && query == nil { - t.Errorf("query should not be nil") - } - if !tt.res.wantErr && len(query.Filters) != tt.res.filterLen { - t.Errorf("got wrong filter len: expected: %v, actual: %v ", tt.res.filterLen, len(query.Filters)) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserQuery(t *testing.T) { - type args struct { - sequence uint64 - } - type res struct { - filterLen int - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user query ok", - args: args{ - sequence: 1, - }, - res: res{ - filterLen: 2, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - query := UserQuery(tt.args.sequence) - if query == nil { - t.Errorf("query should not be nil") - } - if len(query.Filters) != tt.res.filterLen { - t.Errorf("got wrong filter len: expected: %v, actual: %v ", tt.res.filterLen, len(query.Filters)) - } - }) - } -} - -func TestHumanCreateAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - initCode *model.InitUserCode - phoneCode *model.PhoneCode - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - aggregatesLen int - checkData []bool - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user create aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanAdded}, - checkData: []bool{true}, - aggregatesLen: 2, - }, - }, - { - name: "new user nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "create with init code", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - initCode: &model.InitUserCode{}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanAdded, model.InitializedUserCodeAdded}, - checkData: []bool{true, true}, - aggregatesLen: 2, - }, - }, - { - name: "create with phone code", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - phoneCode: &model.PhoneCode{}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanAdded, model.UserPhoneCodeAdded}, - checkData: []bool{true, true}, - aggregatesLen: 2, - }, - }, - { - name: "create with email verified", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress", IsEmailVerified: true}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanAdded, model.UserEmailVerified}, - checkData: []bool{true, false}, - aggregatesLen: 2, - }, - }, - { - name: "create with phone verified", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - Phone: &model.Phone{PhoneNumber: "PhoneNumber", IsPhoneVerified: true}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanAdded, model.UserPhoneVerified}, - checkData: []bool{true, false}, - aggregatesLen: 2, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregates, err := HumanCreateAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.user, tt.args.initCode, tt.args.phoneCode, "", true) - - if !tt.res.wantErr && len(aggregates) != tt.res.aggregatesLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.aggregatesLen, len(aggregates)) - } - - if !tt.res.wantErr && len(aggregates[1].Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(aggregates[1].Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && aggregates[1].Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], aggregates[1].Events[i].Type.String()) - } - if !tt.res.wantErr && tt.res.checkData[i] && aggregates[1].Events[i].Data == nil { - t.Errorf("should have data in event") - } - if !tt.res.wantErr && !tt.res.checkData[i] && aggregates[1].Events[i].Data != nil { - t.Errorf("should not have data in event") - } - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestMachineCreateAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - aggregatesLen int - checkData []bool - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user create aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Machine: &model.Machine{ - Description: "Description", - Name: "Name", - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.MachineAdded}, - checkData: []bool{true}, - aggregatesLen: 2, - }, - }, - { - name: "new user nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregates, err := MachineCreateAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.user, "", true) - - if !tt.res.wantErr && len(aggregates) != tt.res.aggregatesLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.aggregatesLen, len(aggregates)) - } - - if !tt.res.wantErr && len(aggregates[0].Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(aggregates[1].Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if !tt.res.wantErr && aggregates[0].Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], aggregates[0].Events[i].Type.String()) - } - if !tt.res.wantErr && tt.res.checkData[i] && aggregates[0].Events[i].Data == nil { - t.Errorf("should have data in event") - } - if !tt.res.wantErr && !tt.res.checkData[i] && aggregates[0].Events[i].Data != nil { - t.Errorf("should not have data in event") - } - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserRegisterAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - externalIDP *model.ExternalIDP - initCode *model.InitUserCode - resourceOwner string - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - aggLen int - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user register aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - initCode: &model.InitUserCode{}, - resourceOwner: "newResourceowner", - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanRegistered, model.InitializedHumanCodeAdded}, - aggLen: 2, - }, - }, - { - name: "user register with erxternalIDP aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - externalIDP: &model.ExternalIDP{IDPConfigID: "IDPConfigID"}, - resourceOwner: "newResourceowner", - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanRegistered, model.HumanExternalIDPAdded}, - aggLen: 3, - }, - }, - { - name: "new user nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: nil, - initCode: &model.InitUserCode{}, - resourceOwner: "newResourceowner", - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "create with init code", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - resourceOwner: "newResourceowner", - initCode: &model.InitUserCode{}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanRegistered, model.InitializedHumanCodeAdded}, - aggLen: 2, - }, - }, - { - name: "create no resourceowner", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - initCode: &model.InitUserCode{}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregates, err := UserRegisterAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.user, tt.args.externalIDP, tt.args.resourceOwner, tt.args.initCode, false) - - if tt.res.errFunc == nil && len(aggregates) != tt.res.aggLen { - t.Errorf("got wrong aggregates len: expected: %v, actual: %v ", tt.res.aggLen, len(aggregates)) - } - - if tt.res.errFunc == nil && len(aggregates[tt.res.aggLen-1].Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(aggregates[tt.res.aggLen-1].Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && aggregates[tt.res.aggLen-1].Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], aggregates[tt.res.aggLen-1].Events[i].Type.String()) - } - if tt.res.errFunc == nil && aggregates[tt.res.aggLen-1].Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserDeactivateAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user deactivate aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.UserDeactivated, - }, - }, - { - name: "new user nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserDeactivateAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserReactivateAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user reactivate aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.UserReactivated, - }, - }, - { - name: "new user nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserReactivateAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserLockedAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user locked aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.UserLocked, - }, - }, - { - name: "new user nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserLockAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserUnlockedAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user unlocked aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.UserUnlocked, - }, - }, - { - name: "new user nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserUnlockAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserInitCodeAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - code *model.InitUserCode - - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user unlocked aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - code: &model.InitUserCode{Expiry: time.Hour * 1}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.InitializedHumanCodeAdded, - }, - }, - { - name: "code nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserInitCodeAggregate(tt.args.aggCreator, tt.args.user, tt.args.code)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestInitCodeSentAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user init code sent aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.InitializedHumanCodeSent}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserInitCodeSentAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestInitCodeVerifiedAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - password *model.Password - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user init code only email verify", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanEmailVerified, model.InitializedHumanCheckSucceeded}, - }, - }, - { - name: "user init code only password", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress", IsEmailVerified: true}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.InitializedHumanCheckSucceeded}, - }, - }, - { - name: "user init code email and pw", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - password: &model.Password{Secret: &crypto.CryptoValue{}, ChangeRequired: false}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 3, - eventTypes: []models.EventType{model.HumanEmailVerified, model.HumanPasswordChanged, model.InitializedHumanCheckSucceeded}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := InitCodeVerifiedAggregate(tt.args.aggCreator, tt.args.user, tt.args.password)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestInitCodeCheckFailedAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "mfa skipped init ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.HumanMFAInitSkipped, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := SkipMFAAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestSkipMFAAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "init code check failed", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.InitializedHumanCheckFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := InitCodeCheckFailedAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangePasswordAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - passwordChange *model.PasswordChange - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user password aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - passwordChange: &model.PasswordChange{Password: model.Password{ChangeRequired: true}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.HumanPasswordChanged, - }, - }, - { - name: "password nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordChangeAggregate(tt.args.aggCreator, tt.args.user, tt.args.passwordChange)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRequestSetPasswordAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - request *model.PasswordCode - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user password aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - request: &model.PasswordCode{Expiry: time.Hour * 1}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.HumanPasswordCodeAdded, - }, - }, - { - name: "request nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := RequestSetPassword(tt.args.aggCreator, tt.args.user, tt.args.request)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestResendInitialPasswordAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - initcode *usr_model.InitUserCode - email string - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "resend initial password aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - initcode: &usr_model.InitUserCode{Expiry: time.Hour * 1}, - }, - res: res{ - eventLen: 1, - }, - }, - { - name: "resend initial password with same email ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "email"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - initcode: &usr_model.InitUserCode{Expiry: time.Hour * 1}, - email: "email", - }, - res: res{ - eventLen: 1, - }, - }, - { - name: "resend initial password with new email ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - Email: &model.Email{EmailAddress: "old"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - initcode: &usr_model.InitUserCode{Expiry: time.Hour * 1}, - email: "new", - }, - res: res{ - eventLen: 2, - }, - }, - { - name: "request nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ResendInitialPasswordAggregate(tt.args.aggCreator, tt.args.user, tt.args.initcode, tt.args.email)(tt.args.ctx) - if (tt.res.errFunc == nil && err != nil) || (tt.res.errFunc != nil && !tt.res.errFunc(err)) { - t.Errorf("got wrong err: %v ", err) - } - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - }) - } -} - -func TestPasswordCodeSentAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user password code sent aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanPasswordCodeSent}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PasswordCodeSentAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeProfileAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - profile *model.Profile - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user profile aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Profile: &model.Profile{FirstName: "FirstName"}, - }, - }, - profile: &model.Profile{FirstName: "FirstNameChanged"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.HumanProfileChanged, - }, - }, - { - name: "profile nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserName: "UserName", - Human: &model.Human{ - Profile: &model.Profile{DisplayName: "DisplayName"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := ProfileChangeAggregate(tt.args.aggCreator, tt.args.user, tt.args.profile)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - if tt.res.errFunc == nil && agg.Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, agg.Events[0].Type.String()) - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeEmailAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - email *model.Email - code *model.EmailCode - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change email aggregate, verified email", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - email: &model.Email{EmailAddress: "Changed", IsEmailVerified: true}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanEmailChanged, model.HumanEmailVerified}, - }, - }, - { - name: "with code", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - email: &model.Email{EmailAddress: "Changed"}, - code: &model.EmailCode{Expiry: time.Hour * 1}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanEmailChanged, model.HumanEmailCodeAdded}, - }, - }, - { - name: "email nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "Changed"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "email verified and code not nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "Changed", IsEmailVerified: true}, - }, - }, - code: &model.EmailCode{Expiry: time.Hour * 1}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "email not verified and code nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "Changed"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregate, err := EmailChangeAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.user, tt.args.email, tt.args.code) - - if tt.res.errFunc == nil && len(aggregate.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(aggregate.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && aggregate.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], aggregate.Events[i].Type.String()) - } - if tt.res.errFunc == nil && aggregate.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestVerifyEmailAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user email verified aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanEmailVerified}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := EmailVerifiedAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestVerificationFailedEmailAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user email verification failed aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanEmailVerificationFailed}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := EmailVerificationFailedAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCreateEmailCodeAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - code *model.EmailCode - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "with code", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - code: &model.EmailCode{Expiry: time.Hour * 1}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanEmailCodeAdded}, - }, - }, - { - name: "code nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "Changed"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := EmailVerificationCodeAggregate(tt.args.aggCreator, tt.args.user, tt.args.code)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if tt.res.errFunc == nil && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestEmailCodeSentAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user email code sent aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanEmailCodeSent}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := EmailCodeSentAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangePhoneAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - phone *model.Phone - code *model.PhoneCode - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "phone change aggregate verified phone", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Phone: &model.Phone{PhoneNumber: "+41791234567"}, - }, - }, - phone: &model.Phone{PhoneNumber: "+41799876543", IsPhoneVerified: true}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanPhoneChanged, model.HumanPhoneVerified}, - }, - }, - { - name: "with code", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Phone: &model.Phone{PhoneNumber: "PhoneNumber"}, - }, - }, - phone: &model.Phone{PhoneNumber: "Changed"}, - code: &model.PhoneCode{Expiry: time.Hour * 1}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 2, - eventTypes: []models.EventType{model.HumanPhoneChanged, model.HumanPhoneCodeAdded}, - }, - }, - { - name: "phone nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Phone: &model.Phone{PhoneNumber: "Changed"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "phone verified and code not nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Phone: &model.Phone{PhoneNumber: "Changed"}, - }, - }, - phone: &model.Phone{PhoneNumber: "Changed", IsPhoneVerified: true}, - code: &model.PhoneCode{Expiry: time.Hour * 1}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "phone not verified and code nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Phone: &model.Phone{PhoneNumber: "Changed"}, - }, - }, - phone: &model.Phone{PhoneNumber: "Changed"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PhoneChangeAggregate(tt.args.aggCreator, tt.args.user, tt.args.phone, tt.args.code)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if tt.res.errFunc == nil && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestVerifyPhoneAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user phone verified aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Phone: &model.Phone{PhoneNumber: "PhoneNumber"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanPhoneVerified}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PhoneVerifiedAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemovePhoneAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user phone removed aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Phone: &model.Phone{PhoneNumber: "PhoneNumber"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanPhoneRemoved}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PhoneRemovedAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestVerificationFailedPhoneAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user phone verification failed aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Phone: &model.Phone{PhoneNumber: "PhoneNumber"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanPhoneVerificationFailed}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PhoneVerificationFailedAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestCreatePhoneCodeAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - code *model.PhoneCode - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "with code", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "EmailAddress"}, - }, - }, - code: &model.PhoneCode{Expiry: time.Hour * 1}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanPhoneCodeAdded}, - }, - }, - { - name: "code nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Email: &model.Email{EmailAddress: "Changed"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PhoneVerificationCodeAggregate(tt.args.aggCreator, tt.args.user, tt.args.code)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if tt.res.errFunc == nil && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestPhoneCodeSentAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user phone code sent aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanPhoneCodeSent}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := PhoneCodeSentAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeAddressAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - address *model.Address - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user address change aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Address: &model.Address{Locality: "Locality"}, - }, - }, - address: &model.Address{Locality: "Changed"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanAddressChanged}, - }, - }, - { - name: "address nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - Human: &model.Human{ - Address: &model.Address{Locality: "Changed"}, - }, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := AddressChangeAggregate(tt.args.aggCreator, tt.args.user, tt.args.address)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if tt.res.errFunc == nil && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOTPAddAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - otp *model.OTP - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user otp change aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - otp: &model.OTP{}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanMFAOTPAdded}, - }, - }, - { - name: "otp nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := MFAOTPAddAggregate(tt.args.aggCreator, tt.args.user, tt.args.otp)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if tt.res.errFunc == nil && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOTPVerifyAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user otp change aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanMFAOTPVerified}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := MFAOTPVerifyAggregate(tt.args.aggCreator, tt.args.user, "")(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestOTPRemoveAggregate(t *testing.T) { - type args struct { - ctx context.Context - user *model.User - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user otp change aggregate ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - user: &model.User{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.HumanMFAOTPRemoved}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := MFAOTPRemoveAggregate(tt.args.aggCreator, tt.args.user)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestExternalIDPAddedAggregates(t *testing.T) { - type res struct { - aggregateCount int - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *models.AggregateCreator - user *model.User - externalIDP *model.ExternalIDP - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no user error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: models.NewAggregateCreator("test"), - user: nil, - }, - res: res{ - aggregateCount: 0, - isErr: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "user add external idp successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: models.NewAggregateCreator("test"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{ - AggregateID: "AggregateID", - Sequence: 5, - }, - }, - externalIDP: &model.ExternalIDP{ - IDPConfigID: "IDPConfigID", - UserID: "UserID", - DisplayName: "DisplayName", - }, - }, - res: res{ - aggregateCount: 2, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ExternalIDPAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.user, tt.args.externalIDP) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && len(got) != tt.res.aggregateCount { - t.Errorf("ExternalIDPAddedAggregate() aggregate count = %d, wanted count %d", len(got), tt.res.aggregateCount) - } - }) - } -} - -func TestExternalIDPRemovedAggregates(t *testing.T) { - type res struct { - aggregateCount int - isErr func(error) bool - } - type args struct { - ctx context.Context - aggCreator *models.AggregateCreator - user *model.User - externalIDP *model.ExternalIDP - } - tests := []struct { - name string - args args - res res - }{ - { - name: "no user error", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: models.NewAggregateCreator("test"), - user: nil, - }, - res: res{ - aggregateCount: 0, - isErr: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "user removed external idp successful", - args: args{ - ctx: authz.NewMockContext("org", "user"), - aggCreator: models.NewAggregateCreator("test"), - user: &model.User{ - ObjectRoot: models.ObjectRoot{ - AggregateID: "AggregateID", - Sequence: 5, - ResourceOwner: "ResourceOwner", - }, - }, - externalIDP: &model.ExternalIDP{ - IDPConfigID: "IDPConfigID", - UserID: "UserID", - }, - }, - res: res{ - aggregateCount: 2, - isErr: nil, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ExternalIDPRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.user, tt.args.externalIDP, false) - if tt.res.isErr == nil && err != nil { - t.Errorf("no error expected got %T: %v", err, err) - } - if tt.res.isErr != nil && !tt.res.isErr(err) { - t.Errorf("wrong error got %T: %v", err, err) - } - if tt.res.isErr == nil && len(got) != tt.res.aggregateCount { - t.Errorf("ExternalIDPRemovedAggregate() aggregate count = %d, wanted count %d", len(got), tt.res.aggregateCount) - } - }) - } -} diff --git a/internal/usergrant/model/user_grant.go b/internal/usergrant/model/user_grant.go deleted file mode 100644 index c8c733605d..0000000000 --- a/internal/usergrant/model/user_grant.go +++ /dev/null @@ -1,56 +0,0 @@ -package model - -import es_models "github.com/caos/zitadel/internal/eventstore/models" - -type UserGrant struct { - es_models.ObjectRoot - - State UserGrantState - UserID string - ProjectID string - GrantID string - RoleKeys []string -} - -type UserGrantState int32 - -const ( - UserGrantStateActive UserGrantState = iota - UserGrantStateInactive - UserGrantStateRemoved -) - -func (u *UserGrant) IsValid() bool { - return u.ProjectID != "" && u.UserID != "" -} - -func (u *UserGrant) IsActive() bool { - return u.State == UserGrantStateActive -} - -func (u *UserGrant) IsInactive() bool { - return u.State == UserGrantStateInactive -} - -func (u *UserGrant) RemoveRoleKeyIfExisting(key string) bool { - for i, role := range u.RoleKeys { - if role == key { - u.RoleKeys[i] = u.RoleKeys[len(u.RoleKeys)-1] - u.RoleKeys[len(u.RoleKeys)-1] = "" - u.RoleKeys = u.RoleKeys[:len(u.RoleKeys)-1] - return true - } - } - return false -} - -func (u *UserGrant) RemoveRoleKeysIfExisting(keys []string) bool { - exists := false - for _, key := range keys { - keyExists := u.RemoveRoleKeyIfExisting(key) - if keyExists { - exists = true - } - } - return exists -} diff --git a/internal/usergrant/model/user_grant_view.go b/internal/usergrant/model/user_grant_view.go index b5dd342433..246a361e0c 100644 --- a/internal/usergrant/model/user_grant_view.go +++ b/internal/usergrant/model/user_grant_view.go @@ -29,6 +29,14 @@ type UserGrantView struct { Sequence uint64 } +type UserGrantState int32 + +const ( + UserGrantStateActive UserGrantState = iota + UserGrantStateInactive + UserGrantStateRemoved +) + type UserGrantSearchRequest struct { Offset uint64 Limit uint64 diff --git a/internal/usergrant/repository/eventsourcing/cache.go b/internal/usergrant/repository/eventsourcing/cache.go deleted file mode 100644 index 14d940d3c3..0000000000 --- a/internal/usergrant/repository/eventsourcing/cache.go +++ /dev/null @@ -1,34 +0,0 @@ -package eventsourcing - -import ( - "github.com/caos/logging" - "github.com/caos/zitadel/internal/cache" - "github.com/caos/zitadel/internal/cache/config" - "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model" -) - -type UserGrantCache struct { - userGrantCache cache.Cache -} - -func StartCache(conf *config.CacheConfig) (*UserGrantCache, error) { - userGrantCache, err := conf.Config.NewCache() - logging.Log("EVENT-8EhUZ").OnError(err).Panic("unable to create user grant cache") - - return &UserGrantCache{userGrantCache: userGrantCache}, nil -} - -func (c *UserGrantCache) getUserGrant(ID string) *model.UserGrant { - user := &model.UserGrant{ObjectRoot: models.ObjectRoot{AggregateID: ID}} - err := c.userGrantCache.Get(ID, user) - logging.Log("EVENT-QAd7T").OnError(err).Debug("error in getting cache") - - return user -} - -func (c *UserGrantCache) cacheUserGrant(grant *model.UserGrant) { - err := c.userGrantCache.Set(grant.AggregateID, grant) - - logging.Log("EVENT-w2KNQ").OnError(err).Debug("error in setting user grant cache") -} diff --git a/internal/usergrant/repository/eventsourcing/eventstore.go b/internal/usergrant/repository/eventsourcing/eventstore.go deleted file mode 100644 index 1ae08d905d..0000000000 --- a/internal/usergrant/repository/eventsourcing/eventstore.go +++ /dev/null @@ -1,233 +0,0 @@ -package eventsourcing - -import ( - "context" - - "github.com/caos/zitadel/internal/cache/config" - caos_errs "github.com/caos/zitadel/internal/errors" - es_int "github.com/caos/zitadel/internal/eventstore" - "github.com/caos/zitadel/internal/eventstore/models" - es_models "github.com/caos/zitadel/internal/eventstore/models" - es_sdk "github.com/caos/zitadel/internal/eventstore/sdk" - "github.com/caos/zitadel/internal/id" - grant_model "github.com/caos/zitadel/internal/usergrant/model" - "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model" -) - -type UserGrantEventStore struct { - es_int.Eventstore - userGrantCache *UserGrantCache - idGenerator id.Generator -} - -type UserGrantConfig struct { - es_int.Eventstore - Cache *config.CacheConfig -} - -func StartUserGrant(conf UserGrantConfig) (*UserGrantEventStore, error) { - userGrantCache, err := StartCache(conf.Cache) - if err != nil { - return nil, err - } - return &UserGrantEventStore{ - Eventstore: conf.Eventstore, - userGrantCache: userGrantCache, - idGenerator: id.SonyFlakeGenerator, - }, nil -} - -func (es *UserGrantEventStore) UserGrantByID(ctx context.Context, id string) (*grant_model.UserGrant, error) { - grant := es.userGrantCache.getUserGrant(id) - - query, err := UserGrantByIDQuery(grant.AggregateID, grant.Sequence) - if err != nil { - return nil, err - } - err = es_sdk.Filter(ctx, es.FilterEvents, grant.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && grant.Sequence == 0 { - return nil, err - } - es.userGrantCache.cacheUserGrant(grant) - if grant.State == int32(grant_model.UserGrantStateRemoved) { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-2ks8d", "Errors.UserGrant.NotFound") - } - return model.UserGrantToModel(grant), nil -} - -func (es *UserGrantEventStore) AddUserGrant(ctx context.Context, grant *grant_model.UserGrant) (*grant_model.UserGrant, error) { - repoGrant, addAggregates, err := es.PrepareAddUserGrant(ctx, grant) - if err != nil { - return nil, err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoGrant.AppendEvents, addAggregates...) - if err != nil { - return nil, err - } - return model.UserGrantToModel(repoGrant), nil -} - -func (es *UserGrantEventStore) AddUserGrants(ctx context.Context, grants ...*grant_model.UserGrant) error { - aggregates := make([]*es_models.Aggregate, 0) - for _, grant := range grants { - _, addAggregates, err := es.PrepareAddUserGrant(ctx, grant) - if err != nil { - return err - } - for _, agg := range addAggregates { - aggregates = append(aggregates, agg) - } - } - return es_sdk.PushAggregates(ctx, es.PushAggregates, nil, aggregates...) -} - -func (es *UserGrantEventStore) PrepareAddUserGrant(ctx context.Context, grant *grant_model.UserGrant) (*model.UserGrant, []*es_models.Aggregate, error) { - if grant == nil || !grant.IsValid() { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-sdiw3", "Errors.UserGrant.Invalid") - } - id, err := es.idGenerator.Next() - if err != nil { - return nil, nil, err - } - grant.AggregateID = id - - repoGrant := model.UserGrantFromModel(grant) - - addAggregates, err := UserGrantAddedAggregate(ctx, es.Eventstore.AggregateCreator(), repoGrant) - if err != nil { - return nil, nil, err - } - return repoGrant, addAggregates, nil -} - -func (es *UserGrantEventStore) PrepareChangeUserGrant(ctx context.Context, grant *grant_model.UserGrant, cascade bool) (*model.UserGrant, *es_models.Aggregate, error) { - if grant == nil { - return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-lo0s9", "Errors.UserGrant.Invalid") - } - existingGrant, err := es.UserGrantByID(ctx, grant.AggregateID) - if err != nil { - return nil, nil, err - } - repoExistingGrant := model.UserGrantFromModel(existingGrant) - repoGrant := model.UserGrantFromModel(grant) - - aggFunc := UserGrantChangedAggregate(es.Eventstore.AggregateCreator(), repoExistingGrant, repoGrant, cascade) - projectAggregate, err := aggFunc(ctx) - if err != nil { - return nil, nil, err - } - return repoExistingGrant, projectAggregate, err -} - -func (es *UserGrantEventStore) ChangeUserGrant(ctx context.Context, grant *grant_model.UserGrant) (*grant_model.UserGrant, error) { - repoGrant, agg, err := es.PrepareChangeUserGrant(ctx, grant, false) - if err != nil { - return nil, err - } - - err = es_sdk.PushAggregates(ctx, es.PushAggregates, repoGrant.AppendEvents, agg) - if err != nil { - return nil, err - } - es.userGrantCache.cacheUserGrant(repoGrant) - return model.UserGrantToModel(repoGrant), nil -} - -func (es *UserGrantEventStore) ChangeUserGrants(ctx context.Context, grants ...*grant_model.UserGrant) error { - aggregates := make([]*es_models.Aggregate, len(grants)) - for i, grant := range grants { - _, agg, err := es.PrepareChangeUserGrant(ctx, grant, false) - if err != nil { - return err - } - aggregates[i] = agg - } - return es_sdk.PushAggregates(ctx, es.PushAggregates, nil, aggregates...) -} - -func (es *UserGrantEventStore) RemoveUserGrant(ctx context.Context, grantID string) error { - grant, projectAggregates, err := es.PrepareRemoveUserGrant(ctx, grantID, false) - if err != nil { - return err - } - err = es_sdk.PushAggregates(ctx, es.PushAggregates, grant.AppendEvents, projectAggregates...) - if err != nil { - return err - } - es.userGrantCache.cacheUserGrant(grant) - return nil -} - -func (es *UserGrantEventStore) RemoveUserGrants(ctx context.Context, grantIDs ...string) error { - aggregates := make([]*es_models.Aggregate, 0) - for _, grantID := range grantIDs { - _, aggs, err := es.PrepareRemoveUserGrant(ctx, grantID, false) - if err != nil { - return err - } - for _, agg := range aggs { - aggregates = append(aggregates, agg) - } - } - return es_sdk.PushAggregates(ctx, es.PushAggregates, nil, aggregates...) -} - -func (es *UserGrantEventStore) PrepareRemoveUserGrant(ctx context.Context, grantID string, cascade bool) (*model.UserGrant, []*es_models.Aggregate, error) { - grant, err := es.UserGrantByID(ctx, grantID) - if err != nil { - return nil, nil, err - } - repoExisting := model.UserGrantFromModel(grant) - repoGrant := &model.UserGrant{ObjectRoot: models.ObjectRoot{AggregateID: grantID}} - projectAggregates, err := UserGrantRemovedAggregate(ctx, es.Eventstore.AggregateCreator(), repoExisting, repoGrant, cascade) - if err != nil { - return nil, nil, err - } - return repoExisting, projectAggregates, nil -} - -func (es *UserGrantEventStore) DeactivateUserGrant(ctx context.Context, grantID string) (*grant_model.UserGrant, error) { - if grantID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8si34", "Errors.UserGrant.IDMissing") - } - grant, err := es.UserGrantByID(ctx, grantID) - if err != nil { - return nil, err - } - if !grant.IsActive() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-lo9sw", "Errors.UserGrant.NotActive") - } - repoExistingGrant := model.UserGrantFromModel(grant) - repoGrant := &model.UserGrant{ObjectRoot: models.ObjectRoot{AggregateID: grantID}} - - projectAggregate := UserGrantDeactivatedAggregate(es.Eventstore.AggregateCreator(), repoExistingGrant, repoGrant) - err = es_sdk.Push(ctx, es.PushAggregates, repoExistingGrant.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.userGrantCache.cacheUserGrant(repoGrant) - return model.UserGrantToModel(repoExistingGrant), nil -} - -func (es *UserGrantEventStore) ReactivateUserGrant(ctx context.Context, grantID string) (*grant_model.UserGrant, error) { - if grantID == "" { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-sksiw", "Errors.UserGrant.IDMissing") - } - grant, err := es.UserGrantByID(ctx, grantID) - if err != nil { - return nil, err - } - if !grant.IsInactive() { - return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-lo9sw", "Errors.UserGrant.NotInactive") - } - repoExistingGrant := model.UserGrantFromModel(grant) - repoGrant := &model.UserGrant{ObjectRoot: models.ObjectRoot{AggregateID: grantID}} - - projectAggregate := UserGrantReactivatedAggregate(es.Eventstore.AggregateCreator(), repoExistingGrant, repoGrant) - err = es_sdk.Push(ctx, es.PushAggregates, repoExistingGrant.AppendEvents, projectAggregate) - if err != nil { - return nil, err - } - es.userGrantCache.cacheUserGrant(repoExistingGrant) - return model.UserGrantToModel(repoExistingGrant), nil -} diff --git a/internal/usergrant/repository/eventsourcing/eventstore_mock_test.go b/internal/usergrant/repository/eventsourcing/eventstore_mock_test.go deleted file mode 100644 index d026a3d5a5..0000000000 --- a/internal/usergrant/repository/eventsourcing/eventstore_mock_test.go +++ /dev/null @@ -1,113 +0,0 @@ -package eventsourcing - -import ( - "encoding/json" - - mock_cache "github.com/caos/zitadel/internal/cache/mock" - "github.com/caos/zitadel/internal/eventstore/mock" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/id" - "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model" - "github.com/golang/mock/gomock" -) - -func GetMockedEventstore(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *UserGrantEventStore { - return &UserGrantEventStore{ - Eventstore: mockEs, - userGrantCache: GetMockCache(ctrl), - idGenerator: GetSonyFlacke(), - } -} - -func GetMockCache(ctrl *gomock.Controller) *UserGrantCache { - mockCache := mock_cache.NewMockCache(ctrl) - mockCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - mockCache.EXPECT().Set(gomock.Any(), gomock.Any()).Return(nil).AnyTimes() - return &UserGrantCache{userGrantCache: mockCache} -} - -func GetSonyFlacke() id.Generator { - return id.SonyFlakeGenerator -} - -func GetMockUserGrantByIDOK(ctrl *gomock.Controller) *UserGrantEventStore { - user := model.UserGrant{ - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserGrantAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockUserGrantByIDRemoved(ctrl *gomock.Controller) *UserGrantEventStore { - user := model.UserGrant{ - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserGrantAdded, Data: data}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserGrantRemoved}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockUserGrantByIDNoEvents(ctrl *gomock.Controller) *UserGrantEventStore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserGrant(ctrl *gomock.Controller) *UserGrantEventStore { - user := model.UserGrant{ - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserGrantAdded, Data: data}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserGrantInactive(ctrl *gomock.Controller) *UserGrantEventStore { - user := model.UserGrant{ - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}, - } - data, _ := json.Marshal(user) - events := []*es_models.Event{ - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserGrantAdded, Data: data}, - &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.UserGrantDeactivated}, - } - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} - -func GetMockManipulateUserGrantNoEvents(ctrl *gomock.Controller) *UserGrantEventStore { - events := []*es_models.Event{} - mockEs := mock.NewMockEventstore(ctrl) - mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil) - mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST")) - mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil) - return GetMockedEventstore(ctrl, mockEs) -} diff --git a/internal/usergrant/repository/eventsourcing/eventstore_test.go b/internal/usergrant/repository/eventsourcing/eventstore_test.go deleted file mode 100644 index ffbda1e2f2..0000000000 --- a/internal/usergrant/repository/eventsourcing/eventstore_test.go +++ /dev/null @@ -1,441 +0,0 @@ -package eventsourcing - -import ( - "context" - "reflect" - "testing" - - "github.com/golang/mock/gomock" - - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/usergrant/model" -) - -func TestUserByID(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserGrantEventStore - grant *model.UserGrant - } - type res struct { - grant *model.UserGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "user from events, ok", - args: args{ - es: GetMockUserGrantByIDOK(ctrl), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}}, - }, - }, - { - name: "no events found", - args: args{ - es: GetMockUserGrantByIDNoEvents(ctrl), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - { - name: "no id", - args: args{ - es: GetMockUserGrantByIDOK(ctrl), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "removed state", - args: args{ - es: GetMockUserGrantByIDRemoved(ctrl), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.UserGrantByID(nil, tt.args.grant.AggregateID) - - if !tt.res.wantErr && result.AggregateID != tt.res.grant.AggregateID { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.grant.AggregateID, result.AggregateID) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestAddUserGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserGrantEventStore - ctx context.Context - grant *model.UserGrant - } - type res struct { - result *model.UserGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "add grant, ok", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - ProjectID: "ProjectID", - UserID: "UserID", - RoleKeys: []string{"Key"}, - }, - }, - res: res{ - result: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - ProjectID: "ProjectID", - UserID: "UserID", - RoleKeys: []string{"Key"}, - }, - }, - }, - { - name: "invalid grant", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.AddUserGrant(tt.args.ctx, tt.args.grant) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.UserID == "" { - t.Errorf("result has no id") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestChangeUserGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserGrantEventStore - ctx context.Context - grant *model.UserGrant - } - type res struct { - result *model.UserGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change grant, ok", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - RoleKeys: []string{"KeyChanged"}, - }, - }, - res: res{ - result: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - RoleKeys: []string{"KeyChanged"}, - }, - }, - }, - { - name: "invalid grant", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: nil, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing user not found", - args: args{ - es: GetMockManipulateUserGrantNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - RoleKeys: []string{"KeyChanged"}, - }, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ChangeUserGrant(tt.args.ctx, tt.args.grant) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && !reflect.DeepEqual(result.RoleKeys, tt.res.result.RoleKeys) { - t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.res.result.RoleKeys, result.RoleKeys) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestRemoveUserGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserGrantEventStore - ctx context.Context - grant *model.UserGrant - } - type res struct { - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove grant, ok", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - }, - { - name: "no grantID", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "existing grant not found", - args: args{ - es: GetMockManipulateUserGrantNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - err := tt.args.es.RemoveUserGrant(tt.args.ctx, tt.args.grant.AggregateID) - - if !tt.res.wantErr && err != nil { - t.Errorf("should not get err") - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestDeactivateUserGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserGrantEventStore - ctx context.Context - grant *model.UserGrant - } - type res struct { - result *model.UserGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate, ok", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - result: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - ProjectID: "ProjectID", - State: model.UserGrantStateInactive, - }, - }, - }, - { - name: "no grant id", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant not existing", - args: args{ - es: GetMockManipulateUserGrantNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.DeactivateUserGrant(tt.args.ctx, tt.args.grant.AggregateID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.ProjectID != tt.res.result.ProjectID { - t.Errorf("got wrong result AppID: expected: %v, actual: %v ", tt.res.result.ProjectID, result.ProjectID) - } - if !tt.res.wantErr && result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestReactivateUserGrant(t *testing.T) { - ctrl := gomock.NewController(t) - type args struct { - es *UserGrantEventStore - ctx context.Context - grant *model.UserGrant - } - type res struct { - result *model.UserGrant - wantErr bool - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate, ok", - args: args{ - es: GetMockManipulateUserGrantInactive(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - result: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}, - State: model.UserGrantStateActive, - }, - }, - }, - { - name: "no grant id", - args: args{ - es: GetMockManipulateUserGrant(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant not existing", - args: args{ - es: GetMockManipulateUserGrantNoEvents(ctrl), - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID", Sequence: 1}}, - }, - res: res{ - wantErr: true, - errFunc: caos_errs.IsNotFound, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := tt.args.es.ReactivateUserGrant(tt.args.ctx, tt.args.grant.AggregateID) - - if !tt.res.wantErr && result.AggregateID == "" { - t.Errorf("result has no id") - } - if !tt.res.wantErr && result.State != tt.res.result.State { - t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.res.result.State, result.State) - } - if tt.res.wantErr && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} diff --git a/internal/usergrant/repository/eventsourcing/model/types.go b/internal/usergrant/repository/eventsourcing/model/types.go index 8c09224b11..66773d1a9d 100644 --- a/internal/usergrant/repository/eventsourcing/model/types.go +++ b/internal/usergrant/repository/eventsourcing/model/types.go @@ -3,16 +3,13 @@ package model import "github.com/caos/zitadel/internal/eventstore/models" const ( - UserGrantAggregate models.AggregateType = "usergrant" - UserGrantUniqueAggregate models.AggregateType = "usergrant.unique" + UserGrantAggregate models.AggregateType = "usergrant" UserGrantAdded models.EventType = "user.grant.added" UserGrantChanged models.EventType = "user.grant.changed" UserGrantRemoved models.EventType = "user.grant.removed" UserGrantDeactivated models.EventType = "user.grant.deactivated" UserGrantReactivated models.EventType = "user.grant.reactivated" - UserGrantReserved models.EventType = "user.grant.reserved" - UserGrantReleased models.EventType = "user.grant.released" UserGrantCascadeRemoved models.EventType = "user.grant.cascade.removed" UserGrantCascadeChanged models.EventType = "user.grant.cascade.changed" diff --git a/internal/usergrant/repository/eventsourcing/model/user_grant.go b/internal/usergrant/repository/eventsourcing/model/user_grant.go index 6694407d36..2376f5a89c 100644 --- a/internal/usergrant/repository/eventsourcing/model/user_grant.go +++ b/internal/usergrant/repository/eventsourcing/model/user_grant.go @@ -1,16 +1,7 @@ package model import ( - "encoding/json" - "github.com/caos/logging" - caos_errs "github.com/caos/zitadel/internal/errors" es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/usergrant/model" - "reflect" -) - -const ( - UserGrantVersion = "v1" ) type UserGrant struct { @@ -22,77 +13,3 @@ type UserGrant struct { GrantID string `json:"grantId,omitempty"` RoleKeys []string `json:"roleKeys,omitempty"` } - -type UserGrantID struct { - es_models.ObjectRoot - GrantID string `json:"grantId"` -} - -func (g *UserGrant) Changes(changed *UserGrant) map[string]interface{} { - changes := make(map[string]interface{}, 1) - if !reflect.DeepEqual(g.RoleKeys, changed.RoleKeys) { - changes["roleKeys"] = changed.RoleKeys - } - return changes -} - -func UserGrantFromModel(grant *model.UserGrant) *UserGrant { - return &UserGrant{ - ObjectRoot: grant.ObjectRoot, - UserID: grant.UserID, - ProjectID: grant.ProjectID, - GrantID: grant.GrantID, - State: int32(grant.State), - RoleKeys: grant.RoleKeys, - } -} - -func UserGrantToModel(grant *UserGrant) *model.UserGrant { - return &model.UserGrant{ - ObjectRoot: grant.ObjectRoot, - UserID: grant.UserID, - ProjectID: grant.ProjectID, - GrantID: grant.GrantID, - State: model.UserGrantState(grant.State), - RoleKeys: grant.RoleKeys, - } -} - -func (g *UserGrant) AppendEvents(events ...*es_models.Event) error { - for _, event := range events { - if err := g.AppendEvent(event); err != nil { - return err - } - } - return nil -} - -func (g *UserGrant) AppendEvent(event *es_models.Event) error { - g.ObjectRoot.AppendEvent(event) - switch event.Type { - case UserGrantAdded, - UserGrantChanged, - UserGrantCascadeChanged: - return g.setData(event) - case UserGrantDeactivated: - g.appendGrantStateEvent(model.UserGrantStateInactive) - case UserGrantReactivated: - g.appendGrantStateEvent(model.UserGrantStateActive) - case UserGrantRemoved, - UserGrantCascadeRemoved: - g.appendGrantStateEvent(model.UserGrantStateRemoved) - } - return nil -} - -func (g *UserGrant) appendGrantStateEvent(state model.UserGrantState) { - g.State = int32(state) -} - -func (g *UserGrant) setData(event *es_models.Event) error { - if err := json.Unmarshal(event.Data, g); err != nil { - logging.Log("EVEN-lso9x").WithError(err).Error("could not unmarshal event data") - return caos_errs.ThrowInternal(err, "MODEL-o0se3", "could not unmarshal event") - } - return nil -} diff --git a/internal/usergrant/repository/eventsourcing/model/user_grant_test.go b/internal/usergrant/repository/eventsourcing/model/user_grant_test.go deleted file mode 100644 index 580cf8ffdb..0000000000 --- a/internal/usergrant/repository/eventsourcing/model/user_grant_test.go +++ /dev/null @@ -1,61 +0,0 @@ -package model - -import ( - "testing" - - es_models "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/usergrant/model" -) - -func TestAppendGrantStateEvent(t *testing.T) { - type args struct { - grant *UserGrant - grantID *UserGrantID - event *es_models.Event - state model.UserGrantState - } - tests := []struct { - name string - args args - result *UserGrant - }{ - { - name: "append deactivate grant event", - args: args{ - grant: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}}, - grantID: &UserGrantID{GrantID: "ProjectGrantID"}, - event: &es_models.Event{}, - state: model.UserGrantStateInactive, - }, - result: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}, State: int32(model.UserGrantStateInactive)}, - }, - { - name: "append reactivate grant event", - args: args{ - grant: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}}, - grantID: &UserGrantID{GrantID: "ProjectGrantID"}, - event: &es_models.Event{}, - state: model.UserGrantStateActive, - }, - result: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}, State: int32(model.UserGrantStateActive)}, - }, - { - name: "append remove grant event", - args: args{ - grant: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}}, - grantID: &UserGrantID{GrantID: "ProjectGrantID"}, - event: &es_models.Event{}, - state: model.UserGrantStateRemoved, - }, - result: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}, State: int32(model.UserGrantStateRemoved)}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - tt.args.grant.appendGrantStateEvent(tt.args.state) - if tt.args.grant.State != tt.result.State { - t.Errorf("got wrong result: actual: %v, expected: %v ", tt.result.State, tt.args.grant.State) - } - }) - } -} diff --git a/internal/usergrant/repository/eventsourcing/user_grant.go b/internal/usergrant/repository/eventsourcing/user_grant.go deleted file mode 100644 index e348d7d349..0000000000 --- a/internal/usergrant/repository/eventsourcing/user_grant.go +++ /dev/null @@ -1,258 +0,0 @@ -package eventsourcing - -import ( - "context" - - "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/models" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - proj_model "github.com/caos/zitadel/internal/project/model" - proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - usr_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model" -) - -func UserGrantByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) { - if id == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ols34", "id should be filled") - } - return UserGrantQuery(latestSequence). - AggregateIDFilter(id), nil -} - -func UserGrantQuery(latestSequence uint64) *es_models.SearchQuery { - return es_models.NewSearchQuery(). - AggregateTypeFilter(model.UserGrantAggregate). - LatestSequenceFilter(latestSequence) -} - -func UserGrantUniqueQuery(resourceOwner, projectID, userID string) *es_models.SearchQuery { - grantID := resourceOwner + projectID + userID - return es_models.NewSearchQuery(). - AggregateTypeFilter(model.UserGrantUniqueAggregate). - AggregateIDFilter(grantID). - OrderDesc(). - SetLimit(1) -} - -func UserGrantAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, grant *model.UserGrant) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dis83", "existing grant should not be nil") - } - return aggCreator.NewAggregate(ctx, grant.AggregateID, model.UserGrantAggregate, model.UserGrantVersion, grant.Sequence) -} - -func UserGrantAddedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, grant *model.UserGrant) ([]*es_models.Aggregate, error) { - agg, err := UserGrantAggregate(ctx, aggCreator, grant) - if err != nil { - return nil, err - } - validationQuery := es_models.NewSearchQuery(). - AggregateTypeFilter(usr_model.UserAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate). - AggregateIDsFilter(grant.UserID, authz.GetCtxData(ctx).OrgID, grant.ProjectID) - - validation := addUserGrantValidation(authz.GetCtxData(ctx).OrgID, grant) - agg, err = agg.SetPrecondition(validationQuery, validation).AppendEvent(model.UserGrantAdded, grant) - if err != nil { - return nil, err - } - - uniqueAggregate, err := reservedUniqueUserGrantAggregate(ctx, aggCreator, grant) - if err != nil { - return nil, err - } - return []*es_models.Aggregate{ - agg, - uniqueAggregate, - }, nil -} - -func reservedUniqueUserGrantAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, grant *model.UserGrant) (*es_models.Aggregate, error) { - grantID := authz.GetCtxData(ctx).OrgID + grant.ProjectID + grant.UserID - aggregate, err := aggCreator.NewAggregate(ctx, grantID, model.UserGrantUniqueAggregate, model.UserGrantVersion, 0) - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.UserGrantReserved, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(UserGrantUniqueQuery(authz.GetCtxData(ctx).OrgID, grant.ProjectID, grant.UserID), isEventValidation(aggregate, model.UserGrantReserved)), nil -} - -func releasedUniqueUserGrantAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, grant *model.UserGrant) (aggregate *es_models.Aggregate, err error) { - grantID := grant.ResourceOwner + grant.ProjectID + grant.UserID - aggregate, err = aggCreator.NewAggregate(ctx, grantID, model.UserGrantUniqueAggregate, model.UserGrantVersion, 0) - if err != nil { - return nil, err - } - aggregate, err = aggregate.AppendEvent(model.UserGrantReleased, nil) - if err != nil { - return nil, err - } - - return aggregate.SetPrecondition(UserGrantUniqueQuery(grant.ResourceOwner, grant.ProjectID, grant.UserID), isEventValidation(aggregate, model.UserGrantReleased)), nil -} - -func UserGrantChangedAggregate(aggCreator *es_models.AggregateCreator, existingGrant *model.UserGrant, grant *model.UserGrant, cascade bool) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-osl8x", "grant should not be nil") - } - agg, err := UserGrantAggregate(ctx, aggCreator, existingGrant) - if err != nil { - return nil, err - } - changes := existingGrant.Changes(grant) - if !cascade { - return agg.AppendEvent(model.UserGrantChanged, changes) - } - return agg.AppendEvent(model.UserGrantCascadeChanged, changes) - } -} - -func UserGrantDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existingGrant *model.UserGrant, grant *model.UserGrant) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-lo21s", "grant should not be nil") - } - agg, err := UserGrantAggregate(ctx, aggCreator, existingGrant) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.UserGrantDeactivated, nil) - } -} - -func UserGrantReactivatedAggregate(aggCreator *es_models.AggregateCreator, existingGrant *model.UserGrant, grant *model.UserGrant) func(ctx context.Context) (*es_models.Aggregate, error) { - return func(ctx context.Context) (*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-mks34", "grant should not be nil") - } - agg, err := UserGrantAggregate(ctx, aggCreator, existingGrant) - if err != nil { - return nil, err - } - return agg.AppendEvent(model.UserGrantReactivated, nil) - } -} - -func UserGrantRemovedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existingGrant *model.UserGrant, grant *model.UserGrant, cascade bool) ([]*es_models.Aggregate, error) { - if grant == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-lo21s", "grant should not be nil") - } - agg, err := UserGrantAggregate(ctx, aggCreator, existingGrant) - if err != nil { - return nil, err - } - eventType := model.UserGrantRemoved - if cascade { - eventType = model.UserGrantCascadeRemoved - } - agg, err = agg.AppendEvent(eventType, nil) - if err != nil { - return nil, err - } - uniqueAggregate, err := releasedUniqueUserGrantAggregate(ctx, aggCreator, existingGrant) - if err != nil { - return nil, err - } - return []*es_models.Aggregate{ - agg, - uniqueAggregate, - }, nil -} - -func isEventValidation(aggregate *es_models.Aggregate, eventType es_models.EventType) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - if len(events) == 0 { - aggregate.PreviousSequence = 0 - return nil - } - if events[0].Type == eventType { - return errors.ThrowPreconditionFailedf(nil, "EVENT-eJQqe", "user_grant is already %v", eventType) - } - aggregate.PreviousSequence = events[0].Sequence - return nil - } -} - -func addUserGrantValidation(resourceOwner string, grant *model.UserGrant) func(...*es_models.Event) error { - return func(events ...*es_models.Event) error { - existsOrg := false - existsUser := false - project := new(proj_es_model.Project) - for _, event := range events { - switch event.AggregateType { - case usr_model.UserAggregate: - switch event.Type { - case usr_model.UserAdded, usr_model.UserRegistered, usr_model.HumanRegistered, usr_model.HumanAdded, usr_model.MachineAdded: - existsUser = true - case usr_model.UserRemoved: - existsUser = false - } - case org_es_model.OrgAggregate: - switch event.Type { - case org_es_model.OrgAdded: - existsOrg = true - case org_es_model.OrgRemoved: - existsOrg = false - } - case proj_es_model.ProjectAggregate: - project.AppendEvent(event) - } - } - if !existsOrg { - return errors.ThrowPreconditionFailed(nil, "EVENT-3OfIm", "org doesn't exist") - } - if !existsUser { - return errors.ThrowPreconditionFailed(nil, "EVENT-Sl8uS", "user doesn't exist") - } - return checkProjectConditions(resourceOwner, grant, project) - } -} - -//TODO: rethink this function i know it's ugly. -func checkProjectConditions(resourceOwner string, grant *model.UserGrant, project *proj_es_model.Project) error { - if grant.ProjectID != project.AggregateID { - return errors.ThrowInvalidArgument(nil, "EVENT-ixlMx", "project doesn't exist") - } - if project.State == int32(proj_model.ProjectStateRemoved) { - return errors.ThrowPreconditionFailed(nil, "EVENT-Lxp0s", "project doesn't exist") - } - if resourceOwner == project.ResourceOwner { - return checkIfProjectHasRoles(grant.RoleKeys, project.Roles) - } - - if _, projectGrant := proj_es_model.GetProjectGrantByOrgID(project.Grants, resourceOwner); projectGrant != nil { - return checkIfProjectGrantHasRoles(grant.RoleKeys, projectGrant.RoleKeys) - } - return nil -} - -func checkIfProjectHasRoles(roles []string, existingRoles []*proj_es_model.ProjectRole) error { - for _, roleKey := range roles { - if _, role := proj_es_model.GetProjectRole(existingRoles, roleKey); role == nil { - return errors.ThrowPreconditionFailedf(nil, "EVENT-Lxp0s", "project doesn't have role %v", roleKey) - } - } - return nil -} - -func checkIfProjectGrantHasRoles(roles []string, existingRoles []string) error { - roleExists := false - for _, roleKey := range roles { - for _, existingRoleKey := range existingRoles { - if roleKey == existingRoleKey { - roleExists = true - continue - } - } - if !roleExists { - return errors.ThrowPreconditionFailed(nil, "EVENT-LSpwi", "project grant doesn't have role") - } - } - return nil -} diff --git a/internal/usergrant/repository/eventsourcing/user_grant_test.go b/internal/usergrant/repository/eventsourcing/user_grant_test.go deleted file mode 100644 index a2f57fdc16..0000000000 --- a/internal/usergrant/repository/eventsourcing/user_grant_test.go +++ /dev/null @@ -1,451 +0,0 @@ -package eventsourcing - -import ( - "context" - "testing" - - "github.com/caos/zitadel/internal/api/authz" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/models" - "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing/model" -) - -func TestUserGrantAddedAggregate(t *testing.T) { - type args struct { - ctx context.Context - grant *model.UserGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventType models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "usergrant added ok", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - grant: &model.UserGrant{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID"}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventType: model.UserGrantAdded, - }, - }, - { - name: "grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - grant: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregates, err := UserGrantAddedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.grant) - - if tt.res.errFunc == nil && len(aggregates[0].Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(aggregates[0].Events)) - } - if tt.res.errFunc == nil && aggregates[0].Events[0].Type != tt.res.eventType { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventType, aggregates[0].Events[0].Type.String()) - } - if tt.res.errFunc == nil && aggregates[0].Events[0].Data == nil { - t.Errorf("should have data in event") - } - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserGrantChangedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingGrant *model.UserGrant - newGrant *model.UserGrant - cascade bool - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "change project grant", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}}, - newGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"KeyChanged"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.UserGrantChanged}, - }, - }, - { - name: "change project grant cascade", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}}, - newGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"KeyChanged"}, - }, - cascade: true, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.UserGrantCascadeChanged}, - }, - }, - { - name: "existing grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: nil, - newGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}}, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}}, - newGrant: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserGrantChangedAggregate(tt.args.aggCreator, tt.args.existingGrant, tt.args.newGrant, tt.args.cascade)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - if tt.res.errFunc == nil && agg.Events[i].Data == nil { - t.Errorf("should have data in event") - } - } - - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserGrantRemovedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingGrant *model.UserGrant - newGrant *model.UserGrant - cascade bool - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "remove app", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}}, - newGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.UserGrantRemoved}, - }, - }, - { - name: "remove app cascade", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}}, - newGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - }, - cascade: true, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.UserGrantCascadeRemoved}, - }, - }, - { - name: "existing project nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - UserID: "UserID", - ProjectID: "ProjectID", - RoleKeys: []string{"Key"}}, - newGrant: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - aggregates, err := UserGrantRemovedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.existingGrant, tt.args.newGrant, tt.args.cascade) - - if tt.res.errFunc == nil && len(aggregates[0].Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(aggregates[0].Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && aggregates[0].Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], aggregates[0].Events[i].Type.String()) - } - } - - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserGrantDeactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingGrant *model.UserGrant - newGrant *model.UserGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "deactivate project grant", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - }, - newGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.UserGrantDeactivated}, - }, - }, - { - name: "existing grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - newGrant: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserGrantDeactivatedAggregate(tt.args.aggCreator, tt.args.existingGrant, tt.args.newGrant)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -} - -func TestUserGrantReactivatedAggregate(t *testing.T) { - type args struct { - ctx context.Context - existingGrant *model.UserGrant - newGrant *model.UserGrant - aggCreator *models.AggregateCreator - } - type res struct { - eventLen int - eventTypes []models.EventType - errFunc func(err error) bool - } - tests := []struct { - name string - args args - res res - }{ - { - name: "reactivate project grant", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - }, - newGrant: &model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - }, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - eventLen: 1, - eventTypes: []models.EventType{model.UserGrantReactivated}, - }, - }, - { - name: "existing grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - { - name: "grant nil", - args: args{ - ctx: authz.NewMockContext("orgID", "userID"), - existingGrant: &model.UserGrant{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}}, - newGrant: nil, - aggCreator: models.NewAggregateCreator("Test"), - }, - res: res{ - errFunc: caos_errs.IsPreconditionFailed, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - agg, err := UserGrantReactivatedAggregate(tt.args.aggCreator, tt.args.existingGrant, tt.args.newGrant)(tt.args.ctx) - - if tt.res.errFunc == nil && len(agg.Events) != tt.res.eventLen { - t.Errorf("got wrong event len: expected: %v, actual: %v ", tt.res.eventLen, len(agg.Events)) - } - for i := 0; i < tt.res.eventLen; i++ { - if tt.res.errFunc == nil && agg.Events[i].Type != tt.res.eventTypes[i] { - t.Errorf("got wrong event type: expected: %v, actual: %v ", tt.res.eventTypes[i], agg.Events[i].Type.String()) - } - } - - if tt.res.errFunc != nil && !tt.res.errFunc(err) { - t.Errorf("got wrong err: %v ", err) - } - }) - } -}