diff --git a/internal/admin/repository/eventsourcing/eventstore/iam.go b/internal/admin/repository/eventsourcing/eventstore/iam.go index 4144e62fd7..3c94d0478f 100644 --- a/internal/admin/repository/eventsourcing/eventstore/iam.go +++ b/internal/admin/repository/eventsourcing/eventstore/iam.go @@ -9,13 +9,13 @@ import ( "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" org_es "github.com/caos/zitadel/internal/org/repository/eventsourcing" usr_model "github.com/caos/zitadel/internal/user/model" usr_es "github.com/caos/zitadel/internal/user/repository/eventsourcing" - - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_es "github.com/caos/zitadel/internal/iam/repository/eventsourcing" + iam_business "github.com/caos/zitadel/internal/v2/business/iam" ) type IAMRepository struct { @@ -26,6 +26,8 @@ type IAMRepository struct { View *admin_view.View SystemDefaults systemdefaults.SystemDefaults Roles []string + + IAMV2 *iam_business.Repository } func (repo *IAMRepository) IAMMemberByID(ctx context.Context, orgID, userID string) (*iam_model.IAMMemberView, error) { @@ -38,16 +40,25 @@ func (repo *IAMRepository) IAMMemberByID(ctx context.Context, orgID, userID stri func (repo *IAMRepository) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { member.AggregateID = repo.SystemDefaults.IamID + if repo.IAMV2 != nil { + return repo.IAMV2.AddIAMMember(ctx, member) + } return repo.IAMEventstore.AddIAMMember(ctx, member) } func (repo *IAMRepository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { member.AggregateID = repo.SystemDefaults.IamID + if repo.IAMV2 != nil { + return repo.IAMV2.ChangeIAMMember(ctx, member) + } return repo.IAMEventstore.ChangeIAMMember(ctx, member) } func (repo *IAMRepository) RemoveIAMMember(ctx context.Context, userID string) error { member := iam_model.NewIAMMember(repo.SystemDefaults.IamID, userID) + if repo.IAMV2 != nil { + return repo.IAMV2.RemoveIAMMember(ctx, member) + } return repo.IAMEventstore.RemoveIAMMember(ctx, member) } diff --git a/internal/admin/repository/eventsourcing/repository.go b/internal/admin/repository/eventsourcing/repository.go index a7b8a98f25..69c134602f 100644 --- a/internal/admin/repository/eventsourcing/repository.go +++ b/internal/admin/repository/eventsourcing/repository.go @@ -14,6 +14,9 @@ import ( es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing" es_org "github.com/caos/zitadel/internal/org/repository/eventsourcing" es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" + iam_business "github.com/caos/zitadel/internal/v2/business/iam" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/member" ) type Config struct { @@ -37,6 +40,10 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r if err != nil { return nil, err } + esV2 := es.V2() + esV2.RegisterFilterEventMapper(iam.MemberAddedEventType, member.AddedEventMapper). + RegisterFilterEventMapper(iam.MemberChangedEventType, member.ChangedEventMapper). + RegisterFilterEventMapper(iam.MemberRemovedEventType, member.RemovedEventMapper) iam, err := es_iam.StartIAM(es_iam.IAMConfig{ Eventstore: es, @@ -84,6 +91,7 @@ func Start(ctx context.Context, conf Config, systemDefaults sd.SystemDefaults, r SystemDefaults: systemDefaults, SearchLimit: conf.SearchLimit, Roles: roles, + IAMV2: iam_business.StartRepository(&iam_business.Config{Eventstore: esV2}), }, AdministratorRepo: eventstore.AdministratorRepo{ View: view, diff --git a/internal/api/grpc/management/iam_converter.go b/internal/api/grpc/management/iam_converter.go index e8636ed43c..5dbbc2c1bd 100644 --- a/internal/api/grpc/management/iam_converter.go +++ b/internal/api/grpc/management/iam_converter.go @@ -18,9 +18,17 @@ func iamSetupStepFromModel(step iam_model.Step) management.IamSetupStep { switch step { case iam_model.Step1: return management.IamSetupStep_iam_setup_step_1 - //TODO: label policy - // case iam_model.Step2: - // return management.IamSetupStep_iam_setup_step_2 + case iam_model.Step2: + return management.IamSetupStep_iam_setup_step_2 + case iam_model.Step3: + return management.IamSetupStep_iam_setup_step_3 + case iam_model.Step4: + return management.IamSetupStep_iam_setup_step_4 + case iam_model.Step5: + return management.IamSetupStep_iam_setup_step_5 + case iam_model.Step6: + return management.IamSetupStep_iam_setup_step_6 + default: return management.IamSetupStep_iam_setup_step_UNDEFINED } diff --git a/internal/eventstore/config.go b/internal/eventstore/config.go index ab3fbc2b6f..51bb6bfe01 100644 --- a/internal/eventstore/config.go +++ b/internal/eventstore/config.go @@ -4,6 +4,8 @@ import ( "github.com/caos/zitadel/internal/cache/config" "github.com/caos/zitadel/internal/eventstore/internal/repository/sql" "github.com/caos/zitadel/internal/eventstore/models" + es_v2 "github.com/caos/zitadel/internal/eventstore/v2" + sql_v2 "github.com/caos/zitadel/internal/eventstore/v2/repository/sql" ) type Config struct { @@ -13,7 +15,7 @@ type Config struct { } func Start(conf Config) (Eventstore, error) { - repo, err := sql.Start(conf.Repository) + repo, sqlClient, err := sql.Start(conf.Repository) if err != nil { return nil, err } @@ -21,5 +23,6 @@ func Start(conf Config) (Eventstore, error) { return &eventstore{ repo: repo, aggregateCreator: models.NewAggregateCreator(conf.ServiceName), + esV2: es_v2.NewEventstore(sql_v2.NewCRDB(sqlClient)), }, nil } diff --git a/internal/eventstore/eventstore.go b/internal/eventstore/eventstore.go index 138599b856..b4f65d165a 100644 --- a/internal/eventstore/eventstore.go +++ b/internal/eventstore/eventstore.go @@ -6,6 +6,7 @@ import ( "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/internal/repository" "github.com/caos/zitadel/internal/eventstore/models" + es_v2 "github.com/caos/zitadel/internal/eventstore/v2" ) type Eventstore interface { @@ -14,6 +15,7 @@ type Eventstore interface { PushAggregates(ctx context.Context, aggregates ...*models.Aggregate) error FilterEvents(ctx context.Context, searchQuery *models.SearchQuery) (events []*models.Event, err error) LatestSequence(ctx context.Context, searchQuery *models.SearchQueryFactory) (uint64, error) + V2() *es_v2.Eventstore } var _ Eventstore = (*eventstore)(nil) @@ -21,6 +23,8 @@ var _ Eventstore = (*eventstore)(nil) type eventstore struct { repo repository.Repository aggregateCreator *models.AggregateCreator + + esV2 *es_v2.Eventstore } func (es *eventstore) AggregateCreator() *models.AggregateCreator { @@ -62,3 +66,7 @@ func (es *eventstore) LatestSequence(ctx context.Context, queryFactory *models.S func (es *eventstore) Health(ctx context.Context) error { return es.repo.Health(ctx) } + +func (es *eventstore) V2() *es_v2.Eventstore { + return es.esV2 +} diff --git a/internal/eventstore/internal/repository/sql/config.go b/internal/eventstore/internal/repository/sql/config.go index 5778c0c4d4..916dac7011 100644 --- a/internal/eventstore/internal/repository/sql/config.go +++ b/internal/eventstore/internal/repository/sql/config.go @@ -1,6 +1,8 @@ package sql import ( + "database/sql" + _ "github.com/lib/pq" "github.com/caos/zitadel/internal/config/types" @@ -11,12 +13,12 @@ type Config struct { SQL types.SQL } -func Start(conf Config) (*SQL, error) { +func Start(conf Config) (*SQL, *sql.DB, error) { client, err := conf.SQL.Start() if err != nil { - return nil, errors.ThrowPreconditionFailed(err, "SQL-9qBtr", "unable to open database connection") + return nil, nil, errors.ThrowPreconditionFailed(err, "SQL-9qBtr", "unable to open database connection") } return &SQL{ client: client, - }, nil + }, client, nil } diff --git a/internal/eventstore/v2/eventstore.go b/internal/eventstore/v2/eventstore.go index 41642187c3..9304ec26bb 100644 --- a/internal/eventstore/v2/eventstore.go +++ b/internal/eventstore/v2/eventstore.go @@ -124,7 +124,9 @@ func (es *Eventstore) mapEvents(events []*repository.Event) (mappedEvents []Even for i, event := range events { interceptors, ok := es.eventInterceptors[EventType(event.Type)] if !ok || interceptors.eventMapper == nil { - return nil, errors.ThrowPreconditionFailed(nil, "V2-usujB", "event mapper not defined") + mappedEvents[i] = BaseEventFromRepo(event) + continue + // return nil, errors.ThrowPreconditionFailed(nil, "V2-usujB", "event mapper not defined") } mappedEvents[i], err = interceptors.eventMapper(event) if err != nil { diff --git a/internal/eventstore/v2/read_model.go b/internal/eventstore/v2/read_model.go index 2f98063d17..96f8be5251 100644 --- a/internal/eventstore/v2/read_model.go +++ b/internal/eventstore/v2/read_model.go @@ -17,6 +17,7 @@ type ReadModel struct { CreationDate time.Time `json:"-"` ChangeDate time.Time `json:"-"` Events []EventReader `json:"-"` + ResourceOwner string `json:"-"` } //AppendEvents adds all the events to the read model. @@ -36,6 +37,9 @@ func (rm *ReadModel) Reduce() error { if rm.AggregateID == "" { rm.AggregateID = rm.Events[0].AggregateID() } + if rm.ResourceOwner == "" { + rm.ResourceOwner = rm.Events[0].ResourceOwner() + } if rm.CreationDate.IsZero() { rm.CreationDate = rm.Events[0].CreationDate() diff --git a/internal/management/repository/eventsourcing/eventstore/iam.go b/internal/management/repository/eventsourcing/eventstore/iam.go index 165d33df27..0ab06ce403 100644 --- a/internal/management/repository/eventsourcing/eventstore/iam.go +++ b/internal/management/repository/eventsourcing/eventstore/iam.go @@ -2,14 +2,21 @@ package eventstore import ( "context" + iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/iam/repository/eventsourcing" + iam_business "github.com/caos/zitadel/internal/v2/business/iam" ) type IAMRepository struct { IAMEvents *eventsourcing.IAMEventstore + + IAMV2 *iam_business.Repository } func (repo *IAMRepository) IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) { + if repo.IAMV2 != nil { + return repo.IAMV2.IAMByID(ctx, id) + } return repo.IAMEvents.IAMByID(ctx, id) } diff --git a/internal/management/repository/eventsourcing/repository.go b/internal/management/repository/eventsourcing/repository.go index 37917c0ea1..78b1da3530 100644 --- a/internal/management/repository/eventsourcing/repository.go +++ b/internal/management/repository/eventsourcing/repository.go @@ -7,6 +7,7 @@ import ( "github.com/caos/zitadel/internal/config/types" es_int "github.com/caos/zitadel/internal/eventstore" es_spol "github.com/caos/zitadel/internal/eventstore/spooler" + iam_model "github.com/caos/zitadel/internal/iam/model" es_iam "github.com/caos/zitadel/internal/iam/repository/eventsourcing" "github.com/caos/zitadel/internal/management/repository/eventsourcing/eventstore" "github.com/caos/zitadel/internal/management/repository/eventsourcing/handler" @@ -16,6 +17,10 @@ import ( es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing" es_usr "github.com/caos/zitadel/internal/user/repository/eventsourcing" es_grant "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing" + iam_business "github.com/caos/zitadel/internal/v2/business/iam" + "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/member" + "github.com/caos/zitadel/internal/v2/repository/policy" ) type Config struct { @@ -36,10 +41,30 @@ type EsRepository struct { } func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRepository, error) { + es, err := es_int.Start(conf.Eventstore) if err != nil { return nil, err } + esV2 := es.V2() + esV2.RegisterFilterEventMapper(iam.SetupStartedEventType, iam.SetupStepMapper). + RegisterFilterEventMapper(iam.SetupDoneEventType, iam.SetupStepMapper). + RegisterFilterEventMapper(iam.GlobalOrgSetEventType, iam.GlobalOrgSetMapper). + RegisterFilterEventMapper(iam.ProjectSetEventType, iam.ProjectSetMapper). + RegisterFilterEventMapper(iam.LabelPolicyAddedEventType, policy.LabelPolicyAddedEventMapper). + RegisterFilterEventMapper(iam.LabelPolicyChangedEventType, policy.LabelPolicyChangedEventMapper). + RegisterFilterEventMapper(iam.LoginPolicyAddedEventType, policy.LoginPolicyAddedEventMapper). + RegisterFilterEventMapper(iam.LoginPolicyChangedEventType, policy.LoginPolicyChangedEventMapper). + RegisterFilterEventMapper(iam.OrgIAMPolicyAddedEventType, policy.OrgIAMPolicyAddedEventMapper). + RegisterFilterEventMapper(iam.PasswordAgePolicyAddedEventType, policy.PasswordAgePolicyAddedEventMapper). + RegisterFilterEventMapper(iam.PasswordAgePolicyChangedEventType, policy.PasswordAgePolicyChangedEventMapper). + RegisterFilterEventMapper(iam.PasswordComplexityPolicyAddedEventType, policy.PasswordComplexityPolicyAddedEventMapper). + RegisterFilterEventMapper(iam.PasswordComplexityPolicyChangedEventType, policy.PasswordComplexityPolicyChangedEventMapper). + RegisterFilterEventMapper(iam.PasswordLockoutPolicyAddedEventType, policy.PasswordLockoutPolicyAddedEventMapper). + RegisterFilterEventMapper(iam.PasswordLockoutPolicyChangedEventType, policy.PasswordLockoutPolicyChangedEventMapper). + RegisterFilterEventMapper(iam.MemberAddedEventType, member.AddedEventMapper). + RegisterFilterEventMapper(iam.MemberChangedEventType, member.ChangedEventMapper). + RegisterFilterEventMapper(iam.MemberRemovedEventType, member.RemovedEventMapper) sqlClient, err := conf.View.Start() if err != nil { @@ -89,10 +114,17 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string) (*EsRe 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}, - IAMRepository: eventstore.IAMRepository{iam}, + IAMRepository: eventstore.IAMRepository{ + IAMEvents: iam, + IAMV2: iam_business.StartRepository(&iam_business.Config{Eventstore: esV2}), + }, }, nil } func (repo *EsRepository) Health() error { return repo.ProjectEvents.Health(context.Background()) } + +func (repo *EsRepository) IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) { + return repo.IAMRepository.IAMByID(ctx, id) +} diff --git a/internal/management/repository/org.go b/internal/management/repository/org.go index 11b02d14f5..b082b765e3 100644 --- a/internal/management/repository/org.go +++ b/internal/management/repository/org.go @@ -2,6 +2,7 @@ package repository import ( "context" + iam_model "github.com/caos/zitadel/internal/iam/model" org_model "github.com/caos/zitadel/internal/org/model" @@ -30,8 +31,6 @@ type OrgRepository interface { GetOrgMemberRoles() []string - GetMyOrgIamPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) - SearchIDPConfigs(ctx context.Context, request *iam_model.IDPConfigSearchRequest) (*iam_model.IDPConfigSearchResponse, error) IDPConfigByID(ctx context.Context, id string) (*iam_model.IDPConfigView, error) AddOIDCIDPConfig(ctx context.Context, idp *iam_model.IDPConfig) (*iam_model.IDPConfig, error) @@ -41,6 +40,8 @@ type OrgRepository interface { RemoveIDPConfig(ctx context.Context, idpConfigID string) error ChangeOIDCIDPConfig(ctx context.Context, oidcConfig *iam_model.OIDCIDPConfig) (*iam_model.OIDCIDPConfig, error) + GetMyOrgIamPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) + GetLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) GetDefaultLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) diff --git a/internal/v2/business/iam/converter.go b/internal/v2/business/iam/converter.go new file mode 100644 index 0000000000..1cbc36924d --- /dev/null +++ b/internal/v2/business/iam/converter.go @@ -0,0 +1,117 @@ +package iam + +import ( + "github.com/caos/zitadel/internal/eventstore/models" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/v2/repository/iam" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" + "github.com/caos/zitadel/internal/v2/repository/member" +) + +func readModelToIAM(readModel *iam_repo.ReadModel) *model.IAM { + return &model.IAM{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + GlobalOrgID: readModel.GlobalOrgID, + IAMProjectID: readModel.ProjectID, + SetUpDone: model.Step(readModel.SetUpDone), + SetUpStarted: model.Step(readModel.SetUpStarted), + Members: readModelToMembers(&readModel.Members), + DefaultLabelPolicy: readModelToLabelPolicy(&readModel.DefaultLabelPolicy), + DefaultLoginPolicy: readModelToLoginPolicy(&readModel.DefaultLoginPolicy), + DefaultOrgIAMPolicy: readModelToOrgIAMPolicy(&readModel.DefaultOrgIAMPolicy), + DefaultPasswordAgePolicy: readModelToPasswordAgePolicy(&readModel.DefaultPasswordAgePolicy), + DefaultPasswordComplexityPolicy: readModelToPasswordComplexityPolicy(&readModel.DefaultPasswordComplexityPolicy), + DefaultPasswordLockoutPolicy: readModelToPasswordLockoutPolicy(&readModel.DefaultPasswordLockoutPolicy), + // TODO: IDPs: []*model.IDPConfig, + } +} + +func readModelToMembers(readModel *iam_repo.MembersReadModel) []*model.IAMMember { + members := make([]*model.IAMMember, len(readModel.Members)) + + for i, member := range readModel.Members { + members[i] = &model.IAMMember{ + ObjectRoot: readModelToObjectRoot(member.ReadModel), + Roles: member.Roles, + UserID: member.UserID, + } + } + + return members +} + +func readModelToLabelPolicy(readModel *iam.LabelPolicyReadModel) *model.LabelPolicy { + return &model.LabelPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + PrimaryColor: readModel.PrimaryColor, + SecondaryColor: readModel.SecondaryColor, + Default: true, + //TODO: State: int32, + } +} + +func readModelToLoginPolicy(readModel *iam.LoginPolicyReadModel) *model.LoginPolicy { + return &model.LoginPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + AllowExternalIdp: readModel.AllowExternalIDP, + AllowRegister: readModel.AllowRegister, + AllowUsernamePassword: readModel.AllowUserNamePassword, + Default: true, + //TODO: IDPProviders: []*model.IDPProvider, + //TODO: State: int32, + } +} +func readModelToOrgIAMPolicy(readModel *iam.OrgIAMPolicyReadModel) *model.OrgIAMPolicy { + return &model.OrgIAMPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + UserLoginMustBeDomain: readModel.UserLoginMustBeDomain, + Default: true, + //TODO: State: int32, + } +} +func readModelToPasswordAgePolicy(readModel *iam.PasswordAgePolicyReadModel) *model.PasswordAgePolicy { + return &model.PasswordAgePolicy{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + ExpireWarnDays: uint64(readModel.ExpireWarnDays), + MaxAgeDays: uint64(readModel.MaxAgeDays), + //TODO: State: int32, + } +} +func readModelToPasswordComplexityPolicy(readModel *iam.PasswordComplexityPolicyReadModel) *model.PasswordComplexityPolicy { + return &model.PasswordComplexityPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + HasLowercase: readModel.HasLowercase, + HasNumber: readModel.HasNumber, + HasSymbol: readModel.HasSymbol, + HasUppercase: readModel.HasUpperCase, + MinLength: uint64(readModel.MinLength), + //TODO: State: int32, + } +} +func readModelToPasswordLockoutPolicy(readModel *iam.PasswordLockoutPolicyReadModel) *model.PasswordLockoutPolicy { + return &model.PasswordLockoutPolicy{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + MaxAttempts: uint64(readModel.MaxAttempts), + ShowLockOutFailures: readModel.ShowLockOutFailures, + //TODO: State: int32, + } +} + +func readModelToObjectRoot(readModel eventstore.ReadModel) models.ObjectRoot { + return models.ObjectRoot{ + AggregateID: readModel.AggregateID, + ChangeDate: readModel.ChangeDate, + CreationDate: readModel.CreationDate, + ResourceOwner: readModel.ResourceOwner, + Sequence: readModel.ProcessedSequence, + } +} + +func readModelToMember(readModel *member.ReadModel) *model.IAMMember { + return &model.IAMMember{ + ObjectRoot: readModelToObjectRoot(readModel.ReadModel), + Roles: readModel.Roles, + UserID: readModel.UserID, + } +} diff --git a/internal/v2/business/iam/member.go b/internal/v2/business/iam/member.go new file mode 100644 index 0000000000..3efb0a2c40 --- /dev/null +++ b/internal/v2/business/iam/member.go @@ -0,0 +1,100 @@ +package iam + +import ( + "context" + + "github.com/caos/zitadel/internal/errors" + caos_errs "github.com/caos/zitadel/internal/errors" + iam_model "github.com/caos/zitadel/internal/iam/model" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +func (r *Repository) AddIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { + if !member.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-W8m4l", "Errors.IAM.MemberInvalid") + } + + iam, err := r.iamByID(ctx, member.AggregateID) + if err != nil { + return nil, err + } + + idx, _ := iam.Members.MemberByUserID(member.UserID) + if idx > -1 { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-GPhuz", "Errors.IAM.MemberAlreadyExisting") + } + + iamAgg := iam_repo.AggregateFromReadModel(iam). + PushEvents(iam_repo.NewMemberAddedEvent(ctx, member.UserID, member.Roles...)) + + events, err := r.eventstore.PushAggregates(ctx, iamAgg) + if err != nil { + return nil, err + } + + if err = iam.AppendAndReduce(events...); err != nil { + return nil, err + } + + _, addedMember := iam.Members.MemberByUserID(member.UserID) + if member == nil { + return nil, errors.ThrowInternal(nil, "IAM-nuoDN", "member not saved") + } + return readModelToMember(addedMember), nil +} + +func (r *Repository) ChangeIAMMember(ctx context.Context, member *iam_model.IAMMember) (*iam_model.IAMMember, error) { + if !member.IsValid() { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.MemberInvalid") + } + + iam, err := r.iamByID(ctx, member.AggregateID) + if err != nil { + return nil, err + } + + _, currentMember := iam.Members.MemberByUserID(member.UserID) + if currentMember == nil { + return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-GPhuz", "Errors.IAM.MemberNotExisting") + } + + iamAgg := iam_repo.AggregateFromReadModel(iam). + PushEvents(iam_repo.NewMemberChangedEvent(ctx, member.UserID, member.Roles...)) + + events, err := r.eventstore.PushAggregates(ctx, iamAgg) + if err != nil { + return nil, err + } + + if err = iam.AppendAndReduce(events...); err != nil { + return nil, err + } + + _, addedMember := iam.Members.MemberByUserID(member.UserID) + if member == nil { + return nil, errors.ThrowInternal(nil, "IAM-E5nTQ", "member not saved") + } + return readModelToMember(addedMember), nil +} + +func (r *Repository) RemoveIAMMember(ctx context.Context, member *iam_model.IAMMember) error { + iam, err := r.iamByID(ctx, member.AggregateID) + if err != nil { + return err + } + + i, _ := iam.Members.MemberByUserID(member.UserID) + if i == -1 { + return nil + } + + iamAgg := iam_repo.AggregateFromReadModel(iam). + PushEvents(iam_repo.NewMemberRemovedEvent(ctx, member.UserID)) + + events, err := r.eventstore.PushAggregates(ctx, iamAgg) + if err != nil { + return err + } + + return iam.AppendAndReduce(events...) +} diff --git a/internal/v2/business/iam/repository.go b/internal/v2/business/iam/repository.go new file mode 100644 index 0000000000..abd57e3d6f --- /dev/null +++ b/internal/v2/business/iam/repository.go @@ -0,0 +1,48 @@ +package iam + +import ( + "context" + + "github.com/caos/zitadel/internal/eventstore/v2" + iam_model "github.com/caos/zitadel/internal/iam/model" + "github.com/caos/zitadel/internal/tracing" + iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" +) + +type Repository struct { + eventstore *eventstore.Eventstore +} + +type Config struct { + Eventstore *eventstore.Eventstore +} + +func StartRepository(config *Config) *Repository { + return &Repository{ + eventstore: config.Eventstore, + } +} + +func (r *Repository) IAMByID(ctx context.Context, id string) (_ *iam_model.IAM, err error) { + readModel, err := r.iamByID(ctx, id) + if err != nil { + return nil, err + } + + return readModelToIAM(readModel), nil +} + +func (r *Repository) iamByID(ctx context.Context, id string) (_ *iam_repo.ReadModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + query := eventstore.NewSearchQueryFactory(eventstore.ColumnsEvent, iam_repo.AggregateType).AggregateIDs(id) + + readModel := new(iam_repo.ReadModel) + err = r.eventstore.FilterToReducer(ctx, query, readModel) + if err != nil { + return nil, err + } + + return readModel, nil +} diff --git a/internal/v2/business/iam/setup.go b/internal/v2/business/iam/setup.go new file mode 100644 index 0000000000..2bec7fb9e5 --- /dev/null +++ b/internal/v2/business/iam/setup.go @@ -0,0 +1,49 @@ +package iam + +// import ( +// "context" + +// caos_errs "github.com/caos/zitadel/internal/errors" +// "github.com/caos/zitadel/internal/eventstore/v2" +// iam_model "github.com/caos/zitadel/internal/iam/model" +// ) + +// func (r *Repository) StartSetup(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) { +// iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepStartedEvent(ctx, iam_repo.Step(step))) +// if err != nil { +// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed") +// } +// return iam, nil +// } + +// func (r *Repository) SetupDone(ctx context.Context, iamID string, step iam_model.Step) (*iam_model.IAM, error) { +// iam, err := r.setup(ctx, iamID, iam_repo.Step(step), iam_repo.NewSetupStepDoneEvent(ctx, iam_repo.Step(step))) +// if err != nil { +// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-zx03n", "Setup start failed") +// } +// return iam, nil +// } + +// func (r *Repository) setup(ctx context.Context, iamID string, step iam_repo.Step, event eventstore.EventPusher) (*iam_model.IAM, error) { +// iam, err := r.iamByID(ctx, iamID) +// if err != nil && !caos_errs.IsNotFound(err) { +// return nil, err +// } + +// if iam != nil && (iam.SetUpStarted >= iam_repo.Step(step) || iam.SetUpStarted != iam.SetUpDone) { +// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error") +// } + +// aggregate := iam_repo.AggregateFromReadModel(iam). +// PushEvents(event) + +// events, err := r.eventstore.PushAggregates(ctx, aggregate) +// if err != nil { +// return nil, err +// } + +// if err = iam.AppendAndReduce(events...); err != nil { +// return nil, err +// } +// return readModelToIAM(iam), nil +// } diff --git a/internal/v2/business/org/repository.go b/internal/v2/business/org/repository.go new file mode 100644 index 0000000000..9e45aaf013 --- /dev/null +++ b/internal/v2/business/org/repository.go @@ -0,0 +1,99 @@ +package org + +import ( + "context" + + "github.com/caos/zitadel/internal/eventstore/v2" + iam_model "github.com/caos/zitadel/internal/iam/model" +) + +type Repository struct { + eventstore *eventstore.Eventstore +} + +type Config struct { + Eventstore *eventstore.Eventstore +} + +func StartRepository(config *Config) *Repository { + return &Repository{ + eventstore: config.Eventstore, + } +} + +func (r *Repository) GetMyOrgIamPolicy(ctx context.Context) (*iam_model.OrgIAMPolicyView, error) { + return nil, nil +} + +func (r *Repository) GetLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) { + return nil, nil +} +func (r *Repository) GetDefaultLoginPolicy(ctx context.Context) (*iam_model.LoginPolicyView, error) { + return nil, nil +} +func (r *Repository) AddLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { + return nil, nil +} +func (r *Repository) ChangeLoginPolicy(ctx context.Context, policy *iam_model.LoginPolicy) (*iam_model.LoginPolicy, error) { + return nil, nil +} +func (r *Repository) RemoveLoginPolicy(ctx context.Context) error { + return nil +} +func (r *Repository) SearchIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) { + return nil, nil +} +func (r *Repository) AddIDPProviderToLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) (*iam_model.IDPProvider, error) { + return nil, nil +} +func (r *Repository) RemoveIDPProviderFromLoginPolicy(ctx context.Context, provider *iam_model.IDPProvider) error { + return nil +} + +func (r *Repository) GetPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) { + return nil, nil +} +func (r *Repository) GetDefaultPasswordComplexityPolicy(ctx context.Context) (*iam_model.PasswordComplexityPolicyView, error) { + return nil, nil +} +func (r *Repository) AddPasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { + return nil, nil +} +func (r *Repository) ChangePasswordComplexityPolicy(ctx context.Context, policy *iam_model.PasswordComplexityPolicy) (*iam_model.PasswordComplexityPolicy, error) { + return nil, nil +} +func (r *Repository) RemovePasswordComplexityPolicy(ctx context.Context) error { + return nil +} + +func (r *Repository) GetPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error) { + return nil, nil +} +func (r *Repository) GetDefaultPasswordAgePolicy(ctx context.Context) (*iam_model.PasswordAgePolicyView, error) { + return nil, nil +} +func (r *Repository) AddPasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { + return nil, nil +} +func (r *Repository) ChangePasswordAgePolicy(ctx context.Context, policy *iam_model.PasswordAgePolicy) (*iam_model.PasswordAgePolicy, error) { + return nil, nil +} +func (r *Repository) RemovePasswordAgePolicy(ctx context.Context) error { + return nil +} + +func (r *Repository) GetPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) { + return nil, nil +} +func (r *Repository) GetDefaultPasswordLockoutPolicy(ctx context.Context) (*iam_model.PasswordLockoutPolicyView, error) { + return nil, nil +} +func (r *Repository) AddPasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { + return nil, nil +} +func (r *Repository) ChangePasswordLockoutPolicy(ctx context.Context, policy *iam_model.PasswordLockoutPolicy) (*iam_model.PasswordLockoutPolicy, error) { + return nil, nil +} +func (r *Repository) RemovePasswordLockoutPolicy(ctx context.Context) error { + return nil +} diff --git a/internal/v2/repository/iam/aggregate.go b/internal/v2/repository/iam/aggregate.go index bf30340c83..316a6da7c3 100644 --- a/internal/v2/repository/iam/aggregate.go +++ b/internal/v2/repository/iam/aggregate.go @@ -4,9 +4,37 @@ import ( "github.com/caos/zitadel/internal/eventstore/v2" ) +const ( + iamEventTypePrefix = eventstore.EventType("iam.") +) + +const ( + AggregateType = "iam" + AggregateVersion = "v1" +) + type Aggregate struct { eventstore.Aggregate SetUpStarted Step SetUpDone Step } + +func NewAggregate( + id, + resourceOwner string, + previousSequence uint64, +) *Aggregate { + + return &Aggregate{ + Aggregate: *eventstore.NewAggregate(id, AggregateType, resourceOwner, AggregateVersion, previousSequence), + } +} + +func AggregateFromReadModel(rm *ReadModel) *Aggregate { + return &Aggregate{ + Aggregate: *eventstore.NewAggregate(rm.AggregateID, AggregateType, rm.ResourceOwner, AggregateVersion, rm.ProcessedSequence), + SetUpDone: rm.SetUpDone, + SetUpStarted: rm.SetUpStarted, + } +} diff --git a/internal/v2/repository/iam/event_iam_project_set.go b/internal/v2/repository/iam/event_iam_project_set.go index 64478e90e7..f384baf27c 100644 --- a/internal/v2/repository/iam/event_iam_project_set.go +++ b/internal/v2/repository/iam/event_iam_project_set.go @@ -2,8 +2,11 @@ package iam import ( "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -33,3 +36,15 @@ func NewProjectSetEvent(ctx context.Context, projectID string) *ProjectSetEvent ProjectID: projectID, } } + +func ProjectSetMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &ProjectSetEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "IAM-cdFZH", "unable to unmarshal global org set") + } + + return e, nil +} diff --git a/internal/v2/repository/iam/event_iam_added.go b/internal/v2/repository/iam/event_org_set.go similarity index 57% rename from internal/v2/repository/iam/event_iam_added.go rename to internal/v2/repository/iam/event_org_set.go index 9047642d58..b6c89c2b09 100644 --- a/internal/v2/repository/iam/event_iam_added.go +++ b/internal/v2/repository/iam/event_org_set.go @@ -2,8 +2,11 @@ package iam import ( "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -33,3 +36,15 @@ func NewGlobalOrgSetEventEvent(ctx context.Context, orgID string) *GlobalOrgSetE OrgID: orgID, } } + +func GlobalOrgSetMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &GlobalOrgSetEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "IAM-cdFZH", "unable to unmarshal global org set") + } + + return e, nil +} diff --git a/internal/v2/repository/iam/events_step.go b/internal/v2/repository/iam/events_step.go index 02f4b8bec0..fcd42051a5 100644 --- a/internal/v2/repository/iam/events_step.go +++ b/internal/v2/repository/iam/events_step.go @@ -44,20 +44,30 @@ func SetupStepMapper(event *repository.Event) (eventstore.EventReader, error) { return step, nil } -func NewSetupStepDoneEvent(ctx context.Context) *SetupStepEvent { +func NewSetupStepDoneEvent( + ctx context.Context, + step Step, +) *SetupStepEvent { + return &SetupStepEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, SetupDoneEventType, ), + Step: step, } } -func NewSetupStepStartedEvent(ctx context.Context) *SetupStepEvent { +func NewSetupStepStartedEvent( + ctx context.Context, + step Step, +) *SetupStepEvent { + return &SetupStepEvent{ BaseEvent: *eventstore.NewBaseEventForPush( ctx, SetupStartedEventType, ), + Step: step, } } diff --git a/internal/v2/repository/iam/member.go b/internal/v2/repository/iam/member.go index 0a1cabe0a5..455c40b337 100644 --- a/internal/v2/repository/iam/member.go +++ b/internal/v2/repository/iam/member.go @@ -5,11 +5,6 @@ import ( "github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/v2/repository/member" - "github.com/caos/zitadel/internal/v2/repository/members" -) - -const ( - iamEventTypePrefix = eventstore.EventType("iam.") ) var ( @@ -18,24 +13,6 @@ var ( MemberRemovedEventType = iamEventTypePrefix + member.RemovedEventType ) -type MembersReadModel struct { - members.ReadModel -} - -func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { - for _, event := range events { - switch e := event.(type) { - case *MemberAddedEvent: - rm.ReadModel.AppendEvents(&e.AddedEvent) - case *MemberChangedEvent: - rm.ReadModel.AppendEvents(&e.ChangedEvent) - case *MemberRemovedEvent: - rm.ReadModel.AppendEvents(&e.RemovedEvent) - } - } - return nil -} - type MemberReadModel member.ReadModel func (rm *MemberReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { @@ -45,6 +22,8 @@ func (rm *MemberReadModel) AppendEvents(events ...eventstore.EventReader) (err e rm.ReadModel.AppendEvents(&e.AddedEvent) case *MemberChangedEvent: rm.ReadModel.AppendEvents(&e.ChangedEvent) + case *member.AddedEvent, *member.ChangedEvent, *MemberRemovedEvent: + rm.ReadModel.AppendEvents(e) } } return nil @@ -68,7 +47,7 @@ func NewMemberAddedEvent( ) *MemberAddedEvent { return &MemberAddedEvent{ - AddedEvent: *member.NewMemberAddedEvent( + AddedEvent: *member.NewAddedEvent( eventstore.NewBaseEventForPush( ctx, MemberAddedEventType, @@ -86,7 +65,7 @@ func NewMemberChangedEvent( ) *MemberChangedEvent { return &MemberChangedEvent{ - ChangedEvent: *member.NewMemberChangedEvent( + ChangedEvent: *member.NewChangedEvent( eventstore.NewBaseEventForPush( ctx, MemberChangedEventType, @@ -103,7 +82,7 @@ func NewMemberRemovedEvent( ) *MemberRemovedEvent { return &MemberRemovedEvent{ - RemovedEvent: *member.NewMemberRemovedEvent( + RemovedEvent: *member.NewRemovedEvent( eventstore.NewBaseEventForPush( ctx, MemberRemovedEventType, diff --git a/internal/v2/repository/iam/members.go b/internal/v2/repository/iam/members.go new file mode 100644 index 0000000000..fe9d6c6e00 --- /dev/null +++ b/internal/v2/repository/iam/members.go @@ -0,0 +1,27 @@ +package iam + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/member" + "github.com/caos/zitadel/internal/v2/repository/members" +) + +type MembersReadModel struct { + members.ReadModel +} + +func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *MemberAddedEvent: + rm.ReadModel.AppendEvents(&e.AddedEvent) + case *MemberChangedEvent: + rm.ReadModel.AppendEvents(&e.ChangedEvent) + case *MemberRemovedEvent: + rm.ReadModel.AppendEvents(&e.RemovedEvent) + case *member.AddedEvent, *member.ChangedEvent, *member.RemovedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} diff --git a/internal/v2/repository/iam/policy_label.go b/internal/v2/repository/iam/policy_label.go new file mode 100644 index 0000000000..42ae7c4fb3 --- /dev/null +++ b/internal/v2/repository/iam/policy_label.go @@ -0,0 +1,65 @@ +package iam + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + LabelPolicyAddedEventType = iamEventTypePrefix + policy.LabelPolicyAddedEventType + LabelPolicyChangedEventType = iamEventTypePrefix + policy.LabelPolicyChangedEventType +) + +type LabelPolicyReadModel struct{ policy.LabelPolicyReadModel } + +func (rm *LabelPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *LabelPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.LabelPolicyAddedEvent) + case *LabelPolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.LabelPolicyChangedEvent) + case *policy.LabelPolicyAddedEvent, *policy.LabelPolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type LabelPolicyAddedEvent struct { + policy.LabelPolicyAddedEvent +} + +type LabelPolicyChangedEvent struct { + policy.LabelPolicyChangedEvent +} + +// func NewLabelPolicyAddedEvent( +// ctx context.Context, +// primaryColor, +// secondaryColor string, +// ) *LabelPolicyAddedEvent { + +// return &LabelPolicyAddedEvent{ +// LabelPolicyAddedEvent: *policy.NewLabelPolicyAddedEvent( +// ctx, +// primaryColor, +// secondaryColor, +// ), +// } +// } + +// func NewLabelPolicyChangedEvent( +// ctx context.Context, +// primaryColor, +// secondaryColor string, +// ) *MemberChangedEvent { + +// return &LabelPolicyChangedEvent{ +// LabelPolicyChangedEvent: *policy.NewLabelPolicyChangedEvent( +// ctx, +// primaryColor, +// secondaryColor, +// ), +// } +// } diff --git a/internal/v2/repository/iam/policy_login.go b/internal/v2/repository/iam/policy_login.go new file mode 100644 index 0000000000..bfbcdb1881 --- /dev/null +++ b/internal/v2/repository/iam/policy_login.go @@ -0,0 +1,35 @@ +package iam + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + LoginPolicyAddedEventType = iamEventTypePrefix + policy.LoginPolicyAddedEventType + LoginPolicyChangedEventType = iamEventTypePrefix + policy.LoginPolicyChangedEventType +) + +type LoginPolicyReadModel struct{ policy.LoginPolicyReadModel } + +func (rm *LoginPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *LoginPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.LoginPolicyAddedEvent) + case *LoginPolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.LoginPolicyChangedEvent) + case *policy.LoginPolicyAddedEvent, *policy.LoginPolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type LoginPolicyAddedEvent struct { + policy.LoginPolicyAddedEvent +} + +type LoginPolicyChangedEvent struct { + policy.LoginPolicyChangedEvent +} diff --git a/internal/v2/repository/iam/policy_org_iam.go b/internal/v2/repository/iam/policy_org_iam.go new file mode 100644 index 0000000000..2db0950ebf --- /dev/null +++ b/internal/v2/repository/iam/policy_org_iam.go @@ -0,0 +1,28 @@ +package iam + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + OrgIAMPolicyAddedEventType = iamEventTypePrefix + policy.OrgIAMPolicyAddedEventType +) + +type OrgIAMPolicyReadModel struct{ policy.OrgIAMPolicyReadModel } + +func (rm *OrgIAMPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *OrgIAMPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.OrgIAMPolicyAddedEvent) + case *policy.OrgIAMPolicyAddedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type OrgIAMPolicyAddedEvent struct { + policy.OrgIAMPolicyAddedEvent +} diff --git a/internal/v2/repository/iam/policy_password_age.go b/internal/v2/repository/iam/policy_password_age.go new file mode 100644 index 0000000000..03d9ecab8a --- /dev/null +++ b/internal/v2/repository/iam/policy_password_age.go @@ -0,0 +1,37 @@ +package iam + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + PasswordAgePolicyAddedEventType = iamEventTypePrefix + policy.PasswordAgePolicyAddedEventType + PasswordAgePolicyChangedEventType = iamEventTypePrefix + policy.PasswordAgePolicyChangedEventType +) + +type PasswordAgePolicyReadModel struct { + policy.PasswordAgePolicyReadModel +} + +func (rm *PasswordAgePolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *PasswordAgePolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.PasswordAgePolicyAddedEvent) + case *PasswordAgePolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.PasswordAgePolicyChangedEvent) + case *policy.PasswordAgePolicyAddedEvent, *policy.PasswordAgePolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type PasswordAgePolicyAddedEvent struct { + policy.PasswordAgePolicyAddedEvent +} + +type PasswordAgePolicyChangedEvent struct { + policy.PasswordAgePolicyChangedEvent +} diff --git a/internal/v2/repository/iam/policy_password_complexity.go b/internal/v2/repository/iam/policy_password_complexity.go new file mode 100644 index 0000000000..ef8e9a9362 --- /dev/null +++ b/internal/v2/repository/iam/policy_password_complexity.go @@ -0,0 +1,37 @@ +package iam + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + PasswordComplexityPolicyAddedEventType = iamEventTypePrefix + policy.PasswordComplexityPolicyAddedEventType + PasswordComplexityPolicyChangedEventType = iamEventTypePrefix + policy.PasswordComplexityPolicyChangedEventType +) + +type PasswordComplexityPolicyReadModel struct { + policy.PasswordComplexityPolicyReadModel +} + +func (rm *PasswordComplexityPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *PasswordComplexityPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent) + case *PasswordComplexityPolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent) + case *policy.PasswordComplexityPolicyAddedEvent, *policy.PasswordComplexityPolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type PasswordComplexityPolicyAddedEvent struct { + policy.PasswordComplexityPolicyAddedEvent +} + +type PasswordComplexityPolicyChangedEvent struct { + policy.PasswordComplexityPolicyChangedEvent +} diff --git a/internal/v2/repository/iam/policy_password_lockout.go b/internal/v2/repository/iam/policy_password_lockout.go new file mode 100644 index 0000000000..17339e7d67 --- /dev/null +++ b/internal/v2/repository/iam/policy_password_lockout.go @@ -0,0 +1,37 @@ +package iam + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + PasswordLockoutPolicyAddedEventType = iamEventTypePrefix + policy.PasswordLockoutPolicyAddedEventType + PasswordLockoutPolicyChangedEventType = iamEventTypePrefix + policy.PasswordLockoutPolicyChangedEventType +) + +type PasswordLockoutPolicyReadModel struct { + policy.PasswordLockoutPolicyReadModel +} + +func (rm *PasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *PasswordLockoutPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent) + case *PasswordLockoutPolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent) + case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type PasswordLockoutPolicyAddedEvent struct { + policy.PasswordLockoutPolicyAddedEvent +} + +type PasswordLockoutPolicyChangedEvent struct { + policy.PasswordLockoutPolicyChangedEvent +} diff --git a/internal/v2/repository/iam/read_model.go b/internal/v2/repository/iam/read_model.go index ef1f6a24e6..66170822ce 100644 --- a/internal/v2/repository/iam/read_model.go +++ b/internal/v2/repository/iam/read_model.go @@ -17,12 +17,12 @@ type ReadModel struct { GlobalOrgID string ProjectID string - DefaultLoginPolicy policy.LoginPolicyReadModel - DefaultLabelPolicy policy.LabelPolicyReadModel - DefaultOrgIAMPolicy policy.OrgIAMPolicyReadModel - DefaultPasswordComplexityPolicy policy.PasswordComplexityPolicyReadModel - DefaultPasswordAgePolicy policy.PasswordAgePolicyReadModel - DefaultPasswordLockoutPolicy policy.PasswordLockoutPolicyReadModel + DefaultLoginPolicy LoginPolicyReadModel + DefaultLabelPolicy LabelPolicyReadModel + DefaultOrgIAMPolicy OrgIAMPolicyReadModel + DefaultPasswordComplexityPolicy PasswordComplexityPolicyReadModel + DefaultPasswordAgePolicy PasswordAgePolicyReadModel + DefaultPasswordLockoutPolicy PasswordLockoutPolicyReadModel } func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { @@ -64,7 +64,6 @@ func (rm *ReadModel) Reduce() (err error) { } } for _, reduce := range []func() error{ - rm.Members.Reduce, rm.Members.Reduce, rm.DefaultLoginPolicy.Reduce, rm.DefaultLabelPolicy.Reduce, @@ -81,3 +80,10 @@ func (rm *ReadModel) Reduce() (err error) { return nil } + +func (rm *ReadModel) AppendAndReduce(events ...eventstore.EventReader) error { + if err := rm.AppendEvents(events...); err != nil { + return err + } + return rm.Reduce() +} diff --git a/internal/v2/repository/member/aggregate.go b/internal/v2/repository/member/aggregate.go new file mode 100644 index 0000000000..e0f4c00fe6 --- /dev/null +++ b/internal/v2/repository/member/aggregate.go @@ -0,0 +1,16 @@ +package member + +import "github.com/caos/zitadel/internal/eventstore/v2" + +type Aggregate struct { + eventstore.Aggregate + + UserID string + Roles []string +} + +func NewMemberAggregate(userID string) *ReadModel { + return &ReadModel{ + ReadModel: *eventstore.NewReadModel(), + } +} diff --git a/internal/v2/repository/member/event_added.go b/internal/v2/repository/member/event_added.go index 6e29c77437..df65b7ed87 100644 --- a/internal/v2/repository/member/event_added.go +++ b/internal/v2/repository/member/event_added.go @@ -1,7 +1,11 @@ package member import ( + "encoding/json" + + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -23,7 +27,7 @@ func (e *AddedEvent) Data() interface{} { return e } -func NewMemberAddedEvent( +func NewAddedEvent( base *eventstore.BaseEvent, userID string, roles ...string, @@ -35,3 +39,16 @@ func NewMemberAddedEvent( UserID: userID, } } + +func AddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &AddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-puqv4", "unable to unmarshal label policy") + } + + return e, nil +} diff --git a/internal/v2/repository/member/event_changed.go b/internal/v2/repository/member/event_changed.go index 2c03e0fa0e..6c8acc6480 100644 --- a/internal/v2/repository/member/event_changed.go +++ b/internal/v2/repository/member/event_changed.go @@ -1,7 +1,11 @@ package member import ( + "encoding/json" + + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -23,7 +27,7 @@ func (e *ChangedEvent) Data() interface{} { return e } -func NewMemberChangedEvent( +func NewChangedEvent( base *eventstore.BaseEvent, userID string, roles ...string, @@ -35,3 +39,16 @@ func NewMemberChangedEvent( UserID: userID, } } + +func ChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &ChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-puqv4", "unable to unmarshal label policy") + } + + return e, nil +} diff --git a/internal/v2/repository/member/event_removed.go b/internal/v2/repository/member/event_removed.go index 087ecc3269..9f91a3d529 100644 --- a/internal/v2/repository/member/event_removed.go +++ b/internal/v2/repository/member/event_removed.go @@ -1,7 +1,11 @@ package member import ( + "encoding/json" + + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -22,7 +26,7 @@ func (e *RemovedEvent) Data() interface{} { return e } -func NewMemberRemovedEvent( +func NewRemovedEvent( base *eventstore.BaseEvent, userID string, ) *RemovedEvent { @@ -32,3 +36,16 @@ func NewMemberRemovedEvent( UserID: userID, } } + +func RemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &RemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-Ep4ip", "unable to unmarshal label policy") + } + + return e, nil +} diff --git a/internal/v2/repository/member/read_model.go b/internal/v2/repository/member/read_model.go index 5dc315dd92..b8d7609e82 100644 --- a/internal/v2/repository/member/read_model.go +++ b/internal/v2/repository/member/read_model.go @@ -12,6 +12,7 @@ type ReadModel struct { func NewMemberReadModel(userID string) *ReadModel { return &ReadModel{ ReadModel: *eventstore.NewReadModel(), + UserID: userID, } } diff --git a/internal/v2/repository/members/read_models.go b/internal/v2/repository/members/read_models.go index 7dfbddde53..90f3cc2c40 100644 --- a/internal/v2/repository/members/read_models.go +++ b/internal/v2/repository/members/read_models.go @@ -30,14 +30,14 @@ func (rm *ReadModel) MemberByUserID(id string) (idx int, member *member.ReadMode func (rm *ReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { for _, event := range events { switch e := event.(type) { - case *member.MemberAddedEvent: + case *member.AddedEvent: member := member.NewMemberReadModel(e.UserID) rm.Members = append(rm.Members, member) member.AppendEvents(e) - case *member.MemberChangedEvent: + case *member.ChangedEvent: _, member := rm.MemberByUserID(e.UserID) member.AppendEvents(e) - case *member.MemberRemovedEvent: + case *member.RemovedEvent: idx, _ := rm.MemberByUserID(e.UserID) if idx < 0 { return nil diff --git a/internal/v2/repository/org/member.go b/internal/v2/repository/org/member.go new file mode 100644 index 0000000000..88fe31e18d --- /dev/null +++ b/internal/v2/repository/org/member.go @@ -0,0 +1,114 @@ +package org + +import ( + "context" + + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/member" + "github.com/caos/zitadel/internal/v2/repository/members" +) + +const ( + orgEventTypePrefix = eventstore.EventType("org.") +) + +var ( + MemberAddedEventType = orgEventTypePrefix + member.AddedEventType + MemberChangedEventType = orgEventTypePrefix + member.ChangedEventType + MemberRemovedEventType = orgEventTypePrefix + member.RemovedEventType +) + +type MembersReadModel struct { + members.ReadModel +} + +func (rm *MembersReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *MemberAddedEvent: + rm.ReadModel.AppendEvents(&e.AddedEvent) + case *MemberChangedEvent: + rm.ReadModel.AppendEvents(&e.ChangedEvent) + case *MemberRemovedEvent: + rm.ReadModel.AppendEvents(&e.RemovedEvent) + } + } + return nil +} + +type MemberReadModel member.ReadModel + +func (rm *MemberReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *MemberAddedEvent: + rm.ReadModel.AppendEvents(&e.AddedEvent) + case *MemberChangedEvent: + rm.ReadModel.AppendEvents(&e.ChangedEvent) + } + } + return nil +} + +type MemberAddedEvent struct { + member.AddedEvent +} + +type MemberChangedEvent struct { + member.ChangedEvent +} +type MemberRemovedEvent struct { + member.RemovedEvent +} + +func NewMemberAddedEvent( + ctx context.Context, + userID string, + roles ...string, +) *MemberAddedEvent { + + return &MemberAddedEvent{ + AddedEvent: *member.NewAddedEvent( + eventstore.NewBaseEventForPush( + ctx, + MemberAddedEventType, + ), + userID, + roles..., + ), + } +} + +func NewMemberChangedEvent( + ctx context.Context, + userID string, + roles ...string, +) *MemberChangedEvent { + + return &MemberChangedEvent{ + ChangedEvent: *member.NewChangedEvent( + eventstore.NewBaseEventForPush( + ctx, + MemberChangedEventType, + ), + userID, + roles..., + ), + } +} + +func NewMemberRemovedEvent( + ctx context.Context, + userID string, +) *MemberRemovedEvent { + + return &MemberRemovedEvent{ + RemovedEvent: *member.NewRemovedEvent( + eventstore.NewBaseEventForPush( + ctx, + MemberRemovedEventType, + ), + userID, + ), + } +} diff --git a/internal/v2/repository/org/policy_label.go b/internal/v2/repository/org/policy_label.go new file mode 100644 index 0000000000..b751c346f5 --- /dev/null +++ b/internal/v2/repository/org/policy_label.go @@ -0,0 +1,65 @@ +package org + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + LabelPolicyAddedEventType = orgEventTypePrefix + policy.LabelPolicyAddedEventType + LabelPolicyChangedEventType = orgEventTypePrefix + policy.LabelPolicyChangedEventType +) + +type LabelPolicyReadModel struct{ policy.LabelPolicyReadModel } + +func (rm *LabelPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *LabelPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.LabelPolicyAddedEvent) + case *LabelPolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.LabelPolicyChangedEvent) + case *policy.LabelPolicyAddedEvent, *policy.LabelPolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type LabelPolicyAddedEvent struct { + policy.LabelPolicyAddedEvent +} + +type LabelPolicyChangedEvent struct { + policy.LabelPolicyChangedEvent +} + +// func NewLabelPolicyAddedEvent( +// ctx context.Context, +// primaryColor, +// secondaryColor string, +// ) *LabelPolicyAddedEvent { + +// return &LabelPolicyAddedEvent{ +// LabelPolicyAddedEvent: *policy.NewLabelPolicyAddedEvent( +// ctx, +// primaryColor, +// secondaryColor, +// ), +// } +// } + +// func NewLabelPolicyChangedEvent( +// ctx context.Context, +// primaryColor, +// secondaryColor string, +// ) *MemberChangedEvent { + +// return &LabelPolicyChangedEvent{ +// LabelPolicyChangedEvent: *policy.NewLabelPolicyChangedEvent( +// ctx, +// primaryColor, +// secondaryColor, +// ), +// } +// } diff --git a/internal/v2/repository/org/policy_login.go b/internal/v2/repository/org/policy_login.go new file mode 100644 index 0000000000..fb3b007641 --- /dev/null +++ b/internal/v2/repository/org/policy_login.go @@ -0,0 +1,35 @@ +package org + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + LoginPolicyAddedEventType = orgEventTypePrefix + policy.LoginPolicyAddedEventType + LoginPolicyChangedEventType = orgEventTypePrefix + policy.LoginPolicyChangedEventType +) + +type LoginPolicyReadModel struct{ policy.LoginPolicyReadModel } + +func (rm *LoginPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *LoginPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.LoginPolicyAddedEvent) + case *LoginPolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.LoginPolicyChangedEvent) + case *policy.LoginPolicyAddedEvent, *policy.LoginPolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type LoginPolicyAddedEvent struct { + policy.LoginPolicyAddedEvent +} + +type LoginPolicyChangedEvent struct { + policy.LoginPolicyChangedEvent +} diff --git a/internal/v2/repository/org/policy_org_iam.go b/internal/v2/repository/org/policy_org_iam.go new file mode 100644 index 0000000000..7dae966ec3 --- /dev/null +++ b/internal/v2/repository/org/policy_org_iam.go @@ -0,0 +1,28 @@ +package org + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + OrgIAMPolicyAddedEventType = orgEventTypePrefix + policy.OrgIAMPolicyAddedEventType +) + +type OrgIAMPolicyReadModel struct{ policy.OrgIAMPolicyReadModel } + +func (rm *OrgIAMPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *OrgIAMPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.OrgIAMPolicyAddedEvent) + case *policy.OrgIAMPolicyAddedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type OrgIAMPolicyAddedEvent struct { + policy.OrgIAMPolicyAddedEvent +} diff --git a/internal/v2/repository/org/policy_password_age.go b/internal/v2/repository/org/policy_password_age.go new file mode 100644 index 0000000000..c6c80d2155 --- /dev/null +++ b/internal/v2/repository/org/policy_password_age.go @@ -0,0 +1,37 @@ +package org + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + PasswordAgePolicyAddedEventType = orgEventTypePrefix + policy.PasswordAgePolicyAddedEventType + PasswordAgePolicyChangedEventType = orgEventTypePrefix + policy.PasswordAgePolicyChangedEventType +) + +type PasswordAgePolicyReadModel struct { + policy.PasswordAgePolicyReadModel +} + +func (rm *PasswordAgePolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *PasswordAgePolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.PasswordAgePolicyAddedEvent) + case *PasswordAgePolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.PasswordAgePolicyChangedEvent) + case *policy.PasswordAgePolicyAddedEvent, *policy.PasswordAgePolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type PasswordAgePolicyAddedEvent struct { + policy.PasswordAgePolicyAddedEvent +} + +type PasswordAgePolicyChangedEvent struct { + policy.PasswordAgePolicyChangedEvent +} diff --git a/internal/v2/repository/org/policy_password_complexity.go b/internal/v2/repository/org/policy_password_complexity.go new file mode 100644 index 0000000000..b3358cb45d --- /dev/null +++ b/internal/v2/repository/org/policy_password_complexity.go @@ -0,0 +1,37 @@ +package org + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + PasswordComplexityPolicyAddedEventType = orgEventTypePrefix + policy.PasswordComplexityPolicyAddedEventType + PasswordComplexityPolicyChangedEventType = orgEventTypePrefix + policy.PasswordComplexityPolicyChangedEventType +) + +type PasswordComplexityPolicyReadModel struct { + policy.PasswordComplexityPolicyReadModel +} + +func (rm *PasswordComplexityPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *PasswordComplexityPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.PasswordComplexityPolicyAddedEvent) + case *PasswordComplexityPolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.PasswordComplexityPolicyChangedEvent) + case *policy.PasswordComplexityPolicyAddedEvent, *policy.PasswordComplexityPolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type PasswordComplexityPolicyAddedEvent struct { + policy.PasswordComplexityPolicyAddedEvent +} + +type PasswordComplexityPolicyChangedEvent struct { + policy.PasswordComplexityPolicyChangedEvent +} diff --git a/internal/v2/repository/org/policy_password_lockout.go b/internal/v2/repository/org/policy_password_lockout.go new file mode 100644 index 0000000000..fcfd7f3631 --- /dev/null +++ b/internal/v2/repository/org/policy_password_lockout.go @@ -0,0 +1,37 @@ +package org + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/repository/policy" +) + +var ( + PasswordLockoutPolicyAddedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyAddedEventType + PasswordLockoutPolicyChangedEventType = orgEventTypePrefix + policy.PasswordLockoutPolicyChangedEventType +) + +type PasswordLockoutPolicyReadModel struct { + policy.PasswordLockoutPolicyReadModel +} + +func (rm *PasswordLockoutPolicyReadModel) AppendEvents(events ...eventstore.EventReader) (err error) { + for _, event := range events { + switch e := event.(type) { + case *PasswordLockoutPolicyAddedEvent: + rm.ReadModel.AppendEvents(&e.PasswordLockoutPolicyAddedEvent) + case *PasswordLockoutPolicyChangedEvent: + rm.ReadModel.AppendEvents(&e.PasswordLockoutPolicyChangedEvent) + case *policy.PasswordLockoutPolicyAddedEvent, *policy.PasswordLockoutPolicyChangedEvent: + rm.ReadModel.AppendEvents(e) + } + } + return nil +} + +type PasswordLockoutPolicyAddedEvent struct { + policy.PasswordLockoutPolicyAddedEvent +} + +type PasswordLockoutPolicyChangedEvent struct { + policy.PasswordLockoutPolicyChangedEvent +} diff --git a/internal/v2/repository/policy/label.go b/internal/v2/repository/policy/label.go index ace861dfb7..42b3ada6c0 100644 --- a/internal/v2/repository/policy/label.go +++ b/internal/v2/repository/policy/label.go @@ -2,8 +2,11 @@ package policy import ( "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -26,6 +29,20 @@ type LabelPolicyReadModel struct { SecondaryColor string } +func (rm *LabelPolicyReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *LabelPolicyAddedEvent: + rm.PrimaryColor = e.PrimaryColor + rm.SecondaryColor = e.SecondaryColor + case *LabelPolicyChangedEvent: + rm.PrimaryColor = e.PrimaryColor + rm.SecondaryColor = e.SecondaryColor + } + } + return rm.ReadModel.Reduce() +} + type LabelPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` @@ -57,6 +74,19 @@ func NewLabelPolicyAddedEvent( } } +func LabelPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &LabelPolicyAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-puqv4", "unable to unmarshal label policy") + } + + return e, nil +} + type LabelPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` @@ -94,6 +124,19 @@ func NewLabelPolicyChangedEvent( return e } +func LabelPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &LabelPolicyChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-qhfFb", "unable to unmarshal label policy") + } + + return e, nil +} + type LabelPolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } @@ -114,3 +157,9 @@ func NewLabelPolicyRemovedEvent(ctx context.Context) *LabelPolicyRemovedEvent { ), } } + +func LabelPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &LabelPolicyRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} diff --git a/internal/v2/repository/policy/login.go b/internal/v2/repository/policy/login.go index d0659ab58d..a2bfbdb6f4 100644 --- a/internal/v2/repository/policy/login.go +++ b/internal/v2/repository/policy/login.go @@ -2,8 +2,11 @@ package policy import ( "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -28,6 +31,22 @@ type LoginPolicyReadModel struct { AllowExternalIDP bool } +func (rm *LoginPolicyReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *LoginPolicyAddedEvent: + rm.AllowUserNamePassword = e.AllowUserNamePassword + rm.AllowExternalIDP = e.AllowExternalIDP + rm.AllowRegister = e.AllowRegister + case *LoginPolicyChangedEvent: + rm.AllowUserNamePassword = e.AllowUserNamePassword + rm.AllowExternalIDP = e.AllowExternalIDP + rm.AllowRegister = e.AllowRegister + } + } + return rm.ReadModel.Reduce() +} + type LoginPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` @@ -63,6 +82,19 @@ func NewLoginPolicyAddedEvent( } } +func LoginPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &LoginPolicyAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-nWndT", "unable to unmarshal policy") + } + + return e, nil +} + type LoginPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` @@ -105,6 +137,19 @@ func NewLoginPolicyChangedEvent( return e } +func LoginPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &LoginPolicyChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-ehssl", "unable to unmarshal policy") + } + + return e, nil +} + type LoginPolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } @@ -125,3 +170,9 @@ func NewLoginPolicyRemovedEvent(ctx context.Context) *LoginPolicyRemovedEvent { ), } } + +func LoginPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &LoginPolicyRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} diff --git a/internal/v2/repository/policy/org_iam.go b/internal/v2/repository/policy/org_iam.go index 9ad035e920..eaaccd0f2a 100644 --- a/internal/v2/repository/policy/org_iam.go +++ b/internal/v2/repository/policy/org_iam.go @@ -2,8 +2,11 @@ package policy import ( "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -22,6 +25,16 @@ type OrgIAMPolicyReadModel struct { UserLoginMustBeDomain bool } +func (rm *OrgIAMPolicyReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *OrgIAMPolicyAddedEvent: + rm.UserLoginMustBeDomain = e.UserLoginMustBeDomain + } + } + return rm.ReadModel.Reduce() +} + type OrgIAMPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` @@ -49,3 +62,16 @@ func NewOrgIAMPolicyAddedEvent( UserLoginMustBeDomain: userLoginMustBeDomain, } } + +func OrgIAMPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &OrgIAMPolicyAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-TvSmA", "unable to unmarshal policy") + } + + return e, nil +} diff --git a/internal/v2/repository/policy/password_age.go b/internal/v2/repository/policy/password_age.go index 889b9c3273..77a1adc4be 100644 --- a/internal/v2/repository/policy/password_age.go +++ b/internal/v2/repository/policy/password_age.go @@ -2,8 +2,11 @@ package policy import ( "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -15,22 +18,36 @@ const ( type PasswordAgePolicyAggregate struct { eventstore.Aggregate - ExpireWarnDays int - MaxAgeDays int + ExpireWarnDays uint16 + MaxAgeDays uint16 } type PasswordAgePolicyReadModel struct { eventstore.ReadModel - ExpireWarnDays int - MaxAgeDays int + ExpireWarnDays uint16 + MaxAgeDays uint16 +} + +func (rm *PasswordAgePolicyReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *PasswordAgePolicyAddedEvent: + rm.ExpireWarnDays = e.ExpireWarnDays + rm.MaxAgeDays = e.MaxAgeDays + case *PasswordAgePolicyChangedEvent: + rm.ExpireWarnDays = e.ExpireWarnDays + rm.MaxAgeDays = e.MaxAgeDays + } + } + return rm.ReadModel.Reduce() } type PasswordAgePolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` - ExpireWarnDays int `json:"expireWarnDays"` - MaxAgeDays int `json:"maxAgeDays"` + ExpireWarnDays uint16 `json:"expireWarnDays"` + MaxAgeDays uint16 `json:"maxAgeDays"` } func (e *PasswordAgePolicyAddedEvent) CheckPrevious() bool { @@ -44,7 +61,7 @@ func (e *PasswordAgePolicyAddedEvent) Data() interface{} { func NewPasswordAgePolicyAddedEvent( ctx context.Context, expireWarnDays, - maxAgeDays int, + maxAgeDays uint16, ) *PasswordAgePolicyAddedEvent { return &PasswordAgePolicyAddedEvent{ @@ -57,11 +74,24 @@ func NewPasswordAgePolicyAddedEvent( } } +func PasswordAgePolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordAgePolicyAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-T3mGp", "unable to unmarshal policy") + } + + return e, nil +} + type PasswordAgePolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` - ExpireWarnDays int `json:"expireWarnDays,omitempty"` - MaxAgeDays int `json:"maxAgeDays,omitempty"` + ExpireWarnDays uint16 `json:"expireWarnDays,omitempty"` + MaxAgeDays uint16 `json:"maxAgeDays,omitempty"` } func (e *PasswordAgePolicyChangedEvent) CheckPrevious() bool { @@ -95,6 +125,19 @@ func NewPasswordAgePolicyChangedEvent( return e } +func PasswordAgePolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordAgePolicyChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-PqaVq", "unable to unmarshal policy") + } + + return e, nil +} + type PasswordAgePolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } @@ -120,3 +163,16 @@ func NewPasswordAgePolicyRemovedEvent( ), } } + +func PasswordAgePolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordAgePolicyRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-02878", "unable to unmarshal policy") + } + + return e, nil +} diff --git a/internal/v2/repository/policy/password_complexity.go b/internal/v2/repository/policy/password_complexity.go index f9b4d45551..d00a1b32f0 100644 --- a/internal/v2/repository/policy/password_complexity.go +++ b/internal/v2/repository/policy/password_complexity.go @@ -2,8 +2,11 @@ package policy import ( "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -15,7 +18,7 @@ const ( type PasswordComplexityPolicyAggregate struct { eventstore.Aggregate - MinLength int + MinLength uint8 HasLowercase bool HasUpperCase bool HasNumber bool @@ -25,21 +28,41 @@ type PasswordComplexityPolicyAggregate struct { type PasswordComplexityPolicyReadModel struct { eventstore.ReadModel - MinLength int + MinLength uint8 HasLowercase bool HasUpperCase bool HasNumber bool HasSymbol bool } +func (rm *PasswordComplexityPolicyReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *PasswordComplexityPolicyAddedEvent: + rm.MinLength = e.MinLength + rm.HasLowercase = e.HasLowercase + rm.HasUpperCase = e.HasUpperCase + rm.HasNumber = e.HasNumber + rm.HasSymbol = e.HasSymbol + case *PasswordComplexityPolicyChangedEvent: + rm.MinLength = e.MinLength + rm.HasLowercase = e.HasLowercase + rm.HasUpperCase = e.HasUpperCase + rm.HasNumber = e.HasNumber + rm.HasSymbol = e.HasSymbol + } + } + return rm.ReadModel.Reduce() +} + type PasswordComplexityPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` - MinLength int `json:"minLength"` - HasLowercase bool `json:"hasLowercase"` - HasUpperCase bool `json:"hasUppercase"` - HasNumber bool `json:"hasNumber"` - HasSymbol bool `json:"hasSymbol"` + MinLength uint8 `json:"minLength"` + HasLowercase bool `json:"hasLowercase"` + HasUpperCase bool `json:"hasUppercase"` + HasNumber bool `json:"hasNumber"` + HasSymbol bool `json:"hasSymbol"` } func (e *PasswordComplexityPolicyAddedEvent) CheckPrevious() bool { @@ -56,7 +79,7 @@ func NewPasswordComplexityPolicyAddedEvent( hasUpperCase, hasNumber, hasSymbol bool, - minLength int, + minLength uint8, ) *PasswordComplexityPolicyAddedEvent { return &PasswordComplexityPolicyAddedEvent{ @@ -72,14 +95,27 @@ func NewPasswordComplexityPolicyAddedEvent( } } +func PasswordComplexityPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordComplexityPolicyAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-wYxlM", "unable to unmarshal policy") + } + + return e, nil +} + type PasswordComplexityPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` - MinLength int `json:"minLength"` - HasLowercase bool `json:"hasLowercase"` - HasUpperCase bool `json:"hasUppercase"` - HasNumber bool `json:"hasNumber"` - HasSymbol bool `json:"hasSymbol"` + MinLength uint8 `json:"minLength"` + HasLowercase bool `json:"hasLowercase"` + HasUpperCase bool `json:"hasUppercase"` + HasNumber bool `json:"hasNumber"` + HasSymbol bool `json:"hasSymbol"` } func (e *PasswordComplexityPolicyChangedEvent) CheckPrevious() bool { @@ -122,6 +158,19 @@ func NewPasswordComplexityPolicyChangedEvent( return e } +func PasswordComplexityPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordComplexityPolicyChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-zBGB0", "unable to unmarshal policy") + } + + return e, nil +} + type PasswordComplexityPolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } @@ -145,3 +194,9 @@ func NewPasswordComplexityPolicyRemovedEvent( ), } } + +func PasswordComplexityPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &PasswordComplexityPolicyRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +} diff --git a/internal/v2/repository/policy/password_lockout.go b/internal/v2/repository/policy/password_lockout.go index 94f601f1d2..6e5bc9e2a0 100644 --- a/internal/v2/repository/policy/password_lockout.go +++ b/internal/v2/repository/policy/password_lockout.go @@ -2,8 +2,11 @@ package policy import ( "context" + "encoding/json" + "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" ) const ( @@ -15,22 +18,36 @@ const ( type PasswordLockoutPolicyAggregate struct { eventstore.Aggregate - MaxAttempts int + MaxAttempts uint8 ShowLockOutFailures bool } type PasswordLockoutPolicyReadModel struct { eventstore.ReadModel - MaxAttempts int + MaxAttempts uint8 ShowLockOutFailures bool } +func (rm *PasswordLockoutPolicyReadModel) Reduce() error { + for _, event := range rm.Events { + switch e := event.(type) { + case *PasswordLockoutPolicyAddedEvent: + rm.MaxAttempts = e.MaxAttempts + rm.ShowLockOutFailures = e.ShowLockOutFailures + case *PasswordLockoutPolicyChangedEvent: + rm.MaxAttempts = e.MaxAttempts + rm.ShowLockOutFailures = e.ShowLockOutFailures + } + } + return rm.ReadModel.Reduce() +} + type PasswordLockoutPolicyAddedEvent struct { eventstore.BaseEvent `json:"-"` - MaxAttempts int `json:"maxAttempts"` - ShowLockOutFailures bool `json:"showLockOutFailures"` + MaxAttempts uint8 `json:"maxAttempts"` + ShowLockOutFailures bool `json:"showLockOutFailures"` } func (e *PasswordLockoutPolicyAddedEvent) CheckPrevious() bool { @@ -43,7 +60,7 @@ func (e *PasswordLockoutPolicyAddedEvent) Data() interface{} { func NewPasswordLockoutPolicyAddedEvent( ctx context.Context, - maxAttempts int, + maxAttempts uint8, showLockOutFailures bool, ) *PasswordLockoutPolicyAddedEvent { @@ -57,11 +74,24 @@ func NewPasswordLockoutPolicyAddedEvent( } } +func PasswordLockoutPolicyAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordLockoutPolicyAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-8XiVd", "unable to unmarshal policy") + } + + return e, nil +} + type PasswordLockoutPolicyChangedEvent struct { eventstore.BaseEvent `json:"-"` - MaxAttempts int `json:"maxAttempts,omitempty"` - ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"` + MaxAttempts uint8 `json:"maxAttempts,omitempty"` + ShowLockOutFailures bool `json:"showLockOutFailures,omitempty"` } func (e *PasswordLockoutPolicyChangedEvent) CheckPrevious() bool { @@ -95,6 +125,19 @@ func NewPasswordLockoutPolicyChangedEvent( return e } +func PasswordLockoutPolicyChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &PasswordLockoutPolicyChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "POLIC-lWGRc", "unable to unmarshal policy") + } + + return e, nil +} + type PasswordLockoutPolicyRemovedEvent struct { eventstore.BaseEvent `json:"-"` } @@ -118,3 +161,9 @@ func NewPasswordLockoutPolicyRemovedEvent( ), } } + +func PasswordLockoutPolicyRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + return &PasswordLockoutPolicyRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + }, nil +}