diff --git a/internal/admin/repository/eventsourcing/eventstore/iam.go b/internal/admin/repository/eventsourcing/eventstore/iam.go index 9e53490b14..d54fb22e4b 100644 --- a/internal/admin/repository/eventsourcing/eventstore/iam.go +++ b/internal/admin/repository/eventsourcing/eventstore/iam.go @@ -11,17 +11,9 @@ import ( admin_view "github.com/caos/zitadel/internal/admin/repository/eventsourcing/view" "github.com/caos/zitadel/internal/config/systemdefaults" - "github.com/caos/zitadel/internal/domain" v1 "github.com/caos/zitadel/internal/eventstore/v1" - "github.com/caos/zitadel/internal/eventstore/v1/models" "github.com/caos/zitadel/internal/i18n" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model" "github.com/caos/zitadel/internal/query" - "github.com/caos/zitadel/internal/telemetry/tracing" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/view/model" ) type IAMRepository struct { @@ -52,38 +44,6 @@ func (repo *IAMRepository) Languages(ctx context.Context) ([]language.Tag, error return repo.supportedLangs, nil } -func (repo *IAMRepository) IAMMemberByID(ctx context.Context, iamID, userID string) (*iam_model.IAMMemberView, error) { - member, err := repo.View.IAMMemberByIDs(iamID, userID) - if err != nil { - return nil, err - } - return iam_es_model.IAMMemberToModel(member, repo.PrefixAvatarURL), nil -} - -func (repo *IAMRepository) SearchIAMMembers(ctx context.Context, request *iam_model.IAMMemberSearchRequest) (*iam_model.IAMMemberSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - sequence, err := repo.View.GetLatestIAMMemberSequence() - logging.Log("EVENT-Slkci").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest iam sequence") - members, count, err := repo.View.SearchIAMMembers(request) - if err != nil { - return nil, err - } - result := &iam_model.IAMMemberSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: iam_es_model.IAMMembersToModel(members, repo.PrefixAvatarURL), - } - if err == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - func (repo *IAMRepository) GetIAMMemberRoles() []string { roles := make([]string, 0) for _, roleMap := range repo.Roles { @@ -93,99 +53,3 @@ func (repo *IAMRepository) GetIAMMemberRoles() []string { } return roles } - -func (repo *IAMRepository) IDPProvidersByIDPConfigID(ctx context.Context, idpConfigID string) ([]*iam_model.IDPProviderView, error) { - providers, err := repo.View.IDPProvidersByIdpConfigID(idpConfigID) - if err != nil { - return nil, err - } - return iam_es_model.IDPProviderViewsToModel(providers), nil -} - -func (repo *IAMRepository) ExternalIDPsByIDPConfigID(ctx context.Context, idpConfigID string) ([]*usr_model.ExternalIDPView, error) { - externalIDPs, err := repo.View.ExternalIDPsByIDPConfigID(idpConfigID) - if err != nil { - return nil, err - } - return model.ExternalIDPViewsToModel(externalIDPs), nil -} - -func (repo *IAMRepository) SearchIDPConfigs(ctx context.Context, request *iam_model.IDPConfigSearchRequest) (*iam_model.IDPConfigSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - sequence, err := repo.View.GetLatestIDPConfigSequence() - logging.Log("EVENT-Dk8si").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest idp config sequence") - idps, count, err := repo.View.SearchIDPConfigs(request) - if err != nil { - return nil, err - } - result := &iam_model.IDPConfigSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: iam_es_model.IdpConfigViewsToModel(idps), - } - if err == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - -func (repo *IAMRepository) SearchDefaultIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - request.AppendAggregateIDQuery(repo.SystemDefaults.IamID) - sequence, err := repo.View.GetLatestIDPProviderSequence() - logging.Log("EVENT-Tuiks").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Warn("could not read latest iam sequence") - providers, count, err := repo.View.SearchIDPProviders(request) - if err != nil { - return nil, err - } - result := &iam_model.IDPProviderSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: iam_es_model.IDPProviderViewsToModel(providers), - } - if err == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - -func (repo *IAMRepository) SearchIAMMembersx(ctx context.Context, request *iam_model.IAMMemberSearchRequest) (*iam_model.IAMMemberSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - sequence, err := repo.View.GetLatestIAMMemberSequence() - logging.Log("EVENT-Slkci").OnError(err).Warn("could not read latest iam sequence") - members, count, err := repo.View.SearchIAMMembers(request) - if err != nil { - return nil, err - } - result := &iam_model.IAMMemberSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: iam_es_model.IAMMembersToModel(members, repo.PrefixAvatarURL), - } - if err == nil { - result.Sequence = sequence.CurrentSequence - } - return result, nil -} - -func (repo *IAMRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, sequence) - if err != nil { - return nil, err - } - return repo.Eventstore.FilterEvents(ctx, query) -} diff --git a/internal/admin/repository/eventsourcing/handler/handler.go b/internal/admin/repository/eventsourcing/handler/handler.go index d4b2189767..4ed8edcb7a 100644 --- a/internal/admin/repository/eventsourcing/handler/handler.go +++ b/internal/admin/repository/eventsourcing/handler/handler.go @@ -33,19 +33,9 @@ func (h *handler) Eventstore() v1.Eventstore { func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, defaults systemdefaults.SystemDefaults, command *command.Commands, static static.Storage, localDevMode bool) []query.Handler { handlers := []query.Handler{ - newIAMMember( - handler{view, bulkLimit, configs.cycleDuration("IamMember"), errorCount, es}), - newIDPConfig( - handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount, es}), - newIDPProvider( - handler{view, bulkLimit, configs.cycleDuration("IDPProvider"), errorCount, es}, - defaults), newUser( handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es}, defaults), - newExternalIDP( - handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es}, - defaults), } if static != nil { handlers = append(handlers, newStyling( diff --git a/internal/admin/repository/eventsourcing/handler/iam_member.go b/internal/admin/repository/eventsourcing/handler/iam_member.go deleted file mode 100644 index 0dcce47b6d..0000000000 --- a/internal/admin/repository/eventsourcing/handler/iam_member.go +++ /dev/null @@ -1,289 +0,0 @@ -package handler - -import ( - "context" - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - org_model "github.com/caos/zitadel/internal/org/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - org_view "github.com/caos/zitadel/internal/org/repository/view" - "github.com/caos/zitadel/internal/user/repository/view" - view_model "github.com/caos/zitadel/internal/user/repository/view/model" - - "github.com/caos/logging" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" - usr_model "github.com/caos/zitadel/internal/user/model" - usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -const ( - iamMemberTable = "adminapi.iam_members" -) - -type IAMMember struct { - handler - subscription *v1.Subscription -} - -func newIAMMember(handler handler) *IAMMember { - iamMember := &IAMMember{ - handler: handler, - } - - iamMember.subscribe() - - return iamMember -} - -func (m *IAMMember) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (m *IAMMember) CurrentSequence() (uint64, error) { - sequence, err := m.view.GetLatestIAMMemberSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (m *IAMMember) ViewModel() string { - return iamMemberTable -} - -func (m *IAMMember) Subscription() *v1.Subscription { - return m.subscription -} - -func (m *IAMMember) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.IAMAggregate, usr_es_model.UserAggregate} -} - -func (m *IAMMember) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestIAMMemberSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(m.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (m *IAMMember) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.IAMAggregate: - err = m.processIAMMember(event) - case usr_es_model.UserAggregate: - err = m.processUser(event) - } - return err -} - -func (m *IAMMember) processIAMMember(event *es_models.Event) (err error) { - member := new(iam_view_model.IAMMemberView) - switch event.Type { - case model.IAMMemberAdded: - err = member.AppendEvent(event) - if err != nil { - return err - } - err = m.fillData(member) - case model.IAMMemberChanged: - err := member.SetData(event) - if err != nil { - return err - } - member, err = m.view.IAMMemberByIDs(event.AggregateID, member.UserID) - if err != nil { - return err - } - err = member.AppendEvent(event) - case model.IAMMemberRemoved, - model.IAMMemberCascadeRemoved: - err := member.SetData(event) - if err != nil { - return err - } - return m.view.DeleteIAMMember(event.AggregateID, member.UserID, event) - default: - return m.view.ProcessedIAMMemberSequence(event) - } - if err != nil { - return err - } - return m.view.PutIAMMember(member, event) -} - -func (m *IAMMember) processUser(event *es_models.Event) (err error) { - switch event.Type { - case usr_es_model.UserProfileChanged, - usr_es_model.UserEmailChanged, - usr_es_model.HumanProfileChanged, - usr_es_model.HumanEmailChanged, - usr_es_model.MachineChanged, - usr_es_model.HumanAvatarAdded, - usr_es_model.HumanAvatarRemoved: - members, err := m.view.IAMMembersByUserID(event.AggregateID) - if err != nil { - return err - } - if len(members) == 0 { - return m.view.ProcessedIAMMemberSequence(event) - } - user, err := m.getUserByID(event.AggregateID) - if err != nil { - return err - } - for _, member := range members { - m.fillUserData(member, user) - } - return m.view.PutIAMMembers(members, event) - case usr_es_model.UserRemoved: - return m.view.DeleteIAMMembersByUserID(event.AggregateID, event) - default: - return m.view.ProcessedIAMMemberSequence(event) - } -} - -func (m *IAMMember) fillData(member *iam_view_model.IAMMemberView) (err error) { - user, err := m.getUserByID(member.UserID) - if err != nil { - return err - } - return m.fillUserData(member, user) -} - -func (m *IAMMember) fillUserData(member *iam_view_model.IAMMemberView, user *view_model.UserView) error { - org, err := m.getOrgByID(context.Background(), user.ResourceOwner) - if err != nil { - return err - } - policy := org.OrgIamPolicy - if policy == nil { - policy, err = m.getDefaultOrgIAMPolicy(context.TODO()) - if err != nil { - return err - } - } - member.UserName = user.UserName - member.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain) - member.UserResourceOwner = user.ResourceOwner - if user.HumanView != nil { - member.FirstName = user.FirstName - member.LastName = user.LastName - member.DisplayName = user.FirstName + " " + user.LastName - member.Email = user.Email - member.AvatarKey = user.AvatarKey - } - if user.MachineView != nil { - member.DisplayName = user.MachineView.Name - } - return nil -} - -func (m *IAMMember) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-Ld9ow", "id", event.AggregateID).WithError(err).Warn("something went wrong in iammember handler") - return spooler.HandleError(event, err, m.view.GetLatestIAMMemberFailedEvent, m.view.ProcessedIAMMemberFailedEvent, m.view.ProcessedIAMMemberSequence, m.errorCountUntilSkip) -} - -func (m *IAMMember) OnSuccess() error { - return spooler.HandleSuccess(m.view.UpdateIAMMemberSpoolerRunTimestamp) -} - -func (m *IAMMember) getUserByID(userID string) (*view_model.UserView, error) { - user, usrErr := m.view.UserByID(userID) - if usrErr != nil && !caos_errs.IsNotFound(usrErr) { - return nil, usrErr - } - if user == nil { - user = &view_model.UserView{} - } - events, err := m.getUserEvents(userID, user.Sequence) - if err != nil { - return user, usrErr - } - userCopy := *user - for _, event := range events { - if err := userCopy.AppendEvent(event); err != nil { - return user, nil - } - } - if userCopy.State == int32(usr_model.UserStateDeleted) { - return nil, caos_errs.ThrowNotFound(nil, "HANDLER-4n9fs", "Errors.User.NotFound") - } - return &userCopy, nil -} - -func (m *IAMMember) getUserEvents(userID string, sequence uint64) ([]*es_models.Event, error) { - query, err := view.UserByIDQuery(userID, sequence) - if err != nil { - return nil, err - } - - return m.es.FilterEvents(context.Background(), query) -} - -func (u *IAMMember) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := org_view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-3nd7s", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *IAMMember) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) { - existingIAM, err := u.getIAMByID(ctx) - if err != nil { - return nil, err - } - if existingIAM.DefaultOrgIAMPolicy == nil { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-3Bf7s", "Errors.IAM.OrgIAMPolicy.NotExisting") - } - return existingIAM.DefaultOrgIAMPolicy, nil -} - -func (u *IAMMember) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &iam_es_model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} diff --git a/internal/admin/repository/eventsourcing/handler/idp_config.go b/internal/admin/repository/eventsourcing/handler/idp_config.go deleted file mode 100644 index f682d805a1..0000000000 --- a/internal/admin/repository/eventsourcing/handler/idp_config.go +++ /dev/null @@ -1,133 +0,0 @@ -package handler - -import ( - "github.com/caos/logging" - "github.com/caos/zitadel/internal/eventstore/v1" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" - "github.com/caos/zitadel/internal/repository/iam" -) - -const ( - idpConfigTable = "adminapi.idp_configs" -) - -type IDPConfig struct { - handler - subscription *v1.Subscription -} - -func newIDPConfig(handler handler) *IDPConfig { - h := &IDPConfig{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (i *IDPConfig) subscribe() { - i.subscription = i.es.Subscribe(i.AggregateTypes()...) - go func() { - for event := range i.subscription.Events { - query.ReduceEvent(i, event) - } - }() -} - -func (i *IDPConfig) Subscription() *v1.Subscription { - return i.subscription -} - -func (i *IDPConfig) ViewModel() string { - return idpConfigTable -} - -func (i *IDPConfig) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.IAMAggregate} -} - -func (i *IDPConfig) CurrentSequence() (uint64, error) { - sequence, err := i.view.GetLatestIDPConfigSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (i *IDPConfig) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := i.view.GetLatestIDPConfigSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(i.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (i *IDPConfig) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.IAMAggregate: - err = i.processIDPConfig(event) - } - return err -} - -func (i *IDPConfig) processIDPConfig(event *es_models.Event) (err error) { - idp := new(iam_view_model.IDPConfigView) - switch event.Type { - case model.IDPConfigAdded: - err = idp.AppendEvent(iam_model.IDPProviderTypeSystem, event) - case model.IDPConfigChanged, - model.OIDCIDPConfigAdded, - model.OIDCIDPConfigChanged, - es_models.EventType(iam.IDPJWTConfigAddedEventType), - es_models.EventType(iam.IDPJWTConfigChangedEventType): - err = idp.SetData(event) - if err != nil { - return err - } - idp, err = i.view.IDPConfigByID(idp.IDPConfigID) - if err != nil { - return err - } - err = idp.AppendEvent(iam_model.IDPProviderTypeSystem, event) - case model.IDPConfigDeactivated, - model.IDPConfigReactivated: - err = idp.SetData(event) - if err != nil { - return err - } - idp, err = i.view.IDPConfigByID(idp.IDPConfigID) - if err != nil { - return err - } - err = idp.AppendEvent(iam_model.IDPProviderTypeSystem, event) - case model.IDPConfigRemoved: - err = idp.SetData(event) - if err != nil { - return err - } - return i.view.DeleteIDPConfig(idp.IDPConfigID, event) - default: - return i.view.ProcessedIDPConfigSequence(event) - } - if err != nil { - return err - } - return i.view.PutIDPConfig(idp, event) -} - -func (i *IDPConfig) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-Mslo9", "id", event.AggregateID).WithError(err).Warn("something went wrong in idp config handler") - return spooler.HandleError(event, err, i.view.GetLatestIDPConfigFailedEvent, i.view.ProcessedIDPConfigFailedEvent, i.view.ProcessedIDPConfigSequence, i.errorCountUntilSkip) -} - -func (i *IDPConfig) OnSuccess() error { - return spooler.HandleSuccess(i.view.UpdateIDPConfigSpoolerRunTimestamp) -} diff --git a/internal/admin/repository/eventsourcing/handler/idp_providers.go b/internal/admin/repository/eventsourcing/handler/idp_providers.go deleted file mode 100644 index 2cfd435a38..0000000000 --- a/internal/admin/repository/eventsourcing/handler/idp_providers.go +++ /dev/null @@ -1,228 +0,0 @@ -package handler - -import ( - "context" - "github.com/caos/zitadel/internal/domain" - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - org_model "github.com/caos/zitadel/internal/org/model" - "github.com/caos/zitadel/internal/org/repository/view" - - "github.com/caos/logging" - "github.com/caos/zitadel/internal/config/systemdefaults" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -const ( - idpProviderTable = "adminapi.idp_providers" -) - -type IDPProvider struct { - handler - systemDefaults systemdefaults.SystemDefaults - subscription *v1.Subscription -} - -func newIDPProvider( - handler handler, - systemDefaults systemdefaults.SystemDefaults, -) *IDPProvider { - h := &IDPProvider{ - handler: handler, - systemDefaults: systemDefaults, - } - - h.subscribe() - - return h -} - -func (i *IDPProvider) subscribe() { - i.subscription = i.es.Subscribe(i.AggregateTypes()...) - go func() { - for event := range i.subscription.Events { - query.ReduceEvent(i, event) - } - }() -} - -func (i *IDPProvider) Subscription() *v1.Subscription { - return i.subscription -} - -func (i *IDPProvider) ViewModel() string { - return idpProviderTable -} - -func (i *IDPProvider) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.IAMAggregate, org_es_model.OrgAggregate} -} - -func (i *IDPProvider) CurrentSequence() (uint64, error) { - sequence, err := i.view.GetLatestIDPProviderSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (i *IDPProvider) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := i.view.GetLatestIDPProviderSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(i.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (i *IDPProvider) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.IAMAggregate, org_es_model.OrgAggregate: - err = i.processIdpProvider(event) - } - return err -} - -func (i *IDPProvider) processIdpProvider(event *es_models.Event) (err error) { - provider := new(iam_view_model.IDPProviderView) - switch event.Type { - case model.LoginPolicyIDPProviderAdded, org_es_model.LoginPolicyIDPProviderAdded: - err = provider.AppendEvent(event) - if err != nil { - return err - } - err = i.fillData(provider) - case model.LoginPolicyIDPProviderRemoved, model.LoginPolicyIDPProviderCascadeRemoved, - org_es_model.LoginPolicyIDPProviderRemoved, org_es_model.LoginPolicyIDPProviderCascadeRemoved: - err = provider.SetData(event) - if err != nil { - return err - } - return i.view.DeleteIDPProvider(event.AggregateID, provider.IDPConfigID, event) - case model.IDPConfigChanged, org_es_model.IDPConfigChanged: - esConfig := new(iam_view_model.IDPConfigView) - providerType := iam_model.IDPProviderTypeSystem - if event.AggregateID != i.systemDefaults.IamID { - providerType = iam_model.IDPProviderTypeOrg - } - esConfig.AppendEvent(providerType, event) - providers, err := i.view.IDPProvidersByIdpConfigID(esConfig.IDPConfigID) - if err != nil { - return err - } - config, err := i.getDefaultIDPConfig(context.Background(), esConfig.IDPConfigID) - if err != nil { - return err - } - for _, provider := range providers { - i.fillConfigData(provider, config) - } - return i.view.PutIDPProviders(event, providers...) - default: - return i.view.ProcessedIDPProviderSequence(event) - } - if err != nil { - return err - } - return i.view.PutIDPProvider(provider, event) -} - -func (i *IDPProvider) fillData(provider *iam_view_model.IDPProviderView) (err error) { - var config *iam_model.IDPConfig - if provider.IDPProviderType == int32(iam_model.IDPProviderTypeSystem) { - config, err = i.getDefaultIDPConfig(context.Background(), provider.IDPConfigID) - } else { - config, err = i.getOrgIDPConfig(context.Background(), provider.AggregateID, provider.IDPConfigID) - } - if err != nil { - return err - } - i.fillConfigData(provider, config) - return nil -} - -func (i *IDPProvider) fillConfigData(provider *iam_view_model.IDPProviderView, config *iam_model.IDPConfig) { - provider.Name = config.Name - provider.StylingType = int32(config.StylingType) - provider.IDPConfigType = int32(config.Type) - provider.IDPState = int32(config.State) -} - -func (i *IDPProvider) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-Msj8c", "id", event.AggregateID).WithError(err).Warn("something went wrong in idp provider handler") - return spooler.HandleError(event, err, i.view.GetLatestIDPProviderFailedEvent, i.view.ProcessedIDPProviderFailedEvent, i.view.ProcessedIDPProviderSequence, i.errorCountUntilSkip) -} - -func (i *IDPProvider) OnSuccess() error { - return spooler.HandleSuccess(i.view.UpdateIDPProviderSpoolerRunTimestamp) -} - -func (i *IDPProvider) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) { - existing, err := i.getOrgByID(ctx, aggregateID) - if err != nil { - return nil, err - } - if _, i := existing.GetIDP(idpConfigID); i != nil { - return i, nil - } - return nil, errors.ThrowNotFound(nil, "EVENT-4m0fs", "Errors.IDP.NotExisting") -} - -func (i *IDPProvider) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !errors.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, errors.ThrowNotFound(nil, "EVENT-4m9gs", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *IDPProvider) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && errors.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return model.IAMToModel(iam), nil -} - -func (u *IDPProvider) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) { - existing, err := u.getIAMByID(ctx) - if err != nil { - return nil, err - } - if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil { - return existingIDP, nil - } - return nil, errors.ThrowNotFound(nil, "EVENT-4M=Fs", "Errors.IDP.NotExisting") -} diff --git a/internal/admin/repository/eventsourcing/handler/user_external_idps.go b/internal/admin/repository/eventsourcing/handler/user_external_idps.go deleted file mode 100644 index d4331a88ef..0000000000 --- a/internal/admin/repository/eventsourcing/handler/user_external_idps.go +++ /dev/null @@ -1,240 +0,0 @@ -package handler - -import ( - "context" - - "github.com/caos/logging" - "github.com/caos/zitadel/internal/config/systemdefaults" - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - v1 "github.com/caos/zitadel/internal/eventstore/v1" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" - org_model "github.com/caos/zitadel/internal/org/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/view" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model" -) - -const ( - externalIDPTable = "adminapi.user_external_idps" -) - -type ExternalIDP struct { - handler - systemDefaults systemdefaults.SystemDefaults - subscription *v1.Subscription -} - -func newExternalIDP( - handler handler, - systemDefaults systemdefaults.SystemDefaults, -) *ExternalIDP { - h := &ExternalIDP{ - handler: handler, - systemDefaults: systemDefaults, - } - - h.subscribe() - - return h -} - -func (i *ExternalIDP) subscribe() { - i.subscription = i.es.Subscribe(i.AggregateTypes()...) - go func() { - for event := range i.subscription.Events { - query.ReduceEvent(i, event) - } - }() -} - -func (i *ExternalIDP) ViewModel() string { - return externalIDPTable -} - -func (i *ExternalIDP) Subscription() *v1.Subscription { - return i.subscription -} - -func (i *ExternalIDP) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.UserAggregate, iam_es_model.IAMAggregate, org_es_model.OrgAggregate} -} - -func (i *ExternalIDP) CurrentSequence() (uint64, error) { - sequence, err := i.view.GetLatestExternalIDPSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (i *ExternalIDP) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := i.view.GetLatestExternalIDPSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(i.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (i *ExternalIDP) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.UserAggregate: - err = i.processUser(event) - case iam_es_model.IAMAggregate, org_es_model.OrgAggregate: - err = i.processIdpConfig(event) - } - return err -} - -func (i *ExternalIDP) processUser(event *es_models.Event) (err error) { - externalIDP := new(usr_view_model.ExternalIDPView) - switch event.Type { - case model.HumanExternalIDPAdded: - err = externalIDP.AppendEvent(event) - if err != nil { - return err - } - err = i.fillData(externalIDP) - case model.HumanExternalIDPRemoved, model.HumanExternalIDPCascadeRemoved: - err = externalIDP.SetData(event) - if err != nil { - return err - } - return i.view.DeleteExternalIDP(externalIDP.ExternalUserID, externalIDP.IDPConfigID, event) - case model.UserRemoved: - return i.view.DeleteExternalIDPsByUserID(event.AggregateID, event) - default: - return i.view.ProcessedExternalIDPSequence(event) - } - if err != nil { - return err - } - return i.view.PutExternalIDP(externalIDP, event) -} - -func (i *ExternalIDP) processIdpConfig(event *es_models.Event) (err error) { - switch event.Type { - case iam_es_model.IDPConfigChanged, org_es_model.IDPConfigChanged: - configView := new(iam_view_model.IDPConfigView) - config := new(iam_model.IDPConfig) - if event.Type == iam_es_model.IDPConfigChanged { - configView.AppendEvent(iam_model.IDPProviderTypeSystem, event) - } else { - configView.AppendEvent(iam_model.IDPProviderTypeOrg, event) - } - exterinalIDPs, err := i.view.ExternalIDPsByIDPConfigID(configView.IDPConfigID) - if err != nil { - return err - } - if event.AggregateType == iam_es_model.IAMAggregate { - config, err = i.getDefaultIDPConfig(context.Background(), configView.IDPConfigID) - } else { - config, err = i.getOrgIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID) - } - if err != nil { - return err - } - for _, provider := range exterinalIDPs { - i.fillConfigData(provider, config) - } - return i.view.PutExternalIDPs(event, exterinalIDPs...) - default: - return i.view.ProcessedExternalIDPSequence(event) - } -} - -func (i *ExternalIDP) fillData(externalIDP *usr_view_model.ExternalIDPView) error { - config, err := i.getOrgIDPConfig(context.Background(), externalIDP.ResourceOwner, externalIDP.IDPConfigID) - if caos_errs.IsNotFound(err) { - config, err = i.getDefaultIDPConfig(context.Background(), externalIDP.IDPConfigID) - } - if err != nil { - return err - } - i.fillConfigData(externalIDP, config) - return nil -} - -func (i *ExternalIDP) fillConfigData(externalIDP *usr_view_model.ExternalIDPView, config *iam_model.IDPConfig) { - externalIDP.IDPName = config.Name -} - -func (i *ExternalIDP) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-4Rsu8", "id", event.AggregateID).WithError(err).Warn("something went wrong in idp provider handler") - return spooler.HandleError(event, err, i.view.GetLatestExternalIDPFailedEvent, i.view.ProcessedExternalIDPFailedEvent, i.view.ProcessedExternalIDPSequence, i.errorCountUntilSkip) -} - -func (i *ExternalIDP) OnSuccess() error { - return spooler.HandleSuccess(i.view.UpdateExternalIDPSpoolerRunTimestamp) -} - -func (i *ExternalIDP) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) { - existing, err := i.getOrgByID(ctx, aggregateID) - if err != nil { - return nil, err - } - if _, i := existing.GetIDP(idpConfigID); i != nil { - return i, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-2n8Fh", "Errors.IDP.NotExisting") -} - -func (i *ExternalIDP) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-MOFMs", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *ExternalIDP) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &iam_es_model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (u *ExternalIDP) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) { - existing, err := u.getIAMByID(ctx) - if err != nil { - return nil, err - } - if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil { - return existingIDP, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-49O0f", "Errors.IDP.NotExisting") -} diff --git a/internal/admin/repository/eventsourcing/view/external_idps.go b/internal/admin/repository/eventsourcing/view/external_idps.go deleted file mode 100644 index d4cffd2557..0000000000 --- a/internal/admin/repository/eventsourcing/view/external_idps.go +++ /dev/null @@ -1,90 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/view" - "github.com/caos/zitadel/internal/user/repository/view/model" - global_view "github.com/caos/zitadel/internal/view/repository" -) - -const ( - externalIDPTable = "adminapi.user_external_idps" -) - -func (v *View) ExternalIDPByExternalUserIDAndIDPConfigID(externalUserID, idpConfigID string) (*model.ExternalIDPView, error) { - return view.ExternalIDPByExternalUserIDAndIDPConfigID(v.Db, externalIDPTable, externalUserID, idpConfigID) -} - -func (v *View) ExternalIDPByExternalUserIDAndIDPConfigIDAndResourceOwner(externalUserID, idpConfigID, resourceOwner string) (*model.ExternalIDPView, error) { - return view.ExternalIDPByExternalUserIDAndIDPConfigIDAndResourceOwner(v.Db, externalIDPTable, externalUserID, idpConfigID, resourceOwner) -} - -func (v *View) ExternalIDPsByIDPConfigID(idpConfigID string) ([]*model.ExternalIDPView, error) { - return view.ExternalIDPsByIDPConfigID(v.Db, externalIDPTable, idpConfigID) -} - -func (v *View) ExternalIDPsByIDPConfigIDAndResourceOwners(idpConfigID string, resourceOwners []string) ([]*model.ExternalIDPView, error) { - return view.ExternalIDPsByIDPConfigIDAndResourceOwners(v.Db, externalIDPTable, idpConfigID, resourceOwners) -} - -func (v *View) ExternalIDPsByUserID(userID string) ([]*model.ExternalIDPView, error) { - return view.ExternalIDPsByUserID(v.Db, externalIDPTable, userID) -} - -func (v *View) SearchExternalIDPs(request *usr_model.ExternalIDPSearchRequest) ([]*model.ExternalIDPView, uint64, error) { - return view.SearchExternalIDPs(v.Db, externalIDPTable, request) -} - -func (v *View) PutExternalIDP(externalIDP *model.ExternalIDPView, event *models.Event) error { - err := view.PutExternalIDP(v.Db, externalIDPTable, externalIDP) - if err != nil { - return err - } - return v.ProcessedExternalIDPSequence(event) -} - -func (v *View) PutExternalIDPs(event *models.Event, externalIDPs ...*model.ExternalIDPView) error { - err := view.PutExternalIDPs(v.Db, externalIDPTable, externalIDPs...) - if err != nil { - return err - } - return v.ProcessedExternalIDPSequence(event) -} - -func (v *View) DeleteExternalIDP(externalUserID, idpConfigID string, event *models.Event) error { - err := view.DeleteExternalIDP(v.Db, externalIDPTable, externalUserID, idpConfigID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedExternalIDPSequence(event) -} - -func (v *View) DeleteExternalIDPsByUserID(userID string, event *models.Event) error { - err := view.DeleteExternalIDPsByUserID(v.Db, externalIDPTable, userID) - if err != nil { - return err - } - return v.ProcessedExternalIDPSequence(event) -} - -func (v *View) GetLatestExternalIDPSequence() (*global_view.CurrentSequence, error) { - return v.latestSequence(externalIDPTable) -} - -func (v *View) ProcessedExternalIDPSequence(event *models.Event) error { - return v.saveCurrentSequence(externalIDPTable, event) -} - -func (v *View) UpdateExternalIDPSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(externalIDPTable) -} - -func (v *View) GetLatestExternalIDPFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { - return v.latestFailedEvent(externalIDPTable, sequence) -} - -func (v *View) ProcessedExternalIDPFailedEvent(failedEvent *global_view.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/admin/repository/eventsourcing/view/iam_member.go b/internal/admin/repository/eventsourcing/view/iam_member.go deleted file mode 100644 index 2bd4e2fa7e..0000000000 --- a/internal/admin/repository/eventsourcing/view/iam_member.go +++ /dev/null @@ -1,78 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/view" - "github.com/caos/zitadel/internal/iam/repository/view/model" - global_view "github.com/caos/zitadel/internal/view/repository" -) - -const ( - iamMemberTable = "adminapi.iam_members" -) - -func (v *View) IAMMemberByIDs(orgID, userID string) (*model.IAMMemberView, error) { - return view.IAMMemberByIDs(v.Db, iamMemberTable, orgID, userID) -} - -func (v *View) SearchIAMMembers(request *iam_model.IAMMemberSearchRequest) ([]*model.IAMMemberView, uint64, error) { - return view.SearchIAMMembers(v.Db, iamMemberTable, request) -} - -func (v *View) IAMMembersByUserID(userID string) ([]*model.IAMMemberView, error) { - return view.IAMMembersByUserID(v.Db, iamMemberTable, userID) -} - -func (v *View) PutIAMMember(org *model.IAMMemberView, event *models.Event) error { - err := view.PutIAMMember(v.Db, iamMemberTable, org) - if err != nil { - return err - } - return v.ProcessedIAMMemberSequence(event) -} - -func (v *View) PutIAMMembers(members []*model.IAMMemberView, event *models.Event) error { - err := view.PutIAMMembers(v.Db, iamMemberTable, members...) - if err != nil { - return err - } - return v.ProcessedIAMMemberSequence(event) -} - -func (v *View) DeleteIAMMember(iamID, userID string, event *models.Event) error { - err := view.DeleteIAMMember(v.Db, iamMemberTable, iamID, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedIAMMemberSequence(event) -} - -func (v *View) DeleteIAMMembersByUserID(userID string, event *models.Event) error { - err := view.DeleteIAMMembersByUserID(v.Db, iamMemberTable, userID) - if err != nil { - return err - } - return v.ProcessedIAMMemberSequence(event) -} - -func (v *View) GetLatestIAMMemberSequence() (*global_view.CurrentSequence, error) { - return v.latestSequence(iamMemberTable) -} - -func (v *View) ProcessedIAMMemberSequence(event *models.Event) error { - return v.saveCurrentSequence(iamMemberTable, event) -} - -func (v *View) UpdateIAMMemberSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(iamMemberTable) -} - -func (v *View) GetLatestIAMMemberFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { - return v.latestFailedEvent(iamMemberTable, sequence) -} - -func (v *View) ProcessedIAMMemberFailedEvent(failedEvent *global_view.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/admin/repository/eventsourcing/view/idp_configs.go b/internal/admin/repository/eventsourcing/view/idp_configs.go deleted file mode 100644 index 785f080546..0000000000 --- a/internal/admin/repository/eventsourcing/view/idp_configs.go +++ /dev/null @@ -1,58 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/view" - "github.com/caos/zitadel/internal/iam/repository/view/model" - global_view "github.com/caos/zitadel/internal/view/repository" -) - -const ( - idpConfigTable = "adminapi.idp_configs" -) - -func (v *View) IDPConfigByID(idpID string) (*model.IDPConfigView, error) { - return view.IDPByID(v.Db, idpConfigTable, idpID) -} - -func (v *View) SearchIDPConfigs(request *iam_model.IDPConfigSearchRequest) ([]*model.IDPConfigView, uint64, error) { - return view.SearchIDPs(v.Db, idpConfigTable, request) -} - -func (v *View) PutIDPConfig(idp *model.IDPConfigView, event *models.Event) error { - err := view.PutIDP(v.Db, idpConfigTable, idp) - if err != nil { - return err - } - return v.ProcessedIDPConfigSequence(event) -} - -func (v *View) DeleteIDPConfig(idpID string, event *models.Event) error { - err := view.DeleteIDP(v.Db, idpConfigTable, idpID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedIDPConfigSequence(event) -} - -func (v *View) GetLatestIDPConfigSequence() (*global_view.CurrentSequence, error) { - return v.latestSequence(idpConfigTable) -} - -func (v *View) ProcessedIDPConfigSequence(event *models.Event) error { - return v.saveCurrentSequence(idpConfigTable, event) -} - -func (v *View) UpdateIDPConfigSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(idpConfigTable) -} - -func (v *View) GetLatestIDPConfigFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { - return v.latestFailedEvent(idpConfigTable, sequence) -} - -func (v *View) ProcessedIDPConfigFailedEvent(failedEvent *global_view.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/admin/repository/eventsourcing/view/idp_providers.go b/internal/admin/repository/eventsourcing/view/idp_providers.go deleted file mode 100644 index 2739ef9afe..0000000000 --- a/internal/admin/repository/eventsourcing/view/idp_providers.go +++ /dev/null @@ -1,70 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/view" - "github.com/caos/zitadel/internal/iam/repository/view/model" - global_view "github.com/caos/zitadel/internal/view/repository" -) - -const ( - idpProviderTable = "adminapi.idp_providers" -) - -func (v *View) IDPProviderByAggregateAndIdpConfigID(aggregateID, idpConfigID string) (*model.IDPProviderView, error) { - return view.GetIDPProviderByAggregateIDAndConfigID(v.Db, idpProviderTable, aggregateID, idpConfigID) -} - -func (v *View) IDPProvidersByIdpConfigID(idpConfigID string) ([]*model.IDPProviderView, error) { - return view.IDPProvidersByIdpConfigID(v.Db, idpProviderTable, idpConfigID) -} - -func (v *View) SearchIDPProviders(request *iam_model.IDPProviderSearchRequest) ([]*model.IDPProviderView, uint64, error) { - return view.SearchIDPProviders(v.Db, idpProviderTable, request) -} - -func (v *View) PutIDPProvider(provider *model.IDPProviderView, event *models.Event) error { - err := view.PutIDPProvider(v.Db, idpProviderTable, provider) - if err != nil { - return err - } - return v.ProcessedIDPProviderSequence(event) -} - -func (v *View) PutIDPProviders(event *models.Event, providers ...*model.IDPProviderView) error { - err := view.PutIDPProviders(v.Db, idpProviderTable, providers...) - if err != nil { - return err - } - return v.ProcessedIDPProviderSequence(event) -} - -func (v *View) DeleteIDPProvider(aggregateID, idpConfigID string, event *models.Event) error { - err := view.DeleteIDPProvider(v.Db, idpProviderTable, aggregateID, idpConfigID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedIDPProviderSequence(event) -} - -func (v *View) GetLatestIDPProviderSequence() (*global_view.CurrentSequence, error) { - return v.latestSequence(idpProviderTable) -} - -func (v *View) ProcessedIDPProviderSequence(event *models.Event) error { - return v.saveCurrentSequence(idpProviderTable, event) -} - -func (v *View) UpdateIDPProviderSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(idpProviderTable) -} - -func (v *View) GetLatestIDPProviderFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { - return v.latestFailedEvent(idpProviderTable, sequence) -} - -func (v *View) ProcessedIDPProviderFailedEvent(failedEvent *global_view.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/admin/repository/iam.go b/internal/admin/repository/iam.go index bfa1a33969..8a78f49fc4 100644 --- a/internal/admin/repository/iam.go +++ b/internal/admin/repository/iam.go @@ -4,23 +4,10 @@ import ( "context" "golang.org/x/text/language" - - usr_model "github.com/caos/zitadel/internal/user/model" - - iam_model "github.com/caos/zitadel/internal/iam/model" ) type IAMRepository interface { Languages(ctx context.Context) ([]language.Tag, error) - SearchIAMMembers(ctx context.Context, request *iam_model.IAMMemberSearchRequest) (*iam_model.IAMMemberSearchResponse, error) - GetIAMMemberRoles() []string - - SearchIDPConfigs(ctx context.Context, request *iam_model.IDPConfigSearchRequest) (*iam_model.IDPConfigSearchResponse, error) - - SearchDefaultIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) - - IDPProvidersByIDPConfigID(ctx context.Context, idpConfigID string) ([]*iam_model.IDPProviderView, error) - ExternalIDPsByIDPConfigID(ctx context.Context, idpConfigID string) ([]*usr_model.ExternalIDPView, error) } diff --git a/internal/api/grpc/admin/idp.go b/internal/api/grpc/admin/idp.go index 74d4b96258..41ab8893e7 100644 --- a/internal/api/grpc/admin/idp.go +++ b/internal/api/grpc/admin/idp.go @@ -6,6 +6,7 @@ import ( idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp" object_pb "github.com/caos/zitadel/internal/api/grpc/object" "github.com/caos/zitadel/internal/domain" + "github.com/caos/zitadel/internal/query" admin_pb "github.com/caos/zitadel/pkg/grpc/admin" ) @@ -22,7 +23,7 @@ func (s *Server) ListIDPs(ctx context.Context, req *admin_pb.ListIDPsRequest) (* if err != nil { return nil, err } - resp, err := s.query.SearchIDPs(ctx, domain.IAMID, queries) + resp, err := s.query.IDPs(ctx, queries) if err != nil { return nil, err } @@ -93,15 +94,29 @@ func (s *Server) ReactivateIDP(ctx context.Context, req *admin_pb.ReactivateIDPR } func (s *Server) RemoveIDP(ctx context.Context, req *admin_pb.RemoveIDPRequest) (*admin_pb.RemoveIDPResponse, error) { - idpProviders, err := s.iam.IDPProvidersByIDPConfigID(ctx, req.IdpId) + providerQuery, err := query.NewIDPIDSearchQuery(req.IdpId) if err != nil { return nil, err } - externalIDPs, err := s.iam.ExternalIDPsByIDPConfigID(ctx, req.IdpId) + idps, err := s.query.IDPs(ctx, &query.IDPSearchQueries{ + Queries: []query.SearchQuery{providerQuery}, + }) if err != nil { return nil, err } - objectDetails, err := s.command.RemoveDefaultIDPConfig(ctx, req.IdpId, idpProviderViewsToDomain(idpProviders), externalIDPViewsToDomain(externalIDPs)...) + + idpQuery, err := query.NewIDPUserLinkIDPIDSearchQuery(req.IdpId) + if err != nil { + return nil, err + } + userLinks, err := s.query.IDPUserLinks(ctx, &query.IDPUserLinksSearchQuery{ + Queries: []query.SearchQuery{idpQuery}, + }) + if err != nil { + return nil, err + } + + objectDetails, err := s.command.RemoveDefaultIDPConfig(ctx, req.IdpId, idpsToDomain(idps.IDPs), idpUserLinksToDomain(userLinks.Links)...) if err != nil { return nil, err } diff --git a/internal/api/grpc/admin/idp_converter.go b/internal/api/grpc/admin/idp_converter.go index 081a3585e3..ece4e28ef5 100644 --- a/internal/api/grpc/admin/idp_converter.go +++ b/internal/api/grpc/admin/idp_converter.go @@ -6,9 +6,7 @@ import ( "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/eventstore/v1/models" - iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/query" - user_model "github.com/caos/zitadel/internal/user/model" admin_pb "github.com/caos/zitadel/pkg/grpc/admin" ) @@ -89,6 +87,11 @@ func listIDPsToModel(req *admin_pb.ListIDPsRequest) (*query.IDPSearchQueries, er if err != nil { return nil, err } + iamQuery, err := query.NewIDPResourceOwnerSearchQuery(domain.IAMID) + if err != nil { + return nil, err + } + queries = append(queries, iamQuery) return &query.IDPSearchQueries{ SearchRequest: query.SearchRequest{ Offset: offset, @@ -123,30 +126,21 @@ func idpQueryToModel(idpQuery *admin_pb.IDPQuery) (query.SearchQuery, error) { } } -func idpProviderViewsToDomain(idps []*iam_model.IDPProviderView) []*domain.IDPProvider { +func idpsToDomain(idps []*query.IDP) []*domain.IDPProvider { idpProvider := make([]*domain.IDPProvider, len(idps)) for i, idp := range idps { idpProvider[i] = &domain.IDPProvider{ ObjectRoot: models.ObjectRoot{ - AggregateID: idp.AggregateID, + AggregateID: idp.ResourceOwner, }, - IDPConfigID: idp.IDPConfigID, - Type: idpConfigTypeToDomain(idp.IDPProviderType), + IDPConfigID: idp.ID, + Type: idp.OwnerType, } } return idpProvider } -func idpConfigTypeToDomain(idpType iam_model.IDPProviderType) domain.IdentityProviderType { - switch idpType { - case iam_model.IDPProviderTypeOrg: - return domain.IdentityProviderTypeOrg - default: - return domain.IdentityProviderTypeSystem - } -} - -func externalIDPViewsToDomain(idps []*user_model.ExternalIDPView) []*domain.UserIDPLink { +func idpUserLinksToDomain(idps []*query.IDPUserLink) []*domain.UserIDPLink { externalIDPs := make([]*domain.UserIDPLink, len(idps)) for i, idp := range idps { externalIDPs[i] = &domain.UserIDPLink{ @@ -154,9 +148,9 @@ func externalIDPViewsToDomain(idps []*user_model.ExternalIDPView) []*domain.User AggregateID: idp.UserID, ResourceOwner: idp.ResourceOwner, }, - IDPConfigID: idp.IDPConfigID, - ExternalUserID: idp.ExternalUserID, - DisplayName: idp.UserDisplayName, + IDPConfigID: idp.IDPID, + ExternalUserID: idp.ProvidedUserID, + DisplayName: idp.ProvidedUsername, } } return externalIDPs diff --git a/internal/api/grpc/admin/login_policy.go b/internal/api/grpc/admin/login_policy.go index e3b50cfda5..b6195e59ef 100644 --- a/internal/api/grpc/admin/login_policy.go +++ b/internal/api/grpc/admin/login_policy.go @@ -4,6 +4,7 @@ import ( "context" "github.com/caos/zitadel/internal/api/grpc/user" + "github.com/caos/zitadel/internal/query" "github.com/caos/zitadel/internal/api/grpc/idp" "github.com/caos/zitadel/internal/api/grpc/object" @@ -60,11 +61,12 @@ func (s *Server) AddIDPToLoginPolicy(ctx context.Context, req *admin_pb.AddIDPTo } func (s *Server) RemoveIDPFromLoginPolicy(ctx context.Context, req *admin_pb.RemoveIDPFromLoginPolicyRequest) (*admin_pb.RemoveIDPFromLoginPolicyResponse, error) { - externalIDPs, err := s.iam.ExternalIDPsByIDPConfigID(ctx, req.IdpId) - if err != nil { - return nil, err - } - objectDetails, err := s.command.RemoveIDPProviderFromDefaultLoginPolicy(ctx, &domain.IDPProvider{IDPConfigID: req.IdpId}, user.ExternalIDPViewsToExternalIDPs(externalIDPs)...) + idpQuery, err := query.NewIDPUserLinkIDPIDSearchQuery(req.IdpId) + idps, err := s.query.IDPUserLinks(ctx, &query.IDPUserLinksSearchQuery{ + Queries: []query.SearchQuery{idpQuery}, + }) + + objectDetails, err := s.command.RemoveIDPProviderFromDefaultLoginPolicy(ctx, &domain.IDPProvider{IDPConfigID: req.IdpId}, user.ExternalIDPViewsToExternalIDPs(idps.Links)...) if err != nil { return nil, err } diff --git a/internal/api/grpc/auth/user.go b/internal/api/grpc/auth/user.go index e0c978da0d..bf5dd92745 100644 --- a/internal/api/grpc/auth/user.go +++ b/internal/api/grpc/auth/user.go @@ -2,7 +2,6 @@ package auth import ( "context" - "time" "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/api/grpc/change" @@ -12,7 +11,7 @@ import ( user_grpc "github.com/caos/zitadel/internal/api/grpc/user" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/eventstore/v1/models" - user_model "github.com/caos/zitadel/internal/user/model" + "github.com/caos/zitadel/internal/query" grant_model "github.com/caos/zitadel/internal/usergrant/model" auth_pb "github.com/caos/zitadel/pkg/grpc/auth" ) @@ -31,11 +30,18 @@ func (s *Server) RemoveMyUser(ctx context.Context, _ *auth_pb.RemoveMyUserReques if err != nil { return nil, err } - membersShips, err := s.repo.SearchMyUserMemberships(ctx, &user_model.UserMembershipSearchRequest{Queries: []*user_model.UserMembershipSearchQuery{}}) + + userQuery, err := query.NewMembershipUserIDQuery(authz.GetCtxData(ctx).UserID) if err != nil { return nil, err } - details, err := s.command.RemoveUser(ctx, ctxData.UserID, ctxData.ResourceOwner, UserMembershipViewsToDomain(membersShips.Result), userGrantsToIDs(grants.Result)...) + memberships, err := s.query.Memberships(ctx, &query.MembershipSearchQuery{ + Queries: []query.SearchQuery{userQuery}, + }) + if err != nil { + return nil, err + } + details, err := s.command.RemoveUser(ctx, ctxData.UserID, ctxData.ResourceOwner, memberships.Memberships, userGrantsToIDs(grants.Result)...) if err != nil { return nil, err } @@ -129,68 +135,141 @@ func (s *Server) ListMyUserGrants(ctx context.Context, req *auth_pb.ListMyUserGr } func (s *Server) ListMyProjectOrgs(ctx context.Context, req *auth_pb.ListMyProjectOrgsRequest) (*auth_pb.ListMyProjectOrgsResponse, error) { - r, err := ListMyProjectOrgsRequestToModel(req) + queries, err := ListMyProjectOrgsRequestToQuery(req) if err != nil { return nil, err } - res, err := s.repo.SearchMyProjectOrgs(ctx, r) + + iam, err := s.query.IAMByID(ctx, domain.IAMID) + if err != nil { + return nil, err + } + ctxData := authz.GetCtxData(ctx) + + //client of user is not in project of ZITADEL + if ctxData.ProjectID != iam.IAMProjectID { + grants, err := s.repo.UserGrantsByProjectAndUserID(ctxData.ProjectID, ctxData.UserID) + if err != nil { + return nil, err + } + + ids := make([]string, 0, len(grants)) + for _, grant := range grants { + ids = appendIfNotExists(ids, grant.ResourceOwner) + } + + idsQuery, err := query.NewOrgIDsSearchQuery(ids...) + if err != nil { + return nil, err + } + queries.Queries = append(queries.Queries, idsQuery) + } else { + memberships, err := s.myOrgsQuery(ctx, ctxData) + if err != nil { + return nil, err + } + + if !isIAMAdmin(memberships.Memberships) { + ids := make([]string, 0, len(memberships.Memberships)) + for _, grant := range memberships.Memberships { + ids = appendIfNotExists(ids, grant.ResourceOwner) + } + + idsQuery, err := query.NewOrgIDsSearchQuery(ids...) + if err != nil { + return nil, err + } + queries.Queries = append(queries.Queries, idsQuery) + } + } + + orgs, err := s.query.SearchOrgs(ctx, queries) if err != nil { return nil, err } return &auth_pb.ListMyProjectOrgsResponse{ - //TODO: not all details - Details: obj_grpc.ToListDetails(res.TotalResult, 0, time.Time{}), - Result: org.OrgsToPb(res.Result), + Details: obj_grpc.ToListDetails(orgs.Count, orgs.Sequence, orgs.Timestamp), + Result: org.OrgsToPb(orgs.Orgs), }, nil } -func ListMyProjectOrgsRequestToModel(req *auth_pb.ListMyProjectOrgsRequest) (*grant_model.UserGrantSearchRequest, error) { - offset, limit, asc := obj_grpc.ListQueryToModel(req.Query) - queries, err := org.OrgQueriesToUserGrantModel(req.Queries) +func (s *Server) myOrgsQuery(ctx context.Context, ctxData authz.CtxData) (*query.Memberships, error) { + userQuery, err := query.NewMembershipUserIDQuery(ctxData.UserID) if err != nil { return nil, err } - return &grant_model.UserGrantSearchRequest{ - Offset: offset, - Limit: limit, - Asc: asc, + return s.query.Memberships(ctx, &query.MembershipSearchQuery{ + Queries: []query.SearchQuery{userQuery}, + }) +} + +func isIAMAdmin(memberships []*query.Membership) bool { + for _, m := range memberships { + if m.IAM != nil { + return true + } + } + return false +} + +func appendIfNotExists(array []string, value string) []string { + for _, a := range array { + if a == value { + return array + } + } + return append(array, value) +} + +func ListMyProjectOrgsRequestToQuery(req *auth_pb.ListMyProjectOrgsRequest) (*query.OrgSearchQueries, error) { + offset, limit, asc := obj_grpc.ListQueryToModel(req.Query) + queries, err := org.OrgQueriesToQuery(req.Queries) + if err != nil { + return nil, err + } + return &query.OrgSearchQueries{ + SearchRequest: query.SearchRequest{ + Offset: offset, + Limit: limit, + Asc: asc, + }, Queries: queries, }, nil } -func UserMembershipViewsToDomain(memberships []*user_model.UserMembershipView) []*domain.UserMembership { +func membershipToDomain(memberships []*query.Membership) []*domain.UserMembership { result := make([]*domain.UserMembership, len(memberships)) for i, membership := range memberships { + typ, displayName, aggID, objID := MemberTypeToDomain(membership) result[i] = &domain.UserMembership{ - UserID: membership.UserID, - MemberType: MemberTypeToDomain(membership.MemberType), - AggregateID: membership.AggregateID, - ObjectID: membership.ObjectID, - Roles: membership.Roles, - DisplayName: membership.DisplayName, - CreationDate: membership.CreationDate, - ChangeDate: membership.ChangeDate, - ResourceOwner: membership.ResourceOwner, - ResourceOwnerName: membership.ResourceOwnerName, - Sequence: membership.Sequence, + UserID: membership.UserID, + MemberType: typ, + AggregateID: aggID, + ObjectID: objID, + Roles: membership.Roles, + DisplayName: displayName, + CreationDate: membership.CreationDate, + ChangeDate: membership.ChangeDate, + ResourceOwner: membership.ResourceOwner, + //TODO: implement + // ResourceOwnerName: membership.ResourceOwnerName, + Sequence: membership.Sequence, } } return result } -func MemberTypeToDomain(mType user_model.MemberType) domain.MemberType { - switch mType { - case user_model.MemberTypeIam: - return domain.MemberTypeIam - case user_model.MemberTypeOrganisation: - return domain.MemberTypeOrganisation - case user_model.MemberTypeProject: - return domain.MemberTypeProject - case user_model.MemberTypeProjectGrant: - return domain.MemberTypeProjectGrant - default: - return domain.MemberTypeUnspecified +func MemberTypeToDomain(m *query.Membership) (_ domain.MemberType, displayName, aggID, objID string) { + if m.Org != nil { + return domain.MemberTypeOrganisation, m.Org.Name, m.Org.OrgID, "" + } else if m.IAM != nil { + return domain.MemberTypeIam, m.IAM.Name, m.IAM.IAMID, "" + } else if m.Project != nil { + return domain.MemberTypeProject, m.Project.Name, m.Project.ProjectID, "" + } else if m.ProjectGrant != nil { + return domain.MemberTypeProjectGrant, m.ProjectGrant.ProjectName, m.ProjectGrant.ProjectID, m.ProjectGrant.GrantID } + return domain.MemberTypeUnspecified, "", "", "" } func userGrantsToIDs(userGrants []*grant_model.UserGrantView) []string { diff --git a/internal/api/grpc/management/iam.go b/internal/api/grpc/management/iam.go index 2d4e001f4c..006ada73c4 100644 --- a/internal/api/grpc/management/iam.go +++ b/internal/api/grpc/management/iam.go @@ -7,7 +7,7 @@ import ( ) func (s *Server) GetIAM(ctx context.Context, req *mgmt_pb.GetIAMRequest) (*mgmt_pb.GetIAMResponse, error) { - iam, err := s.project.GetIAMByID(ctx) + iam, err := s.query.IAMByID(ctx, s.systemDefaults.IamID) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/idp.go b/internal/api/grpc/management/idp.go index 7d49dca2c2..ec6709f410 100644 --- a/internal/api/grpc/management/idp.go +++ b/internal/api/grpc/management/idp.go @@ -6,6 +6,7 @@ import ( "github.com/caos/zitadel/internal/api/authz" idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp" object_pb "github.com/caos/zitadel/internal/api/grpc/object" + "github.com/caos/zitadel/internal/query" mgmt_pb "github.com/caos/zitadel/pkg/grpc/management" ) @@ -18,11 +19,11 @@ func (s *Server) GetOrgIDPByID(ctx context.Context, req *mgmt_pb.GetOrgIDPByIDRe } func (s *Server) ListOrgIDPs(ctx context.Context, req *mgmt_pb.ListOrgIDPsRequest) (*mgmt_pb.ListOrgIDPsResponse, error) { - queries, err := listIDPsToModel(req) + queries, err := listIDPsToModel(ctx, req) if err != nil { return nil, err } - resp, err := s.query.SearchIDPs(ctx, authz.GetCtxData(ctx).OrgID, queries) + resp, err := s.query.IDPs(ctx, queries) if err != nil { return nil, err } @@ -83,11 +84,17 @@ func (s *Server) RemoveOrgIDP(ctx context.Context, req *mgmt_pb.RemoveOrgIDPRequ if err != nil { return nil, err } - externalIDPs, err := s.user.ExternalIDPsByIDPConfigID(ctx, req.IdpId) + idpQuery, err := query.NewIDPUserLinkIDPIDSearchQuery(req.IdpId) if err != nil { return nil, err } - _, err = s.command.RemoveIDPConfig(ctx, req.IdpId, authz.GetCtxData(ctx).OrgID, idp != nil, externalIDPViewsToDomain(externalIDPs)...) + userLinks, err := s.query.IDPUserLinks(ctx, &query.IDPUserLinksSearchQuery{ + Queries: []query.SearchQuery{idpQuery}, + }) + if err != nil { + return nil, err + } + _, err = s.command.RemoveIDPConfig(ctx, req.IdpId, authz.GetCtxData(ctx).OrgID, idp != nil, userLinksToDomain(userLinks.Links)...) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/idp_converter.go b/internal/api/grpc/management/idp_converter.go index 9dc9e2156d..7f3840fcea 100644 --- a/internal/api/grpc/management/idp_converter.go +++ b/internal/api/grpc/management/idp_converter.go @@ -1,6 +1,9 @@ package management import ( + "context" + + "github.com/caos/zitadel/internal/api/authz" idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp" "github.com/caos/zitadel/internal/api/grpc/object" "github.com/caos/zitadel/internal/domain" @@ -8,7 +11,6 @@ import ( "github.com/caos/zitadel/internal/eventstore/v1/models" iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/query" - user_model "github.com/caos/zitadel/internal/user/model" mgmt_pb "github.com/caos/zitadel/pkg/grpc/management" ) @@ -83,12 +85,21 @@ func updateJWTConfigToDomain(req *mgmt_pb.UpdateOrgIDPJWTConfigRequest) *domain. } } -func listIDPsToModel(req *mgmt_pb.ListOrgIDPsRequest) (queries *query.IDPSearchQueries, err error) { +func listIDPsToModel(ctx context.Context, req *mgmt_pb.ListOrgIDPsRequest) (queries *query.IDPSearchQueries, err error) { offset, limit, asc := object.ListQueryToModel(req.Query) q, err := idpQueriesToModel(req.Queries) if err != nil { return nil, err } + iamQuery, err := query.NewIDPIDSearchQuery(domain.IAMID) + if err != nil { + return nil, err + } + resourceOwnerQuery, err := query.NewIDPResourceOwnerSearchQuery(authz.GetCtxData(ctx).OrgID) + if err != nil { + return nil, err + } + q = append(q, resourceOwnerQuery, iamQuery) return &query.IDPSearchQueries{ SearchRequest: query.SearchRequest{ Offset: offset, @@ -148,18 +159,18 @@ func idpConfigTypeToDomain(idpType iam_model.IDPProviderType) domain.IdentityPro } } -func externalIDPViewsToDomain(idps []*user_model.ExternalIDPView) []*domain.UserIDPLink { - externalIDPs := make([]*domain.UserIDPLink, len(idps)) +func userLinksToDomain(idps []*query.IDPUserLink) []*domain.UserIDPLink { + links := make([]*domain.UserIDPLink, len(idps)) for i, idp := range idps { - externalIDPs[i] = &domain.UserIDPLink{ + links[i] = &domain.UserIDPLink{ ObjectRoot: models.ObjectRoot{ AggregateID: idp.UserID, ResourceOwner: idp.ResourceOwner, }, - IDPConfigID: idp.IDPConfigID, - ExternalUserID: idp.ExternalUserID, - DisplayName: idp.UserDisplayName, + IDPConfigID: idp.IDPID, + ExternalUserID: idp.ProvidedUserID, + DisplayName: idp.ProvidedUsername, } } - return externalIDPs + return links } diff --git a/internal/api/grpc/management/org.go b/internal/api/grpc/management/org.go index ce2cc985af..0abda8ee47 100644 --- a/internal/api/grpc/management/org.go +++ b/internal/api/grpc/management/org.go @@ -208,7 +208,11 @@ func (s *Server) SetPrimaryOrgDomain(ctx context.Context, req *mgmt_pb.SetPrimar } func (s *Server) ListOrgMemberRoles(ctx context.Context, req *mgmt_pb.ListOrgMemberRolesRequest) (*mgmt_pb.ListOrgMemberRolesResponse, error) { - roles := s.org.GetOrgMemberRoles() + iam, err := s.iam.IAMByID(ctx, domain.IAMID) + if err != nil { + return nil, err + } + roles := s.org.GetOrgMemberRoles(authz.GetCtxData(ctx).OrgID == iam.GlobalOrgID) return &mgmt_pb.ListOrgMemberRolesResponse{ Result: roles, }, nil diff --git a/internal/api/grpc/management/policy_login.go b/internal/api/grpc/management/policy_login.go index 7b6260fc46..525ffe0856 100644 --- a/internal/api/grpc/management/policy_login.go +++ b/internal/api/grpc/management/policy_login.go @@ -9,6 +9,7 @@ import ( policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy" "github.com/caos/zitadel/internal/api/grpc/user" "github.com/caos/zitadel/internal/domain" + "github.com/caos/zitadel/internal/query" mgmt_pb "github.com/caos/zitadel/pkg/grpc/management" ) @@ -93,11 +94,17 @@ func (s *Server) AddIDPToLoginPolicy(ctx context.Context, req *mgmt_pb.AddIDPToL } func (s *Server) RemoveIDPFromLoginPolicy(ctx context.Context, req *mgmt_pb.RemoveIDPFromLoginPolicyRequest) (*mgmt_pb.RemoveIDPFromLoginPolicyResponse, error) { - externalIDPs, err := s.user.ExternalIDPsByIDPConfigID(ctx, req.IdpId) + idpQuery, err := query.NewIDPUserLinkIDPIDSearchQuery(req.IdpId) if err != nil { return nil, err } - objectDetails, err := s.command.RemoveIDPProviderFromLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, &domain.IDPProvider{IDPConfigID: req.IdpId}, user.ExternalIDPViewsToExternalIDPs(externalIDPs)...) + userLinks, err := s.query.IDPUserLinks(ctx, &query.IDPUserLinksSearchQuery{ + Queries: []query.SearchQuery{idpQuery}, + }) + if err != nil { + return nil, err + } + objectDetails, err := s.command.RemoveIDPProviderFromLoginPolicy(ctx, authz.GetCtxData(ctx).OrgID, &domain.IDPProvider{IDPConfigID: req.IdpId}, user.ExternalIDPViewsToExternalIDPs(userLinks.Links)...) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go index 6e72b72b17..6c447fbb2d 100644 --- a/internal/api/grpc/management/user.go +++ b/internal/api/grpc/management/user.go @@ -261,11 +261,17 @@ func (s *Server) RemoveUser(ctx context.Context, req *mgmt_pb.RemoveUserRequest) if err != nil { return nil, err } - membersShips, err := s.user.UserMembershipsByUserID(ctx, req.Id) + userQuery, err := query.NewMembershipUserIDQuery(req.Id) if err != nil { return nil, err } - objectDetails, err := s.command.RemoveUser(ctx, req.Id, authz.GetCtxData(ctx).OrgID, UserMembershipViewsToDomain(membersShips), userGrantsToIDs(grants)...) + memberships, err := s.query.Memberships(ctx, &query.MembershipSearchQuery{ + Queries: []query.SearchQuery{userQuery}, + }) + if err != nil { + return nil, err + } + objectDetails, err := s.command.RemoveUser(ctx, req.Id, authz.GetCtxData(ctx).OrgID, memberships.Memberships, userGrantsToIDs(grants)...) if err != nil { return nil, err } diff --git a/internal/api/grpc/org/converter.go b/internal/api/grpc/org/converter.go index f62eb1f845..587da8c8e8 100644 --- a/internal/api/grpc/org/converter.go +++ b/internal/api/grpc/org/converter.go @@ -5,7 +5,6 @@ import ( "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/query" - grant_model "github.com/caos/zitadel/internal/usergrant/model" org_pb "github.com/caos/zitadel/pkg/grpc/org" ) @@ -31,10 +30,10 @@ func OrgQueryToModel(apiQuery *org_pb.OrgQuery) (query.SearchQuery, error) { } } -func OrgQueriesToUserGrantModel(queries []*org_pb.OrgQuery) (_ []*grant_model.UserGrantSearchQuery, err error) { - q := make([]*grant_model.UserGrantSearchQuery, len(queries)) +func OrgQueriesToQuery(queries []*org_pb.OrgQuery) (_ []query.SearchQuery, err error) { + q := make([]query.SearchQuery, len(queries)) for i, query := range queries { - q[i], err = OrgQueryToUserGrantQueryModel(query) + q[i], err = OrgQueryToQuery(query) if err != nil { return nil, err } @@ -42,20 +41,12 @@ func OrgQueriesToUserGrantModel(queries []*org_pb.OrgQuery) (_ []*grant_model.Us return q, nil } -func OrgQueryToUserGrantQueryModel(query *org_pb.OrgQuery) (*grant_model.UserGrantSearchQuery, error) { - switch q := query.Query.(type) { +func OrgQueryToQuery(search *org_pb.OrgQuery) (query.SearchQuery, error) { + switch q := search.Query.(type) { case *org_pb.OrgQuery_DomainQuery: - return &grant_model.UserGrantSearchQuery{ - Key: grant_model.UserGrantSearchKeyOrgDomain, - Method: object.TextMethodToModel(q.DomainQuery.Method), - Value: q.DomainQuery.Domain, - }, nil + return query.NewOrgDomainSearchQuery(object.TextMethodToQuery(q.DomainQuery.Method), q.DomainQuery.Domain) case *org_pb.OrgQuery_NameQuery: - return &grant_model.UserGrantSearchQuery{ - Key: grant_model.UserGrantSearchKeyOrgName, - Method: object.TextMethodToModel(q.NameQuery.Method), - Value: q.NameQuery.Name, - }, nil + return query.NewOrgNameSearchQuery(object.TextMethodToQuery(q.NameQuery.Method), q.NameQuery.Name) default: return nil, errors.ThrowInvalidArgument(nil, "ADMIN-ADvsd", "List.Query.Invalid") } @@ -71,9 +62,10 @@ func OrgViewsToPb(orgs []*query.Org) []*org_pb.Org { func OrgViewToPb(org *query.Org) *org_pb.Org { return &org_pb.Org{ - Id: org.ID, - State: OrgStateToPb(org.State), - Name: org.Name, + Id: org.ID, + State: OrgStateToPb(org.State), + Name: org.Name, + PrimaryDomain: org.Domain, Details: object.ToViewDetailsPb( org.Sequence, org.CreationDate, @@ -83,7 +75,7 @@ func OrgViewToPb(org *query.Org) *org_pb.Org { } } -func OrgsToPb(orgs []*grant_model.Org) []*org_pb.Org { +func OrgsToPb(orgs []*query.Org) []*org_pb.Org { o := make([]*org_pb.Org, len(orgs)) for i, org := range orgs { o[i] = OrgToPb(org) @@ -91,17 +83,13 @@ func OrgsToPb(orgs []*grant_model.Org) []*org_pb.Org { return o } -func OrgToPb(org *grant_model.Org) *org_pb.Org { +func OrgToPb(org *query.Org) *org_pb.Org { return &org_pb.Org{ - Id: org.OrgID, - Name: org.OrgName, - // State: OrgStateToPb(org.State), //TODO: not provided - // Details: object.ChangeToDetailsPb(//TODO: not provided - // org.Sequence,//TODO: not provided - // org.CreationDate,//TODO: not provided - // org.EventDate,//TODO: not provided - // org.ResourceOwner,//TODO: not provided - // ),//TODO: not provided + Id: org.ID, + Name: org.Name, + PrimaryDomain: org.Domain, + Details: object.AddToDetailsPb(org.Sequence, org.CreationDate, org.ResourceOwner), + State: OrgStateToPb(org.State), } } diff --git a/internal/api/grpc/user/converter.go b/internal/api/grpc/user/converter.go index 5347f4d849..a40c78f16b 100644 --- a/internal/api/grpc/user/converter.go +++ b/internal/api/grpc/user/converter.go @@ -4,6 +4,7 @@ import ( "github.com/caos/zitadel/internal/api/grpc/object" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/eventstore/v1/models" + "github.com/caos/zitadel/internal/query" "github.com/caos/zitadel/internal/user/model" usr_grant_model "github.com/caos/zitadel/internal/usergrant/model" user_pb "github.com/caos/zitadel/pkg/grpc/user" @@ -233,7 +234,7 @@ func WebAuthNTokenToWebAuthNKeyPb(token *domain.WebAuthNToken) *user_pb.WebAuthN } } -func ExternalIDPViewsToExternalIDPs(externalIDPs []*model.ExternalIDPView) []*domain.UserIDPLink { +func ExternalIDPViewsToExternalIDPs(externalIDPs []*query.IDPUserLink) []*domain.UserIDPLink { idps := make([]*domain.UserIDPLink, len(externalIDPs)) for i, idp := range externalIDPs { idps[i] = &domain.UserIDPLink{ @@ -241,9 +242,9 @@ func ExternalIDPViewsToExternalIDPs(externalIDPs []*model.ExternalIDPView) []*do AggregateID: idp.UserID, ResourceOwner: idp.ResourceOwner, }, - IDPConfigID: idp.IDPConfigID, - ExternalUserID: idp.ExternalUserID, - DisplayName: idp.UserDisplayName, + IDPConfigID: idp.IDPID, + ExternalUserID: idp.ProvidedUserID, + DisplayName: idp.ProvidedUsername, } } return idps diff --git a/internal/auth/repository/eventsourcing/eventstore/user_grant.go b/internal/auth/repository/eventsourcing/eventstore/user_grant.go index 9c5063704c..b31a960c8a 100644 --- a/internal/auth/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/auth/repository/eventsourcing/eventstore/user_grant.go @@ -13,7 +13,6 @@ import ( authz_repo "github.com/caos/zitadel/internal/authz/repository/eventsourcing" caos_errs "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/telemetry/tracing" - user_model "github.com/caos/zitadel/internal/user/model" user_view_model "github.com/caos/zitadel/internal/user/repository/view/model" grant_model "github.com/caos/zitadel/internal/usergrant/model" "github.com/caos/zitadel/internal/usergrant/repository/view/model" @@ -64,6 +63,7 @@ func (repo *UserGrantRepo) SearchMyProjectOrgs(ctx context.Context, request *gra if ctxData.ProjectID == "" { return nil, caos_errs.ThrowPreconditionFailed(nil, "APP-7lqva", "Could not get ProjectID") } + err = repo.AuthZRepo.FillIamProjectID(ctx) if err != nil { return nil, err @@ -109,32 +109,6 @@ func (repo *UserGrantRepo) membershipsToOrgResp(memberships *query.Memberships) } } -func (repo *UserGrantRepo) SearchMyUserMemberships(ctx context.Context, request *user_model.UserMembershipSearchRequest) (*user_model.UserMembershipSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - request.AppendUserIDQuery(authz.GetCtxData(ctx).UserID) - sequence, sequenceErr := repo.View.GetLatestUserMembershipSequence() - logging.Log("EVENT-Dn7sf").OnError(sequenceErr).Warn("could not read latest user sequence") - - memberships, count, err := repo.View.SearchUserMemberships(request) - if err != nil { - return nil, err - } - result := &user_model.UserMembershipSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: user_view_model.UserMembershipsToModel(memberships), - } - if sequenceErr == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - func (repo *UserGrantRepo) SearchMyZitadelPermissions(ctx context.Context) ([]string, error) { memberships, err := repo.searchUserMemberships(ctx) if err != nil { diff --git a/internal/auth/repository/eventsourcing/handler/handler.go b/internal/auth/repository/eventsourcing/handler/handler.go index b273680a8b..c847b29810 100644 --- a/internal/auth/repository/eventsourcing/handler/handler.go +++ b/internal/auth/repository/eventsourcing/handler/handler.go @@ -36,8 +36,6 @@ func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es systemDefaults.IamID), newUserSession( handler{view, bulkLimit, configs.cycleDuration("UserSession"), errorCount, es}), - newUserMembership( - handler{view, bulkLimit, configs.cycleDuration("UserMembership"), errorCount, es}), newToken( handler{view, bulkLimit, configs.cycleDuration("Token"), errorCount, es}), newUserGrant( diff --git a/internal/auth/repository/eventsourcing/handler/user_membership.go b/internal/auth/repository/eventsourcing/handler/user_membership.go deleted file mode 100644 index d18c246abb..0000000000 --- a/internal/auth/repository/eventsourcing/handler/user_membership.go +++ /dev/null @@ -1,325 +0,0 @@ -package handler - -import ( - "context" - - "github.com/caos/logging" - - "github.com/caos/zitadel/internal/errors" - v1 "github.com/caos/zitadel/internal/eventstore/v1" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - org_model "github.com/caos/zitadel/internal/org/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - org_view "github.com/caos/zitadel/internal/org/repository/view" - proj_model "github.com/caos/zitadel/internal/project/model" - proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - proj_view "github.com/caos/zitadel/internal/project/repository/view" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - usr_es_model "github.com/caos/zitadel/internal/user/repository/view/model" -) - -const ( - userMembershipTable = "auth.user_memberships" -) - -type UserMembership struct { - handler - subscription *v1.Subscription -} - -func newUserMembership( - handler handler, -) *UserMembership { - h := &UserMembership{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (m *UserMembership) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (m *UserMembership) ViewModel() string { - return userMembershipTable -} - -func (m *UserMembership) Subscription() *v1.Subscription { - return m.subscription -} - -func (_ *UserMembership) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{iam_es_model.IAMAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate, model.UserAggregate} -} - -func (m *UserMembership) CurrentSequence() (uint64, error) { - sequence, err := m.view.GetLatestUserMembershipSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (m *UserMembership) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestUserMembershipSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(m.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (m *UserMembership) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case iam_es_model.IAMAggregate: - err = m.processIAM(event) - case org_es_model.OrgAggregate: - err = m.processOrg(event) - case proj_es_model.ProjectAggregate: - err = m.processProject(event) - case model.UserAggregate: - err = m.processUser(event) - } - return err -} - -func (m *UserMembership) processIAM(event *es_models.Event) (err error) { - member := new(usr_es_model.UserMembershipView) - err = member.AppendEvent(event) - if err != nil { - return err - } - switch event.Type { - case iam_es_model.IAMMemberAdded: - m.fillIamDisplayName(member) - case iam_es_model.IAMMemberChanged: - member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeIam) - if err != nil { - return err - } - err = member.AppendEvent(event) - case iam_es_model.IAMMemberRemoved, - iam_es_model.IAMMemberCascadeRemoved: - return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeIam, event) - default: - return m.view.ProcessedUserMembershipSequence(event) - } - if err != nil { - return err - } - return m.view.PutUserMembership(member, event) -} - -func (m *UserMembership) fillIamDisplayName(member *usr_es_model.UserMembershipView) { - member.DisplayName = member.AggregateID - member.ResourceOwnerName = member.ResourceOwner -} - -func (m *UserMembership) processOrg(event *es_models.Event) (err error) { - member := new(usr_es_model.UserMembershipView) - err = member.AppendEvent(event) - if err != nil { - return err - } - switch event.Type { - case org_es_model.OrgMemberAdded: - err = m.fillOrgName(member) - case org_es_model.OrgMemberChanged: - member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeOrganisation) - if err != nil { - return err - } - err = member.AppendEvent(event) - case org_es_model.OrgMemberRemoved, - org_es_model.OrgMemberCascadeRemoved: - return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeOrganisation, event) - case org_es_model.OrgChanged: - return m.updateOrgName(event) - default: - return m.view.ProcessedUserMembershipSequence(event) - } - if err != nil { - return err - } - return m.view.PutUserMembership(member, event) -} - -func (m *UserMembership) fillOrgName(member *usr_es_model.UserMembershipView) (err error) { - org, err := m.getOrgByID(context.Background(), member.ResourceOwner) - if err != nil { - return err - } - member.ResourceOwnerName = org.Name - if member.AggregateID == org.AggregateID { - member.DisplayName = org.Name - } - return nil -} - -func (m *UserMembership) updateOrgName(event *es_models.Event) error { - org, err := m.getOrgByID(context.Background(), event.AggregateID) - if err != nil { - return err - } - - memberships, err := m.view.UserMembershipsByResourceOwner(event.ResourceOwner) - if err != nil { - return err - } - for _, membership := range memberships { - membership.ResourceOwnerName = org.Name - if membership.AggregateID == event.AggregateID { - membership.DisplayName = org.Name - } - } - return m.view.BulkPutUserMemberships(memberships, event) -} - -func (m *UserMembership) processProject(event *es_models.Event) (err error) { - member := new(usr_es_model.UserMembershipView) - err = member.AppendEvent(event) - if err != nil { - return err - } - switch event.Type { - case proj_es_model.ProjectMemberAdded, proj_es_model.ProjectGrantMemberAdded: - err = m.fillProjectDisplayName(member) - if err != nil { - return err - } - err = m.fillOrgName(member) - case proj_es_model.ProjectMemberChanged: - member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeProject) - if err != nil { - return err - } - err = member.AppendEvent(event) - case proj_es_model.ProjectMemberRemoved, - proj_es_model.ProjectMemberCascadeRemoved: - return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeProject, event) - case proj_es_model.ProjectGrantMemberChanged: - member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, member.ObjectID, usr_model.MemberTypeProjectGrant) - if err != nil { - return err - } - err = member.AppendEvent(event) - case proj_es_model.ProjectGrantMemberRemoved, - proj_es_model.ProjectGrantMemberCascadeRemoved: - return m.view.DeleteUserMembership(member.UserID, event.AggregateID, member.ObjectID, usr_model.MemberTypeProjectGrant, event) - case proj_es_model.ProjectChanged: - return m.updateProjectDisplayName(event) - case proj_es_model.ProjectRemoved: - return m.view.DeleteUserMembershipsByAggregateID(event.AggregateID, event) - case proj_es_model.ProjectGrantRemoved: - return m.view.DeleteUserMembershipsByAggregateIDAndObjectID(event.AggregateID, member.ObjectID, event) - default: - return m.view.ProcessedUserMembershipSequence(event) - } - if err != nil { - return err - } - return m.view.PutUserMembership(member, event) -} - -func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembershipView) (err error) { - project, err := m.getProjectByID(context.Background(), member.AggregateID) - if err != nil { - return err - } - member.DisplayName = project.Name - return nil -} - -func (m *UserMembership) updateProjectDisplayName(event *es_models.Event) error { - proj := new(proj_es_model.Project) - err := proj.SetData(event) - if err != nil { - return err - } - if proj.Name == "" { - return m.view.ProcessedUserMembershipSequence(event) - } - - memberships, err := m.view.UserMembershipsByAggregateID(event.AggregateID) - if err != nil { - return err - } - for _, membership := range memberships { - membership.DisplayName = proj.Name - } - return m.view.BulkPutUserMemberships(memberships, event) -} - -func (m *UserMembership) processUser(event *es_models.Event) (err error) { - switch event.Type { - case model.UserRemoved: - return m.view.DeleteUserMembershipsByUserID(event.AggregateID, event) - default: - return m.view.ProcessedUserMembershipSequence(event) - } -} - -func (m *UserMembership) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-Ms3fj", "id", event.AggregateID).WithError(err).Warn("something went wrong in user membership handler") - return spooler.HandleError(event, err, m.view.GetLatestUserMembershipFailedEvent, m.view.ProcessedUserMembershipFailedEvent, m.view.ProcessedUserMembershipSequence, m.errorCountUntilSkip) -} - -func (m *UserMembership) OnSuccess() error { - return spooler.HandleSuccess(m.view.UpdateUserMembershipSpoolerRunTimestamp) -} - -func (u *UserMembership) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := org_view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !errors.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, errors.ThrowNotFound(nil, "EVENT-3m9vs", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *UserMembership) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) { - query, err := proj_view.ProjectByIDQuery(projID, 0) - if err != nil { - return nil, err - } - esProject := &proj_es_model.Project{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: projID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esProject.AppendEvents, query) - if err != nil && !errors.IsNotFound(err) { - return nil, err - } - if esProject.Sequence == 0 { - return nil, errors.ThrowNotFound(nil, "EVENT-Dbfw2", "Errors.Project.NotFound") - } - - return proj_es_model.ProjectToModel(esProject), nil -} diff --git a/internal/auth/repository/eventsourcing/view/user_membership.go b/internal/auth/repository/eventsourcing/view/user_membership.go deleted file mode 100644 index 8508bc2086..0000000000 --- a/internal/auth/repository/eventsourcing/view/user_membership.go +++ /dev/null @@ -1,98 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/view" - "github.com/caos/zitadel/internal/user/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -const ( - userMembershipTable = "auth.user_memberships" -) - -func (v *View) UserMembershipByIDs(userID, aggregateID, objectID string, memberType usr_model.MemberType) (*model.UserMembershipView, error) { - return view.UserMembershipByIDs(v.Db, userMembershipTable, userID, aggregateID, objectID, memberType) -} - -func (v *View) UserMembershipsByAggregateID(aggregateID string) ([]*model.UserMembershipView, error) { - return view.UserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID) -} - -func (v *View) UserMembershipsByResourceOwner(resourceOwner string) ([]*model.UserMembershipView, error) { - return view.UserMembershipsByResourceOwner(v.Db, userMembershipTable, resourceOwner) -} - -func (v *View) SearchUserMemberships(request *usr_model.UserMembershipSearchRequest) ([]*model.UserMembershipView, uint64, error) { - return view.SearchUserMemberships(v.Db, userMembershipTable, request) -} - -func (v *View) PutUserMembership(membership *model.UserMembershipView, event *models.Event) error { - err := view.PutUserMembership(v.Db, userMembershipTable, membership) - if err != nil { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) BulkPutUserMemberships(memberships []*model.UserMembershipView, event *models.Event) error { - err := view.PutUserMemberships(v.Db, userMembershipTable, memberships...) - if err != nil { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) DeleteUserMembership(userID, aggregateID, objectID string, memberType usr_model.MemberType, event *models.Event) error { - err := view.DeleteUserMembership(v.Db, userMembershipTable, userID, aggregateID, objectID, memberType) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) DeleteUserMembershipsByUserID(userID string, event *models.Event) error { - err := view.DeleteUserMembershipsByUserID(v.Db, userMembershipTable, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) DeleteUserMembershipsByAggregateID(aggregateID string, event *models.Event) error { - err := view.DeleteUserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) DeleteUserMembershipsByAggregateIDAndObjectID(aggregateID, objectID string, event *models.Event) error { - err := view.DeleteUserMembershipsByAggregateIDAndObjectID(v.Db, userMembershipTable, aggregateID, objectID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) GetLatestUserMembershipSequence() (*repository.CurrentSequence, error) { - return v.latestSequence(userMembershipTable) -} - -func (v *View) ProcessedUserMembershipSequence(event *models.Event) error { - return v.saveCurrentSequence(userMembershipTable, event) -} - -func (v *View) UpdateUserMembershipSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(userMembershipTable) -} - -func (v *View) GetLatestUserMembershipFailedEvent(sequence uint64) (*repository.FailedEvent, error) { - return v.latestFailedEvent(userMembershipTable, sequence) -} - -func (v *View) ProcessedUserMembershipFailedEvent(failedEvent *repository.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/auth/repository/user.go b/internal/auth/repository/user.go index 72ab396108..c5e90098a5 100644 --- a/internal/auth/repository/user.go +++ b/internal/auth/repository/user.go @@ -40,8 +40,6 @@ type myUserRepo interface { MyUserChanges(ctx context.Context, lastSequence uint64, limit uint64, sortAscending bool, retention time.Duration) (*model.UserChanges, error) - SearchMyUserMemberships(ctx context.Context, request *model.UserMembershipSearchRequest) (*model.UserMembershipSearchResponse, error) - GetMyMetadataByKey(ctx context.Context, key string) (*domain.Metadata, error) SearchMyMetadata(ctx context.Context, req *domain.MetadataSearchRequest) (*domain.MetadataSearchResponse, error) } diff --git a/internal/command/user.go b/internal/command/user.go index 4ebb9bff9a..db0e1a061b 100644 --- a/internal/command/user.go +++ b/internal/command/user.go @@ -6,6 +6,7 @@ import ( "time" "github.com/caos/zitadel/internal/eventstore" + "github.com/caos/zitadel/internal/query" "github.com/caos/zitadel/internal/eventstore/v1/models" @@ -169,7 +170,7 @@ func (c *Commands) UnlockUser(ctx context.Context, userID, resourceOwner string) return writeModelToObjectDetails(&existingUser.WriteModel), nil } -func (c *Commands) RemoveUser(ctx context.Context, userID, resourceOwner string, cascadingUserMemberships []*domain.UserMembership, cascadingGrantIDs ...string) (*domain.ObjectDetails, error) { +func (c *Commands) RemoveUser(ctx context.Context, userID, resourceOwner string, cascadingUserMemberships []*query.Membership, cascadingGrantIDs ...string) (*domain.ObjectDetails, error) { if userID == "" { return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-2M0ds", "Errors.User.UserIDMissing") } @@ -200,7 +201,7 @@ func (c *Commands) RemoveUser(ctx context.Context, userID, resourceOwner string, } if len(cascadingUserMemberships) > 0 { - membershipEvents, err := c.removeUserMemberships(ctx, cascadingUserMemberships, true) + membershipEvents, err := c.removeUserMemberships(ctx, cascadingUserMemberships) if err != nil { return nil, err } diff --git a/internal/command/user_membership.go b/internal/command/user_membership.go index 391d61d438..d75fd2b817 100644 --- a/internal/command/user_membership.go +++ b/internal/command/user_membership.go @@ -3,32 +3,31 @@ package command import ( "context" - "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/eventstore" + "github.com/caos/zitadel/internal/query" "github.com/caos/zitadel/internal/repository/iam" "github.com/caos/zitadel/internal/repository/org" "github.com/caos/zitadel/internal/repository/project" ) -func (c *Commands) removeUserMemberships(ctx context.Context, memberships []*domain.UserMembership, cascade bool) (_ []eventstore.Command, err error) { +func (c *Commands) removeUserMemberships(ctx context.Context, memberships []*query.Membership) (_ []eventstore.Command, err error) { events := make([]eventstore.Command, 0) for _, membership := range memberships { - switch membership.MemberType { - case domain.MemberTypeIam: + if membership.IAM != nil { iamAgg := iam.NewAggregate() removeEvent := c.removeIAMMember(ctx, &iamAgg.Aggregate, membership.UserID, true) events = append(events, removeEvent) - case domain.MemberTypeOrganisation: - iamAgg := org.NewAggregate(membership.AggregateID, membership.ResourceOwner) + } else if membership.Org != nil { + iamAgg := org.NewAggregate(membership.Org.OrgID, membership.ResourceOwner) removeEvent := c.removeOrgMember(ctx, &iamAgg.Aggregate, membership.UserID, true) events = append(events, removeEvent) - case domain.MemberTypeProject: - projectAgg := project.NewAggregate(membership.AggregateID, membership.ResourceOwner) + } else if membership.Project != nil { + projectAgg := project.NewAggregate(membership.Project.ProjectID, membership.ResourceOwner) removeEvent := c.removeProjectMember(ctx, &projectAgg.Aggregate, membership.UserID, true) events = append(events, removeEvent) - case domain.MemberTypeProjectGrant: - projectAgg := project.NewAggregate(membership.AggregateID, membership.ResourceOwner) - removeEvent := c.removeProjectGrantMember(ctx, &projectAgg.Aggregate, membership.UserID, membership.ObjectID, true) + } else if membership.ProjectGrant != nil { + projectAgg := project.NewAggregate(membership.ProjectGrant.ProjectID, membership.ResourceOwner) + removeEvent := c.removeProjectGrantMember(ctx, &projectAgg.Aggregate, membership.UserID, membership.ProjectGrant.GrantID, true) events = append(events, removeEvent) } } diff --git a/internal/command/user_test.go b/internal/command/user_test.go index 1d322d87ea..41475aa821 100644 --- a/internal/command/user_test.go +++ b/internal/command/user_test.go @@ -13,6 +13,7 @@ import ( "github.com/caos/zitadel/internal/eventstore" "github.com/caos/zitadel/internal/eventstore/repository" "github.com/caos/zitadel/internal/id" + "github.com/caos/zitadel/internal/query" "github.com/caos/zitadel/internal/repository/iam" "github.com/caos/zitadel/internal/repository/member" "github.com/caos/zitadel/internal/repository/org" @@ -920,7 +921,7 @@ func TestCommandSide_RemoveUser(t *testing.T) { ctx context.Context orgID string userID string - cascadeUserMemberships []*domain.UserMembership + cascadeUserMemberships []*query.Membership cascadeUserGrants []string } ) @@ -1200,31 +1201,36 @@ func TestCommandSide_RemoveUser(t *testing.T) { ctx: context.Background(), orgID: "org1", userID: "user1", - cascadeUserMemberships: []*domain.UserMembership{ + cascadeUserMemberships: []*query.Membership{ { - MemberType: domain.MemberTypeIam, + IAM: &query.IAMMembership{ + IAMID: "IAM", + }, UserID: "user1", - AggregateID: "IAM", ResourceOwner: "org1", }, { - MemberType: domain.MemberTypeOrganisation, + Org: &query.OrgMembership{ + OrgID: "org1", + }, UserID: "user1", ResourceOwner: "org1", - AggregateID: "org1", }, { - MemberType: domain.MemberTypeProject, + + Project: &query.ProjectMembership{ + ProjectID: "project1", + }, UserID: "user1", ResourceOwner: "org1", - AggregateID: "project1", }, { - MemberType: domain.MemberTypeProjectGrant, + ProjectGrant: &query.ProjectGrantMembership{ + ProjectID: "project1", + GrantID: "grant1", + }, UserID: "user1", ResourceOwner: "org1", - AggregateID: "project1", - ObjectID: "grant1", }, }, }, diff --git a/internal/management/repository/eventsourcing/eventstore/org.go b/internal/management/repository/eventsourcing/eventstore/org.go index 6cf55fe1cf..56a14f28c2 100644 --- a/internal/management/repository/eventsourcing/eventstore/org.go +++ b/internal/management/repository/eventsourcing/eventstore/org.go @@ -3,9 +3,7 @@ package eventstore import ( "context" "encoding/json" - "io/ioutil" "net/http" - "os" "strings" "sync" "time" @@ -14,21 +12,16 @@ import ( "github.com/golang/protobuf/ptypes" "golang.org/x/text/language" - "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" v1 "github.com/caos/zitadel/internal/eventstore/v1" "github.com/caos/zitadel/internal/eventstore/v1/models" "github.com/caos/zitadel/internal/i18n" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" mgmt_view "github.com/caos/zitadel/internal/management/repository/eventsourcing/view" org_model "github.com/caos/zitadel/internal/org/model" org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" org_view "github.com/caos/zitadel/internal/org/repository/view" - "github.com/caos/zitadel/internal/org/repository/view/model" "github.com/caos/zitadel/internal/query" usr_model "github.com/caos/zitadel/internal/user/model" "github.com/caos/zitadel/internal/user/repository/view" @@ -86,124 +79,19 @@ func (repo *OrgRepository) OrgChanges(ctx context.Context, id string, lastSequen return changes, nil } -func (repo *OrgRepository) OrgMemberByID(ctx context.Context, orgID, userID string) (*org_model.OrgMemberView, error) { - member, err := repo.View.OrgMemberByIDs(orgID, userID) - if err != nil { - return nil, err - } - return model.OrgMemberToModel(member, repo.PrefixAvatarURL), nil -} - -func (repo *OrgRepository) SearchMyOrgMembers(ctx context.Context, request *org_model.OrgMemberSearchRequest) (*org_model.OrgMemberSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - request.Queries = append(request.Queries, &org_model.OrgMemberSearchQuery{Key: org_model.OrgMemberSearchKeyOrgID, Method: domain.SearchMethodEquals, Value: authz.GetCtxData(ctx).OrgID}) - sequence, sequenceErr := repo.View.GetLatestOrgMemberSequence() - logging.Log("EVENT-Smu3d").OnError(sequenceErr).Warn("could not read latest org member sequence") - members, count, err := repo.View.SearchOrgMembers(request) - if err != nil { - return nil, err - } - result := &org_model.OrgMemberSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: model.OrgMembersToModel(members, repo.PrefixAvatarURL), - } - if sequenceErr == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - -func (repo *OrgRepository) GetOrgMemberRoles() []string { +func (repo *OrgRepository) GetOrgMemberRoles(isGlobal bool) []string { roles := make([]string, 0) for _, roleMap := range repo.Roles { if strings.HasPrefix(roleMap, "ORG") { roles = append(roles, roleMap) } } + if isGlobal { + roles = append(roles, domain.RoleSelfManagementGlobal) + } return roles } -func (repo *OrgRepository) IDPConfigByID(ctx context.Context, idpConfigID string) (*iam_model.IDPConfigView, error) { - idp, err := repo.View.IDPConfigByID(idpConfigID) - if err != nil { - return nil, err - } - return iam_view_model.IDPConfigViewToModel(idp), nil -} - -func (repo *OrgRepository) SearchIDPConfigs(ctx context.Context, request *iam_model.IDPConfigSearchRequest) (*iam_model.IDPConfigSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - request.AppendMyOrgQuery(authz.GetCtxData(ctx).OrgID, repo.SystemDefaults.IamID) - - sequence, sequenceErr := repo.View.GetLatestIDPConfigSequence() - logging.Log("EVENT-Dk8si").OnError(sequenceErr).Warn("could not read latest idp config sequence") - idps, count, err := repo.View.SearchIDPConfigs(request) - if err != nil { - return nil, err - } - result := &iam_model.IDPConfigSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: iam_view_model.IdpConfigViewsToModel(idps), - } - if sequenceErr == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - -func (repo *OrgRepository) GetIDPProvidersByIDPConfigID(ctx context.Context, aggregateID, idpConfigID string) ([]*iam_model.IDPProviderView, error) { - idpProviders, err := repo.View.IDPProvidersByIdpConfigID(aggregateID, idpConfigID) - if err != nil { - return nil, err - } - return iam_view_model.IDPProviderViewsToModel(idpProviders), err -} - -func (repo *OrgRepository) SearchIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) { - policy, err := repo.Query.LoginPolicyByID(ctx, authz.GetCtxData(ctx).OrgID) - if err != nil { - return nil, err - } - if policy.IsDefault { - request.AppendAggregateIDQuery(domain.IAMID) - } else { - request.AppendAggregateIDQuery(authz.GetCtxData(ctx).OrgID) - } - err = request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - sequence, sequenceErr := repo.View.GetLatestIDPProviderSequence() - logging.Log("EVENT-Tuiks").OnError(sequenceErr).Warn("could not read latest iam sequence") - providers, count, err := repo.View.SearchIDPProviders(request) - if err != nil { - return nil, err - } - result := &iam_model.IDPProviderSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: iam_view_model.IDPProviderViewsToModel(providers), - } - if sequenceErr == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - func (repo *OrgRepository) getOrgChanges(ctx context.Context, orgID string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (*org_model.OrgChanges, error) { query := org_view.ChangesQuery(orgID, lastSequence, limit, sortAscending, auditLogRetention) @@ -283,34 +171,3 @@ func (r *OrgRepository) getUserEvents(ctx context.Context, userID string, sequen return r.Eventstore.FilterEvents(ctx, query) } - -func (es *OrgRepository) getOrgEvents(ctx context.Context, id string, sequence uint64) ([]*models.Event, error) { - query, err := org_view.OrgByIDQuery(id, sequence) - if err != nil { - return nil, err - } - return es.Eventstore.FilterEvents(ctx, query) -} - -func (repo *OrgRepository) getIAMEvents(ctx context.Context, sequence uint64) ([]*models.Event, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, sequence) - if err != nil { - return nil, err - } - return repo.Eventstore.FilterEvents(ctx, query) -} - -func (repo *OrgRepository) readTranslationFile(dir http.FileSystem, filename string) ([]byte, error) { - r, err := dir.Open(filename) - if os.IsNotExist(err) { - return nil, errors.ThrowNotFound(err, "TEXT-93nfl", "Errors.TranslationFile.NotFound") - } - if err != nil { - return nil, errors.ThrowInternal(err, "TEXT-3n8fs", "Errors.TranslationFile.ReadError") - } - contents, err := ioutil.ReadAll(r) - if err != nil { - return nil, errors.ThrowInternal(err, "TEXT-322fs", "Errors.TranslationFile.ReadError") - } - return contents, nil -} diff --git a/internal/management/repository/eventsourcing/eventstore/project.go b/internal/management/repository/eventsourcing/eventstore/project.go index d8d82cb84b..8a4b26a906 100644 --- a/internal/management/repository/eventsourcing/eventstore/project.go +++ b/internal/management/repository/eventsourcing/eventstore/project.go @@ -10,18 +10,13 @@ import ( "github.com/golang/protobuf/ptypes" "github.com/caos/zitadel/internal/api/authz" - "github.com/caos/zitadel/internal/domain" caos_errs "github.com/caos/zitadel/internal/errors" v1 "github.com/caos/zitadel/internal/eventstore/v1" "github.com/caos/zitadel/internal/eventstore/v1/models" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" "github.com/caos/zitadel/internal/management/repository/eventsourcing/view" proj_model "github.com/caos/zitadel/internal/project/model" proj_view "github.com/caos/zitadel/internal/project/repository/view" - "github.com/caos/zitadel/internal/project/repository/view/model" + "github.com/caos/zitadel/internal/query" usr_model "github.com/caos/zitadel/internal/user/model" usr_view "github.com/caos/zitadel/internal/user/repository/view" usr_es_model "github.com/caos/zitadel/internal/user/repository/view/model" @@ -34,38 +29,7 @@ type ProjectRepo struct { Roles []string IAMID string PrefixAvatarURL string -} - -func (repo *ProjectRepo) ProjectMemberByID(ctx context.Context, projectID, userID string) (*proj_model.ProjectMemberView, error) { - member, err := repo.View.ProjectMemberByIDs(projectID, userID) - if err != nil { - return nil, err - } - return model.ProjectMemberToModel(member, repo.PrefixAvatarURL), nil -} - -func (repo *ProjectRepo) SearchProjectMembers(ctx context.Context, request *proj_model.ProjectMemberSearchRequest) (*proj_model.ProjectMemberSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - sequence, sequenceErr := repo.View.GetLatestProjectMemberSequence() - logging.Log("EVENT-3dgt6").OnError(sequenceErr).Warn("could not read latest project member sequence") - members, count, err := repo.View.SearchProjectMembers(request) - if err != nil { - return nil, err - } - result := &proj_model.ProjectMemberSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: uint64(count), - Result: model.ProjectMembersToModel(members, repo.PrefixAvatarURL), - } - if sequenceErr == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil + Query *query.Queries } func (repo *ProjectRepo) ProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool, retention time.Duration) (*proj_model.ProjectChanges, error) { @@ -114,40 +78,8 @@ func (repo *ProjectRepo) ApplicationChanges(ctx context.Context, projectID strin return changes, nil } -func (repo *ProjectRepo) ProjectGrantMemberByID(ctx context.Context, projectID, userID string) (*proj_model.ProjectGrantMemberView, error) { - member, err := repo.View.ProjectGrantMemberByIDs(projectID, userID) - if err != nil { - return nil, err - } - return model.ProjectGrantMemberToModel(member, repo.PrefixAvatarURL), nil -} - -func (repo *ProjectRepo) SearchProjectGrantMembers(ctx context.Context, request *proj_model.ProjectGrantMemberSearchRequest) (*proj_model.ProjectGrantMemberSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - sequence, sequenceErr := repo.View.GetLatestProjectGrantMemberSequence() - logging.Log("EVENT-Du8sk").OnError(sequenceErr).Warn("could not read latest project grant sequence") - members, count, err := repo.View.SearchProjectGrantMembers(request) - if err != nil { - return nil, err - } - result := &proj_model.ProjectGrantMemberSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: uint64(count), - Result: model.ProjectGrantMembersToModel(members, repo.PrefixAvatarURL), - } - if sequenceErr == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - func (repo *ProjectRepo) GetProjectMemberRoles(ctx context.Context) ([]string, error) { - iam, err := repo.GetIAMByID(ctx) + iam, err := repo.Query.IAMByID(ctx, repo.IAMID) if err != nil { return nil, err } @@ -311,20 +243,3 @@ func (repo *ProjectRepo) getApplicationChanges(ctx context.Context, projectID st LastSequence: lastSequence, }, nil } - -func (u *ProjectRepo) GetIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &iam_es_model.IAM{ - ObjectRoot: models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore.FilterEvents, iam.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} diff --git a/internal/management/repository/eventsourcing/eventstore/user.go b/internal/management/repository/eventsourcing/eventstore/user.go index 5c9a5ecdeb..3f78122ada 100644 --- a/internal/management/repository/eventsourcing/eventstore/user.go +++ b/internal/management/repository/eventsourcing/eventstore/user.go @@ -227,46 +227,6 @@ func (repo *UserRepo) ProfileByID(ctx context.Context, userID string) (*usr_mode return user.GetProfile() } -func (repo *UserRepo) SearchExternalIDPs(ctx context.Context, request *usr_model.ExternalIDPSearchRequest) (*usr_model.ExternalIDPSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - sequence, seqErr := repo.View.GetLatestExternalIDPSequence() - logging.Log("EVENT-Qs7uf").OnError(seqErr).Warn("could not read latest external idp sequence") - externalIDPS, count, err := repo.View.SearchExternalIDPs(request) - if err != nil { - return nil, err - } - result := &usr_model.ExternalIDPSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: model.ExternalIDPViewsToModel(externalIDPS), - } - if seqErr == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - -func (repo *UserRepo) ExternalIDPsByIDPConfigID(ctx context.Context, idpConfigID string) ([]*usr_model.ExternalIDPView, error) { - externalIDPs, err := repo.View.ExternalIDPsByIDPConfigID(idpConfigID) - if err != nil { - return nil, err - } - return model.ExternalIDPViewsToModel(externalIDPs), nil -} - -func (repo *UserRepo) ExternalIDPsByIDPConfigIDAndResourceOwner(ctx context.Context, idpConfigID, resourceOwner string) ([]*usr_model.ExternalIDPView, error) { - externalIDPs, err := repo.View.ExternalIDPsByIDPConfigIDAndResourceOwner(idpConfigID, resourceOwner) - if err != nil { - return nil, err - } - return model.ExternalIDPViewsToModel(externalIDPs), nil -} - func (repo *UserRepo) EmailByID(ctx context.Context, userID string) (*usr_model.Email, error) { user, err := repo.UserByID(ctx, userID) if err != nil { @@ -300,44 +260,6 @@ func (repo *UserRepo) AddressByID(ctx context.Context, userID string) (*usr_mode return user.GetAddress() } -func (repo *UserRepo) SearchUserMemberships(ctx context.Context, request *usr_model.UserMembershipSearchRequest) (*usr_model.UserMembershipSearchResponse, error) { - err := request.EnsureLimit(repo.SearchLimit) - if err != nil { - return nil, err - } - sequence, sequenceErr := repo.View.GetLatestUserMembershipSequence() - logging.Log("EVENT-Dn7sf").OnError(sequenceErr).Warn("could not read latest user sequence") - - result := handleSearchUserMembershipsPermissions(ctx, request, sequence) - if result != nil { - return result, nil - } - - memberships, count, err := repo.View.SearchUserMemberships(request) - if err != nil { - return nil, err - } - result = &usr_model.UserMembershipSearchResponse{ - Offset: request.Offset, - Limit: request.Limit, - TotalResult: count, - Result: model.UserMembershipsToModel(memberships), - } - if sequenceErr == nil { - result.Sequence = sequence.CurrentSequence - result.Timestamp = sequence.LastSuccessfulSpoolerRun - } - return result, nil -} - -func (repo *UserRepo) UserMembershipsByUserID(ctx context.Context, userID string) ([]*usr_model.UserMembershipView, error) { - memberships, err := repo.View.UserMembershipsByUserID(userID) - if err != nil { - return nil, err - } - return model.UserMembershipsToModel(memberships), nil -} - func (r *UserRepo) getUserChanges(ctx context.Context, userID string, lastSequence uint64, limit uint64, sortAscending bool, retention time.Duration) (*usr_model.UserChanges, error) { query := usr_view.ChangesQuery(userID, lastSequence, limit, sortAscending, retention) diff --git a/internal/management/repository/eventsourcing/handler/handler.go b/internal/management/repository/eventsourcing/handler/handler.go index 71c432835f..1764f8056a 100644 --- a/internal/management/repository/eventsourcing/handler/handler.go +++ b/internal/management/repository/eventsourcing/handler/handler.go @@ -33,23 +33,9 @@ func (h *handler) Eventstore() v1.Eventstore { func Register(configs Configs, bulkLimit, errorCount uint64, view *view.View, es v1.Eventstore, defaults systemdefaults.SystemDefaults, staticStorage static.Storage) []query.Handler { return []query.Handler{ - newProjectMember(handler{view, bulkLimit, configs.cycleDuration("ProjectMember"), errorCount, es}), - newProjectGrantMember(handler{view, bulkLimit, configs.cycleDuration("ProjectGrantMember"), errorCount, es}), newUser(handler{view, bulkLimit, configs.cycleDuration("User"), errorCount, es}, defaults.IamID), newUserGrant(handler{view, bulkLimit, configs.cycleDuration("UserGrant"), errorCount, es}), - newOrgMember( - handler{view, bulkLimit, configs.cycleDuration("OrgMember"), errorCount, es}), - newUserMembership( - handler{view, bulkLimit, configs.cycleDuration("UserMembership"), errorCount, es}), - newIDPConfig( - handler{view, bulkLimit, configs.cycleDuration("IDPConfig"), errorCount, es}), - newIDPProvider( - handler{view, bulkLimit, configs.cycleDuration("IDPProvider"), errorCount, es}, - defaults), - newExternalIDP( - handler{view, bulkLimit, configs.cycleDuration("ExternalIDP"), errorCount, es}, - defaults), newMetadata( handler{view, bulkLimit, configs.cycleDuration("Metadata"), errorCount, es}), } diff --git a/internal/management/repository/eventsourcing/handler/idp_config.go b/internal/management/repository/eventsourcing/handler/idp_config.go deleted file mode 100644 index 4e510303e3..0000000000 --- a/internal/management/repository/eventsourcing/handler/idp_config.go +++ /dev/null @@ -1,139 +0,0 @@ -package handler - -import ( - "github.com/caos/logging" - "github.com/caos/zitadel/internal/eventstore/v1" - "github.com/caos/zitadel/internal/repository/iam" - "github.com/caos/zitadel/internal/repository/org" - - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" - "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" -) - -const ( - idpConfigTable = "management.idp_configs" -) - -type IDPConfig struct { - handler - subscription *v1.Subscription -} - -func newIDPConfig(handler handler) *IDPConfig { - h := &IDPConfig{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (m *IDPConfig) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (m *IDPConfig) ViewModel() string { - return idpConfigTable -} - -func (m *IDPConfig) Subscription() *v1.Subscription { - return m.subscription -} - -func (_ *IDPConfig) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.OrgAggregate, iam_es_model.IAMAggregate} -} - -func (m *IDPConfig) CurrentSequence() (uint64, error) { - sequence, err := m.view.GetLatestIDPConfigSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (m *IDPConfig) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestIDPConfigSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(m.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (m *IDPConfig) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.OrgAggregate: - err = m.processIdpConfig(iam_model.IDPProviderTypeOrg, event) - case iam_es_model.IAMAggregate: - err = m.processIdpConfig(iam_model.IDPProviderTypeSystem, event) - } - return err -} - -func (m *IDPConfig) processIdpConfig(providerType iam_model.IDPProviderType, event *es_models.Event) (err error) { - idp := new(iam_view_model.IDPConfigView) - switch event.Type { - case model.IDPConfigAdded, - iam_es_model.IDPConfigAdded: - err = idp.AppendEvent(providerType, event) - case model.IDPConfigChanged, iam_es_model.IDPConfigChanged, - model.OIDCIDPConfigAdded, iam_es_model.OIDCIDPConfigAdded, - model.OIDCIDPConfigChanged, iam_es_model.OIDCIDPConfigChanged, - es_models.EventType(org.IDPJWTConfigAddedEventType), es_models.EventType(iam.IDPJWTConfigAddedEventType), - es_models.EventType(org.IDPJWTConfigChangedEventType), es_models.EventType(iam.IDPJWTConfigChangedEventType): - err = idp.SetData(event) - if err != nil { - return err - } - idp, err = m.view.IDPConfigByID(idp.IDPConfigID) - if err != nil { - return err - } - err = idp.AppendEvent(providerType, event) - case model.IDPConfigDeactivated, iam_es_model.IDPConfigDeactivated, - model.IDPConfigReactivated, iam_es_model.IDPConfigReactivated: - err = idp.SetData(event) - if err != nil { - return err - } - idp, err = m.view.IDPConfigByID(idp.IDPConfigID) - if err != nil { - return err - } - err = idp.AppendEvent(providerType, event) - case model.IDPConfigRemoved, iam_es_model.IDPConfigRemoved: - err = idp.SetData(event) - if err != nil { - return err - } - return m.view.DeleteIDPConfig(idp.IDPConfigID, event) - default: - return m.view.ProcessedIDPConfigSequence(event) - } - if err != nil { - return err - } - return m.view.PutIDPConfig(idp, event) -} - -func (i *IDPConfig) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-Nxu8s", "id", event.AggregateID).WithError(err).Warn("something went wrong in idp config handler") - return spooler.HandleError(event, err, i.view.GetLatestIDPConfigFailedEvent, i.view.ProcessedIDPConfigFailedEvent, i.view.ProcessedIDPConfigSequence, i.errorCountUntilSkip) -} - -func (i *IDPConfig) OnSuccess() error { - return spooler.HandleSuccess(i.view.UpdateIDPConfigSpoolerRunTimestamp) -} diff --git a/internal/management/repository/eventsourcing/handler/idp_providers.go b/internal/management/repository/eventsourcing/handler/idp_providers.go deleted file mode 100644 index 00ecfb3ff4..0000000000 --- a/internal/management/repository/eventsourcing/handler/idp_providers.go +++ /dev/null @@ -1,234 +0,0 @@ -package handler - -import ( - "context" - "github.com/caos/logging" - "github.com/caos/zitadel/internal/config/systemdefaults" - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" - org_model "github.com/caos/zitadel/internal/org/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/org/repository/view" -) - -const ( - idpProviderTable = "management.idp_providers" -) - -type IDPProvider struct { - handler - systemDefaults systemdefaults.SystemDefaults - subscription *v1.Subscription -} - -func newIDPProvider( - handler handler, - systemDefaults systemdefaults.SystemDefaults, -) *IDPProvider { - h := &IDPProvider{ - handler: handler, - systemDefaults: systemDefaults, - } - - h.subscribe() - - return h -} - -func (m *IDPProvider) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (m *IDPProvider) ViewModel() string { - return idpProviderTable -} - -func (p *IDPProvider) Subscription() *v1.Subscription { - return p.subscription -} - -func (_ *IDPProvider) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.IAMAggregate, org_es_model.OrgAggregate} -} - -func (m *IDPProvider) CurrentSequence() (uint64, error) { - sequence, err := m.view.GetLatestIDPProviderSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (m *IDPProvider) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestIDPProviderSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(m.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (m *IDPProvider) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.IAMAggregate, org_es_model.OrgAggregate: - err = m.processIdpProvider(event) - } - return err -} - -func (m *IDPProvider) processIdpProvider(event *es_models.Event) (err error) { - provider := new(iam_view_model.IDPProviderView) - switch event.Type { - case model.LoginPolicyIDPProviderAdded, org_es_model.LoginPolicyIDPProviderAdded: - err = provider.AppendEvent(event) - if err != nil { - return err - } - err = m.fillData(provider) - case model.LoginPolicyIDPProviderRemoved, model.LoginPolicyIDPProviderCascadeRemoved, - org_es_model.LoginPolicyIDPProviderRemoved, org_es_model.LoginPolicyIDPProviderCascadeRemoved: - err = provider.SetData(event) - if err != nil { - return err - } - return m.view.DeleteIDPProvider(event.AggregateID, provider.IDPConfigID, event) - case model.IDPConfigChanged, org_es_model.IDPConfigChanged: - esConfig := new(iam_view_model.IDPConfigView) - providerType := iam_model.IDPProviderTypeSystem - if event.AggregateID != m.systemDefaults.IamID { - providerType = iam_model.IDPProviderTypeOrg - } - esConfig.AppendEvent(providerType, event) - providers, err := m.view.IDPProvidersByIdpConfigID(event.AggregateID, esConfig.IDPConfigID) - if err != nil { - return err - } - config := new(iam_model.IDPConfig) - if event.AggregateID == m.systemDefaults.IamID { - config, err = m.getDefaultIDPConfig(context.Background(), esConfig.IDPConfigID) - } else { - config, err = m.getOrgIDPConfig(context.Background(), event.AggregateID, esConfig.IDPConfigID) - } - if err != nil { - return err - } - for _, provider := range providers { - m.fillConfigData(provider, config) - } - return m.view.PutIDPProviders(event, providers...) - case org_es_model.LoginPolicyRemoved: - return m.view.DeleteIDPProvidersByAggregateID(event.AggregateID, event) - default: - return m.view.ProcessedIDPProviderSequence(event) - } - if err != nil { - return err - } - return m.view.PutIDPProvider(provider, event) -} - -func (m *IDPProvider) fillData(provider *iam_view_model.IDPProviderView) (err error) { - var config *iam_model.IDPConfig - if provider.IDPProviderType == int32(iam_model.IDPProviderTypeSystem) { - config, err = m.getDefaultIDPConfig(context.Background(), provider.IDPConfigID) - } else { - config, err = m.getOrgIDPConfig(context.Background(), provider.AggregateID, provider.IDPConfigID) - } - if err != nil { - return err - } - m.fillConfigData(provider, config) - return nil -} - -func (m *IDPProvider) fillConfigData(provider *iam_view_model.IDPProviderView, config *iam_model.IDPConfig) { - provider.Name = config.Name - provider.StylingType = int32(config.StylingType) - provider.IDPConfigType = int32(config.Type) - provider.IDPState = int32(config.State) -} - -func (m *IDPProvider) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-Msj8c", "id", event.AggregateID).WithError(err).Warn("something went wrong in idp provider handler") - return spooler.HandleError(event, err, m.view.GetLatestIDPProviderFailedEvent, m.view.ProcessedIDPProviderFailedEvent, m.view.ProcessedIDPProviderSequence, m.errorCountUntilSkip) -} - -func (m *IDPProvider) OnSuccess() error { - return spooler.HandleSuccess(m.view.UpdateIDPProviderSpoolerRunTimestamp) -} - -func (i *IDPProvider) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) { - existing, err := i.getOrgByID(ctx, aggregateID) - if err != nil { - return nil, err - } - if _, i := existing.GetIDP(idpConfigID); i != nil { - return i, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-2m9dS", "Errors.Org.IdpNotExisting") -} - -func (i *IDPProvider) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-4n9fs", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *IDPProvider) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return model.IAMToModel(iam), nil -} - -func (u *IDPProvider) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) { - existing, err := u.getIAMByID(ctx) - if err != nil { - return nil, err - } - if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil { - return existingIDP, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-4M0fs", "Errors.IAM.IdpNotExisting") -} diff --git a/internal/management/repository/eventsourcing/handler/org_member.go b/internal/management/repository/eventsourcing/handler/org_member.go deleted file mode 100644 index 2b140a25c9..0000000000 --- a/internal/management/repository/eventsourcing/handler/org_member.go +++ /dev/null @@ -1,289 +0,0 @@ -package handler - -import ( - "context" - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - org_view "github.com/caos/zitadel/internal/org/repository/view" - "github.com/caos/zitadel/internal/user/repository/view" - - "github.com/caos/logging" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - 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" - org_view_model "github.com/caos/zitadel/internal/org/repository/view/model" - usr_model "github.com/caos/zitadel/internal/user/model" - usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model" -) - -const ( - orgMemberTable = "management.org_members" -) - -type OrgMember struct { - handler - subscription *v1.Subscription -} - -func newOrgMember( - handler handler, -) *OrgMember { - h := &OrgMember{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (m *OrgMember) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (m *OrgMember) ViewModel() string { - return orgMemberTable -} - -func (m *OrgMember) Subscription() *v1.Subscription { - return m.subscription -} - -func (_ *OrgMember) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.OrgAggregate, usr_es_model.UserAggregate} -} - -func (p *OrgMember) CurrentSequence() (uint64, error) { - sequence, err := p.view.GetLatestOrgMemberSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (m *OrgMember) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestOrgMemberSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(m.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (m *OrgMember) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.OrgAggregate: - err = m.processOrgMember(event) - case usr_es_model.UserAggregate: - err = m.processUser(event) - } - return err -} - -func (m *OrgMember) processOrgMember(event *es_models.Event) (err error) { - member := new(org_view_model.OrgMemberView) - switch event.Type { - case model.OrgMemberAdded: - err = member.AppendEvent(event) - if err != nil { - return err - } - err = m.fillData(member) - case model.OrgMemberChanged: - err = member.SetData(event) - if err != nil { - return err - } - member, err = m.view.OrgMemberByIDs(event.AggregateID, member.UserID) - if err != nil { - return err - } - err = member.AppendEvent(event) - case model.OrgMemberRemoved, - model.OrgMemberCascadeRemoved: - err = member.SetData(event) - if err != nil { - return err - } - return m.view.DeleteOrgMember(event.AggregateID, member.UserID, event) - default: - return m.view.ProcessedOrgMemberSequence(event) - } - if err != nil { - return err - } - return m.view.PutOrgMember(member, event) -} - -func (m *OrgMember) processUser(event *es_models.Event) (err error) { - switch event.Type { - case usr_es_model.UserProfileChanged, - usr_es_model.UserEmailChanged, - usr_es_model.HumanProfileChanged, - usr_es_model.HumanEmailChanged, - usr_es_model.MachineChanged, - usr_es_model.HumanAvatarAdded, - usr_es_model.HumanAvatarRemoved: - members, err := m.view.OrgMembersByUserID(event.AggregateID) - if err != nil { - return err - } - if len(members) == 0 { - return m.view.ProcessedOrgMemberSequence(event) - } - user, err := m.getUserByID(event.AggregateID) - if err != nil { - return err - } - for _, member := range members { - m.fillUserData(member, user) - } - return m.view.PutOrgMembers(members, event) - case usr_es_model.UserRemoved: - return m.view.DeleteOrgMembersByUserID(event.AggregateID, event) - default: - return m.view.ProcessedOrgMemberSequence(event) - } -} - -func (m *OrgMember) fillData(member *org_view_model.OrgMemberView) (err error) { - user, err := m.getUserByID(member.UserID) - if err != nil { - return err - } - return m.fillUserData(member, user) -} - -func (m *OrgMember) fillUserData(member *org_view_model.OrgMemberView, user *usr_view_model.UserView) error { - org, err := m.getOrgByID(context.Background(), user.ResourceOwner) - if err != nil { - return err - } - policy := org.OrgIamPolicy - if policy == nil { - policy, err = m.getDefaultOrgIAMPolicy(context.TODO()) - if err != nil { - return err - } - } - member.UserName = user.UserName - member.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain) - member.UserResourceOwner = user.ResourceOwner - if user.HumanView != nil { - member.FirstName = user.FirstName - member.LastName = user.LastName - member.DisplayName = user.DisplayName - member.Email = user.Email - member.AvatarKey = user.AvatarKey - } - if user.MachineView != nil { - member.DisplayName = user.MachineView.Name - } - return nil -} - -func (m *OrgMember) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-u73es", "id", event.AggregateID).WithError(err).Warn("something went wrong in orgmember handler") - return spooler.HandleError(event, err, m.view.GetLatestOrgMemberFailedEvent, m.view.ProcessedOrgMemberFailedEvent, m.view.ProcessedOrgMemberSequence, m.errorCountUntilSkip) -} - -func (o *OrgMember) OnSuccess() error { - return spooler.HandleSuccess(o.view.UpdateOrgMemberSpoolerRunTimestamp) -} - -func (u *OrgMember) getUserByID(userID string) (*usr_view_model.UserView, error) { - user, usrErr := u.view.UserByID(userID) - if usrErr != nil && !caos_errs.IsNotFound(usrErr) { - return nil, usrErr - } - if user == nil { - user = &usr_view_model.UserView{} - } - events, err := u.getUserEvents(userID, user.Sequence) - if err != nil { - return user, usrErr - } - userCopy := *user - for _, event := range events { - if err := userCopy.AppendEvent(event); err != nil { - return user, nil - } - } - if userCopy.State == int32(usr_model.UserStateDeleted) { - return nil, caos_errs.ThrowNotFound(nil, "HANDLER-m9dos", "Errors.User.NotFound") - } - return &userCopy, nil -} - -func (u *OrgMember) getUserEvents(userID string, sequence uint64) ([]*es_models.Event, error) { - query, err := view.UserByIDQuery(userID, sequence) - if err != nil { - return nil, err - } - - return u.es.FilterEvents(context.Background(), query) -} - -func (u *OrgMember) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := org_view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound") - } - - return model.OrgToModel(esOrg), nil -} - -func (u *OrgMember) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) { - existingIAM, err := u.getIAMByID(ctx) - if err != nil { - return nil, err - } - if existingIAM.DefaultOrgIAMPolicy == nil { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-2Fj8s", "Errors.IAM.OrgIAMPolicy.NotExisting") - } - return existingIAM.DefaultOrgIAMPolicy, nil -} - -func (u *OrgMember) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &iam_es_model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} diff --git a/internal/management/repository/eventsourcing/handler/project_grant_member.go b/internal/management/repository/eventsourcing/handler/project_grant_member.go deleted file mode 100644 index 261c1239a1..0000000000 --- a/internal/management/repository/eventsourcing/handler/project_grant_member.go +++ /dev/null @@ -1,297 +0,0 @@ -package handler - -import ( - "context" - - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - org_model "github.com/caos/zitadel/internal/org/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - org_view "github.com/caos/zitadel/internal/org/repository/view" - "github.com/caos/zitadel/internal/user/repository/view" - usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model" - - "github.com/caos/logging" - - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - view_model "github.com/caos/zitadel/internal/project/repository/view/model" - usr_model "github.com/caos/zitadel/internal/user/model" - usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" -) - -const ( - projectGrantMemberTable = "management.project_grant_members" -) - -type ProjectGrantMember struct { - handler - subscription *v1.Subscription -} - -func newProjectGrantMember( - handler handler, -) *ProjectGrantMember { - h := &ProjectGrantMember{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (m *ProjectGrantMember) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (p *ProjectGrantMember) ViewModel() string { - return projectGrantMemberTable -} - -func (p *ProjectGrantMember) Subscription() *v1.Subscription { - return p.subscription -} - -func (_ *ProjectGrantMember) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{proj_es_model.ProjectAggregate, usr_es_model.UserAggregate} -} - -func (p *ProjectGrantMember) CurrentSequence() (uint64, error) { - sequence, err := p.view.GetLatestProjectGrantMemberSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (p *ProjectGrantMember) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := p.view.GetLatestProjectGrantMemberSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(p.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (p *ProjectGrantMember) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case proj_es_model.ProjectAggregate: - err = p.processProjectGrantMember(event) - case usr_es_model.UserAggregate: - err = p.processUser(event) - } - return err -} - -func (p *ProjectGrantMember) processProjectGrantMember(event *es_models.Event) (err error) { - member := new(view_model.ProjectGrantMemberView) - switch event.Type { - case proj_es_model.ProjectGrantMemberAdded: - err = member.AppendEvent(event) - if err != nil { - return err - } - err = p.fillData(member) - case proj_es_model.ProjectGrantMemberChanged: - err = member.SetData(event) - if err != nil { - return err - } - member, err = p.view.ProjectGrantMemberByIDs(member.GrantID, member.UserID) - if err != nil { - return err - } - err = member.AppendEvent(event) - case proj_es_model.ProjectGrantMemberRemoved, - proj_es_model.ProjectGrantMemberCascadeRemoved: - err = member.SetData(event) - if err != nil { - return err - } - return p.view.DeleteProjectGrantMember(member.GrantID, member.UserID, event) - case proj_es_model.ProjectRemoved: - err = p.view.DeleteProjectGrantMembersByProjectID(event.AggregateID) - if err != nil { - return err - } - return p.view.ProcessedProjectGrantMemberSequence(event) - default: - return p.view.ProcessedProjectGrantMemberSequence(event) - } - if err != nil { - return err - } - return p.view.PutProjectGrantMember(member, event) -} - -func (p *ProjectGrantMember) processUser(event *es_models.Event) (err error) { - switch event.Type { - case usr_es_model.UserProfileChanged, - usr_es_model.UserEmailChanged, - usr_es_model.HumanProfileChanged, - usr_es_model.HumanEmailChanged, - usr_es_model.MachineChanged, - usr_es_model.HumanAvatarAdded, - usr_es_model.HumanAvatarRemoved: - members, err := p.view.ProjectGrantMembersByUserID(event.AggregateID) - if err != nil { - return err - } - if len(members) == 0 { - return p.view.ProcessedProjectGrantMemberSequence(event) - } - user, err := p.getUserByID(event.AggregateID) - if err != nil { - return err - } - for _, member := range members { - p.fillUserData(member, user) - } - return p.view.PutProjectGrantMembers(members, event) - case usr_es_model.UserRemoved: - p.view.DeleteProjectGrantMembersByUserID(event.AggregateID) - default: - return p.view.ProcessedProjectGrantMemberSequence(event) - } - return nil -} - -func (p *ProjectGrantMember) fillData(member *view_model.ProjectGrantMemberView) (err error) { - user, err := p.getUserByID(member.UserID) - if err != nil { - return err - } - p.fillUserData(member, user) - return nil -} - -func (p *ProjectGrantMember) fillUserData(member *view_model.ProjectGrantMemberView, user *usr_view_model.UserView) error { - org, err := p.getOrgByID(context.Background(), user.ResourceOwner) - policy := org.OrgIamPolicy - if policy == nil { - policy, err = p.getDefaultOrgIAMPolicy(context.TODO()) - if err != nil { - return err - } - } - member.UserName = user.UserName - member.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain) - member.UserResourceOwner = user.ResourceOwner - if user.HumanView != nil { - member.FirstName = user.FirstName - member.LastName = user.LastName - member.DisplayName = user.DisplayName - member.Email = user.Email - member.AvatarKey = user.AvatarKey - } - if user.MachineView != nil { - member.DisplayName = user.MachineView.Name - } - return nil -} - -func (p *ProjectGrantMember) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-kls93", "id", event.AggregateID).WithError(err).Warn("something went wrong in projectmember handler") - return spooler.HandleError(event, err, p.view.GetLatestProjectGrantMemberFailedEvent, p.view.ProcessedProjectGrantMemberFailedEvent, p.view.ProcessedProjectGrantMemberSequence, p.errorCountUntilSkip) -} - -func (p *ProjectGrantMember) OnSuccess() error { - return spooler.HandleSuccess(p.view.UpdateProjectGrantMemberSpoolerRunTimestamp) -} - -func (u *ProjectGrantMember) getUserByID(userID string) (*usr_view_model.UserView, error) { - user, usrErr := u.view.UserByID(userID) - if usrErr != nil && !caos_errs.IsNotFound(usrErr) { - return nil, usrErr - } - if user == nil { - user = &usr_view_model.UserView{} - } - events, err := u.getUserEvents(userID, user.Sequence) - if err != nil { - return user, usrErr - } - userCopy := *user - for _, event := range events { - if err := userCopy.AppendEvent(event); err != nil { - return user, nil - } - } - if userCopy.State == int32(usr_model.UserStateDeleted) { - return nil, caos_errs.ThrowNotFound(nil, "HANDLER-m9dos", "Errors.User.NotFound") - } - return &userCopy, nil -} - -func (u *ProjectGrantMember) getUserEvents(userID string, sequence uint64) ([]*es_models.Event, error) { - query, err := view.UserByIDQuery(userID, sequence) - if err != nil { - return nil, err - } - - return u.es.FilterEvents(context.Background(), query) -} - -func (u *ProjectGrantMember) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := org_view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-3nd7s", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *ProjectGrantMember) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) { - existingIAM, err := u.getIAMByID(ctx) - if err != nil { - return nil, err - } - if existingIAM.DefaultOrgIAMPolicy == nil { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-3Bf7s", "Errors.IAM.OrgIAMPolicy.NotExisting") - } - return existingIAM.DefaultOrgIAMPolicy, nil -} - -func (u *ProjectGrantMember) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &iam_es_model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} diff --git a/internal/management/repository/eventsourcing/handler/project_member.go b/internal/management/repository/eventsourcing/handler/project_member.go deleted file mode 100644 index c4ee0409bc..0000000000 --- a/internal/management/repository/eventsourcing/handler/project_member.go +++ /dev/null @@ -1,294 +0,0 @@ -package handler - -import ( - "context" - - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - org_model "github.com/caos/zitadel/internal/org/model" - org_view "github.com/caos/zitadel/internal/org/repository/view" - "github.com/caos/zitadel/internal/user/repository/view" - - "github.com/caos/logging" - - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - view_model "github.com/caos/zitadel/internal/project/repository/view/model" - usr_model "github.com/caos/zitadel/internal/user/model" - usr_es_model "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model" -) - -const ( - projectMemberTable = "management.project_members" -) - -type ProjectMember struct { - handler - subscription *v1.Subscription -} - -func newProjectMember( - handler handler, -) *ProjectMember { - h := &ProjectMember{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (m *ProjectMember) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (p *ProjectMember) ViewModel() string { - return projectMemberTable -} - -func (p *ProjectMember) Subscription() *v1.Subscription { - return p.subscription -} - -func (_ *ProjectMember) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{proj_es_model.ProjectAggregate, usr_es_model.UserAggregate} -} - -func (p *ProjectMember) CurrentSequence() (uint64, error) { - sequence, err := p.view.GetLatestProjectMemberSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (p *ProjectMember) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := p.view.GetLatestProjectMemberSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(p.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (p *ProjectMember) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case proj_es_model.ProjectAggregate: - err = p.processProjectMember(event) - case usr_es_model.UserAggregate: - err = p.processUser(event) - } - return err -} - -func (p *ProjectMember) processProjectMember(event *es_models.Event) (err error) { - member := new(view_model.ProjectMemberView) - switch event.Type { - case proj_es_model.ProjectMemberAdded: - err = member.AppendEvent(event) - if err != nil { - return err - } - p.fillData(member) - case proj_es_model.ProjectMemberChanged: - err = member.SetData(event) - if err != nil { - return err - } - member, err = p.view.ProjectMemberByIDs(event.AggregateID, member.UserID) - if err != nil { - return err - } - err = member.AppendEvent(event) - case proj_es_model.ProjectMemberRemoved, proj_es_model.ProjectMemberCascadeRemoved: - err = member.SetData(event) - if err != nil { - return err - } - return p.view.DeleteProjectMember(event.AggregateID, member.UserID, event) - case proj_es_model.ProjectRemoved: - return p.view.DeleteProjectMembersByProjectID(event.AggregateID) - default: - return p.view.ProcessedProjectMemberSequence(event) - } - if err != nil { - return err - } - return p.view.PutProjectMember(member, event) -} - -func (p *ProjectMember) processUser(event *es_models.Event) (err error) { - switch event.Type { - case usr_es_model.UserProfileChanged, - usr_es_model.UserEmailChanged, - usr_es_model.HumanProfileChanged, - usr_es_model.HumanEmailChanged, - usr_es_model.MachineChanged, - usr_es_model.HumanAvatarAdded, - usr_es_model.HumanAvatarRemoved: - members, err := p.view.ProjectMembersByUserID(event.AggregateID) - if err != nil { - return err - } - if len(members) == 0 { - return p.view.ProcessedProjectMemberSequence(event) - } - user, err := p.getUserByID(event.AggregateID) - if err != nil { - return err - } - for _, member := range members { - p.fillUserData(member, user) - } - return p.view.PutProjectMembers(members, event) - case usr_es_model.UserRemoved: - p.view.DeleteProjectMembersByUserID(event.AggregateID) - default: - return p.view.ProcessedProjectMemberSequence(event) - } - return nil -} - -func (p *ProjectMember) fillData(member *view_model.ProjectMemberView) (err error) { - user, err := p.getUserByID(member.UserID) - if err != nil { - return err - } - return p.fillUserData(member, user) -} - -func (p *ProjectMember) fillUserData(member *view_model.ProjectMemberView, user *usr_view_model.UserView) error { - org, err := p.getOrgByID(context.Background(), user.ResourceOwner) - if err != nil { - return err - } - policy := org.OrgIamPolicy - if policy == nil { - policy, err = p.getDefaultOrgIAMPolicy(context.TODO()) - if err != nil { - return err - } - } - member.UserName = user.UserName - member.PreferredLoginName = user.GenerateLoginName(org.GetPrimaryDomain().Domain, policy.UserLoginMustBeDomain) - member.UserResourceOwner = user.ResourceOwner - if user.HumanView != nil { - member.FirstName = user.FirstName - member.LastName = user.LastName - member.Email = user.Email - member.DisplayName = user.DisplayName - member.AvatarKey = user.AvatarKey - } - if user.MachineView != nil { - member.DisplayName = user.MachineView.Name - } - return nil -} - -func (p *ProjectMember) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-u73es", "id", event.AggregateID).WithError(err).Warn("something went wrong in projectmember handler") - return spooler.HandleError(event, err, p.view.GetLatestProjectMemberFailedEvent, p.view.ProcessedProjectMemberFailedEvent, p.view.ProcessedProjectMemberSequence, p.errorCountUntilSkip) -} - -func (p *ProjectMember) OnSuccess() error { - return spooler.HandleSuccess(p.view.UpdateProjectMemberSpoolerRunTimestamp) -} - -func (u *ProjectMember) getUserByID(userID string) (*usr_view_model.UserView, error) { - user, usrErr := u.view.UserByID(userID) - if usrErr != nil && !caos_errs.IsNotFound(usrErr) { - return nil, usrErr - } - if user == nil { - user = &usr_view_model.UserView{} - } - events, err := u.getUserEvents(userID, user.Sequence) - if err != nil { - return user, usrErr - } - userCopy := *user - for _, event := range events { - if err := userCopy.AppendEvent(event); err != nil { - return user, nil - } - } - if userCopy.State == int32(usr_model.UserStateUnspecified) || userCopy.State == int32(usr_model.UserStateDeleted) { - return nil, caos_errs.ThrowNotFound(nil, "HANDLER-m9dos", "Errors.User.NotFound") - } - return &userCopy, nil -} - -func (u *ProjectMember) getUserEvents(userID string, sequence uint64) ([]*es_models.Event, error) { - query, err := view.UserByIDQuery(userID, sequence) - if err != nil { - return nil, err - } - - return u.es.FilterEvents(context.Background(), query) -} - -func (u *ProjectMember) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := org_view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-3N8fs", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *ProjectMember) getDefaultOrgIAMPolicy(ctx context.Context) (*iam_model.OrgIAMPolicy, error) { - existingIAM, err := u.getIAMByID(ctx) - if err != nil { - return nil, err - } - if existingIAM.DefaultOrgIAMPolicy == nil { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-5M9sd", "Errors.IAM.OrgIAMPolicy.NotExisting") - } - return existingIAM.DefaultOrgIAMPolicy, nil -} - -func (u *ProjectMember) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &iam_es_model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} diff --git a/internal/management/repository/eventsourcing/handler/user_external_idps.go b/internal/management/repository/eventsourcing/handler/user_external_idps.go deleted file mode 100644 index 0c16cffe3b..0000000000 --- a/internal/management/repository/eventsourcing/handler/user_external_idps.go +++ /dev/null @@ -1,242 +0,0 @@ -package handler - -import ( - "context" - "github.com/caos/zitadel/internal/domain" - "github.com/caos/zitadel/internal/eventstore/v1" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - iam_view "github.com/caos/zitadel/internal/iam/repository/view" - org_model "github.com/caos/zitadel/internal/org/model" - "github.com/caos/zitadel/internal/org/repository/view" - - "github.com/caos/logging" - - "github.com/caos/zitadel/internal/config/systemdefaults" - caos_errs "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_model "github.com/caos/zitadel/internal/iam/model" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - iam_view_model "github.com/caos/zitadel/internal/iam/repository/view/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - usr_view_model "github.com/caos/zitadel/internal/user/repository/view/model" -) - -const ( - externalIDPTable = "management.user_external_idps" -) - -type ExternalIDP struct { - handler - systemDefaults systemdefaults.SystemDefaults - subscription *v1.Subscription -} - -func newExternalIDP( - handler handler, - systemDefaults systemdefaults.SystemDefaults, -) *ExternalIDP { - h := &ExternalIDP{ - handler: handler, - systemDefaults: systemDefaults, - } - - h.subscribe() - - return h -} - -func (m *ExternalIDP) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (i *ExternalIDP) ViewModel() string { - return externalIDPTable -} - -func (i *ExternalIDP) Subscription() *v1.Subscription { - return i.subscription -} - -func (_ *ExternalIDP) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{model.UserAggregate, iam_es_model.IAMAggregate, org_es_model.OrgAggregate} -} - -func (i *ExternalIDP) CurrentSequence() (uint64, error) { - sequence, err := i.view.GetLatestExternalIDPSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (i *ExternalIDP) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := i.view.GetLatestExternalIDPSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(i.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (i *ExternalIDP) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case model.UserAggregate: - err = i.processUser(event) - case iam_es_model.IAMAggregate, org_es_model.OrgAggregate: - err = i.processIdpConfig(event) - } - return err -} - -func (i *ExternalIDP) processUser(event *es_models.Event) (err error) { - externalIDP := new(usr_view_model.ExternalIDPView) - switch event.Type { - case model.HumanExternalIDPAdded: - err = externalIDP.AppendEvent(event) - if err != nil { - return err - } - err = i.fillData(externalIDP) - case model.HumanExternalIDPRemoved, model.HumanExternalIDPCascadeRemoved: - err = externalIDP.SetData(event) - if err != nil { - return err - } - return i.view.DeleteExternalIDP(externalIDP.ExternalUserID, externalIDP.IDPConfigID, event) - case model.UserRemoved: - return i.view.DeleteExternalIDPsByUserID(event.AggregateID, event) - default: - return i.view.ProcessedExternalIDPSequence(event) - } - if err != nil { - return err - } - return i.view.PutExternalIDP(externalIDP, event) -} - -func (i *ExternalIDP) processIdpConfig(event *es_models.Event) (err error) { - switch event.Type { - case iam_es_model.IDPConfigChanged, org_es_model.IDPConfigChanged: - configView := new(iam_view_model.IDPConfigView) - config := new(iam_model.IDPConfig) - if event.Type == iam_es_model.IDPConfigChanged { - configView.AppendEvent(iam_model.IDPProviderTypeSystem, event) - } else { - configView.AppendEvent(iam_model.IDPProviderTypeOrg, event) - } - exterinalIDPs, err := i.view.ExternalIDPsByIDPConfigID(configView.IDPConfigID) - if err != nil { - return err - } - if event.AggregateType == iam_es_model.IAMAggregate { - config, err = i.getDefaultIDPConfig(context.Background(), configView.IDPConfigID) - } else { - config, err = i.getOrgIDPConfig(context.Background(), event.AggregateID, configView.IDPConfigID) - } - if err != nil { - return err - } - for _, provider := range exterinalIDPs { - i.fillConfigData(provider, config) - } - return i.view.PutExternalIDPs(event, exterinalIDPs...) - default: - return i.view.ProcessedExternalIDPSequence(event) - } - return nil -} - -func (i *ExternalIDP) fillData(externalIDP *usr_view_model.ExternalIDPView) error { - config, err := i.getOrgIDPConfig(context.Background(), externalIDP.ResourceOwner, externalIDP.IDPConfigID) - if caos_errs.IsNotFound(err) { - config, err = i.getDefaultIDPConfig(context.Background(), externalIDP.IDPConfigID) - } - if err != nil { - return err - } - i.fillConfigData(externalIDP, config) - return nil -} - -func (i *ExternalIDP) fillConfigData(externalIDP *usr_view_model.ExternalIDPView, config *iam_model.IDPConfig) { - externalIDP.IDPName = config.Name -} - -func (i *ExternalIDP) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-4Rsu8", "id", event.AggregateID).WithError(err).Warn("something went wrong in idp provider handler") - return spooler.HandleError(event, err, i.view.GetLatestExternalIDPFailedEvent, i.view.ProcessedExternalIDPFailedEvent, i.view.ProcessedExternalIDPSequence, i.errorCountUntilSkip) -} - -func (i *ExternalIDP) OnSuccess() error { - return spooler.HandleSuccess(i.view.UpdateExternalIDPSpoolerRunTimestamp) -} - -func (i *ExternalIDP) getOrgIDPConfig(ctx context.Context, aggregateID, idpConfigID string) (*iam_model.IDPConfig, error) { - existing, err := i.getOrgByID(ctx, aggregateID) - if err != nil { - return nil, err - } - if _, i := existing.GetIDP(idpConfigID); i != nil { - return i, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-22n7G", "Errors.IDP.NotExisting") -} - -func (i *ExternalIDP) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, i.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-4m0fs", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *ExternalIDP) getIAMByID(ctx context.Context) (*iam_model.IAM, error) { - query, err := iam_view.IAMByIDQuery(domain.IAMID, 0) - if err != nil { - return nil, err - } - iam := &iam_es_model.IAM{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: domain.IAMID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, iam.AppendEvents, query) - if err != nil && caos_errs.IsNotFound(err) && iam.Sequence == 0 { - return nil, err - } - return iam_es_model.IAMToModel(iam), nil -} - -func (u *ExternalIDP) getDefaultIDPConfig(ctx context.Context, idpConfigID string) (*iam_model.IDPConfig, error) { - existing, err := u.getIAMByID(ctx) - if err != nil { - return nil, err - } - if _, existingIDP := existing.GetIDP(idpConfigID); existingIDP != nil { - return existingIDP, nil - } - return nil, caos_errs.ThrowNotFound(nil, "EVENT-22Nv8", "Errors.IAM.IdpNotExisting") -} diff --git a/internal/management/repository/eventsourcing/handler/user_membership.go b/internal/management/repository/eventsourcing/handler/user_membership.go deleted file mode 100644 index c55ca442fb..0000000000 --- a/internal/management/repository/eventsourcing/handler/user_membership.go +++ /dev/null @@ -1,317 +0,0 @@ -package handler - -import ( - "context" - - "github.com/caos/logging" - - caos_errs "github.com/caos/zitadel/internal/errors" - v1 "github.com/caos/zitadel/internal/eventstore/v1" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/eventstore/v1/query" - es_sdk "github.com/caos/zitadel/internal/eventstore/v1/sdk" - "github.com/caos/zitadel/internal/eventstore/v1/spooler" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" - org_model "github.com/caos/zitadel/internal/org/model" - org_es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model" - org_view "github.com/caos/zitadel/internal/org/repository/view" - proj_model "github.com/caos/zitadel/internal/project/model" - proj_es_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model" - proj_view "github.com/caos/zitadel/internal/project/repository/view" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/eventsourcing/model" - usr_es_model "github.com/caos/zitadel/internal/user/repository/view/model" -) - -const ( - userMembershipTable = "management.user_memberships" -) - -type UserMembership struct { - handler - subscription *v1.Subscription -} - -func newUserMembership( - handler handler, -) *UserMembership { - h := &UserMembership{ - handler: handler, - } - - h.subscribe() - - return h -} - -func (m *UserMembership) subscribe() { - m.subscription = m.es.Subscribe(m.AggregateTypes()...) - go func() { - for event := range m.subscription.Events { - query.ReduceEvent(m, event) - } - }() -} - -func (m *UserMembership) ViewModel() string { - return userMembershipTable -} - -func (m *UserMembership) Subscription() *v1.Subscription { - return m.subscription -} - -func (_ *UserMembership) AggregateTypes() []es_models.AggregateType { - return []es_models.AggregateType{iam_es_model.IAMAggregate, org_es_model.OrgAggregate, proj_es_model.ProjectAggregate, model.UserAggregate} -} - -func (u *UserMembership) CurrentSequence() (uint64, error) { - sequence, err := u.view.GetLatestUserMembershipSequence() - if err != nil { - return 0, err - } - return sequence.CurrentSequence, nil -} - -func (m *UserMembership) EventQuery() (*es_models.SearchQuery, error) { - sequence, err := m.view.GetLatestUserMembershipSequence() - if err != nil { - return nil, err - } - return es_models.NewSearchQuery(). - AggregateTypeFilter(m.AggregateTypes()...). - LatestSequenceFilter(sequence.CurrentSequence), nil -} - -func (m *UserMembership) Reduce(event *es_models.Event) (err error) { - switch event.AggregateType { - case iam_es_model.IAMAggregate: - err = m.processIAM(event) - case org_es_model.OrgAggregate: - err = m.processOrg(event) - case proj_es_model.ProjectAggregate: - err = m.processProject(event) - case model.UserAggregate: - err = m.processUser(event) - } - return err -} - -func (m *UserMembership) processIAM(event *es_models.Event) (err error) { - member := new(usr_es_model.UserMembershipView) - err = member.AppendEvent(event) - if err != nil { - return err - } - switch event.Type { - case iam_es_model.IAMMemberAdded: - m.fillIamDisplayName(member) - case iam_es_model.IAMMemberChanged: - member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeIam) - if err != nil { - return err - } - err = member.AppendEvent(event) - case iam_es_model.IAMMemberRemoved, - iam_es_model.IAMMemberCascadeRemoved: - return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeIam, event) - default: - return m.view.ProcessedUserMembershipSequence(event) - } - if err != nil { - return err - } - return m.view.PutUserMembership(member, event) -} - -func (m *UserMembership) fillIamDisplayName(member *usr_es_model.UserMembershipView) { - member.DisplayName = member.AggregateID -} - -func (m *UserMembership) processOrg(event *es_models.Event) (err error) { - member := new(usr_es_model.UserMembershipView) - err = member.AppendEvent(event) - if err != nil { - return err - } - switch event.Type { - case org_es_model.OrgMemberAdded: - err = m.fillOrgDisplayName(member) - case org_es_model.OrgMemberChanged: - member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeOrganisation) - if err != nil { - return err - } - err = member.AppendEvent(event) - case org_es_model.OrgMemberRemoved, org_es_model.OrgMemberCascadeRemoved: - return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeOrganisation, event) - case org_es_model.OrgChanged: - return m.updateOrgDisplayName(event) - default: - return m.view.ProcessedUserMembershipSequence(event) - } - if err != nil { - return err - } - return m.view.PutUserMembership(member, event) -} - -func (m *UserMembership) fillOrgDisplayName(member *usr_es_model.UserMembershipView) (err error) { - org, err := m.getOrgByID(context.Background(), member.AggregateID) - if err != nil { - return err - } - member.DisplayName = org.Name - return nil -} - -func (m *UserMembership) updateOrgDisplayName(event *es_models.Event) error { - org := new(org_es_model.Org) - err := org.SetData(event) - if err != nil { - return err - } - if org.Name == "" { - return m.view.ProcessedUserMembershipSequence(event) - } - - memberships, err := m.view.UserMembershipsByAggregateID(event.AggregateID) - if err != nil { - return err - } - for _, membership := range memberships { - membership.DisplayName = org.Name - } - return m.view.BulkPutUserMemberships(memberships, event) -} - -func (m *UserMembership) processProject(event *es_models.Event) (err error) { - member := new(usr_es_model.UserMembershipView) - err = member.AppendEvent(event) - if err != nil { - return err - } - switch event.Type { - case proj_es_model.ProjectMemberAdded, proj_es_model.ProjectGrantMemberAdded: - err = m.fillProjectDisplayName(member) - case proj_es_model.ProjectMemberChanged: - member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeProject) - if err != nil { - return err - } - err = member.AppendEvent(event) - case proj_es_model.ProjectMemberRemoved, proj_es_model.ProjectMemberCascadeRemoved: - return m.view.DeleteUserMembership(member.UserID, event.AggregateID, event.AggregateID, usr_model.MemberTypeProject, event) - case proj_es_model.ProjectGrantMemberChanged: - member, err = m.view.UserMembershipByIDs(member.UserID, event.AggregateID, member.ObjectID, usr_model.MemberTypeProjectGrant) - if err != nil { - return err - } - err = member.AppendEvent(event) - case proj_es_model.ProjectGrantMemberRemoved, - proj_es_model.ProjectGrantMemberCascadeRemoved: - return m.view.DeleteUserMembership(member.UserID, event.AggregateID, member.ObjectID, usr_model.MemberTypeProjectGrant, event) - case proj_es_model.ProjectChanged: - return m.updateProjectDisplayName(event) - case proj_es_model.ProjectRemoved: - return m.view.DeleteUserMembershipsByAggregateID(event.AggregateID, event) - case proj_es_model.ProjectGrantRemoved: - return m.view.DeleteUserMembershipsByAggregateIDAndObjectID(event.AggregateID, member.ObjectID, event) - default: - return m.view.ProcessedUserMembershipSequence(event) - } - if err != nil { - return err - } - return m.view.PutUserMembership(member, event) -} - -func (m *UserMembership) fillProjectDisplayName(member *usr_es_model.UserMembershipView) (err error) { - project, err := m.getProjectByID(context.Background(), member.AggregateID) - if err != nil { - return err - } - member.DisplayName = project.Name - return nil -} - -func (m *UserMembership) updateProjectDisplayName(event *es_models.Event) error { - proj := new(proj_es_model.Project) - err := proj.SetData(event) - if err != nil { - return err - } - if proj.Name == "" { - return m.view.ProcessedUserMembershipSequence(event) - } - - memberships, err := m.view.UserMembershipsByAggregateID(event.AggregateID) - if err != nil { - return err - } - for _, membership := range memberships { - membership.DisplayName = proj.Name - } - return m.view.BulkPutUserMemberships(memberships, event) -} - -func (m *UserMembership) processUser(event *es_models.Event) (err error) { - switch event.Type { - case model.UserRemoved: - return m.view.DeleteUserMembershipsByUserID(event.AggregateID, event) - default: - return m.view.ProcessedUserMembershipSequence(event) - } -} - -func (m *UserMembership) OnError(event *es_models.Event, err error) error { - logging.LogWithFields("SPOOL-Fwer2", "id", event.AggregateID).WithError(err).Warn("something went wrong in user membership handler") - return spooler.HandleError(event, err, m.view.GetLatestUserMembershipFailedEvent, m.view.ProcessedUserMembershipFailedEvent, m.view.ProcessedUserMembershipSequence, m.errorCountUntilSkip) -} - -func (m *UserMembership) OnSuccess() error { - return spooler.HandleSuccess(m.view.UpdateUserMembershipSpoolerRunTimestamp) -} - -func (u *UserMembership) getOrgByID(ctx context.Context, orgID string) (*org_model.Org, error) { - query, err := org_view.OrgByIDQuery(orgID, 0) - if err != nil { - return nil, err - } - - esOrg := &org_es_model.Org{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: orgID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esOrg.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esOrg.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-kVLb2", "Errors.Org.NotFound") - } - - return org_es_model.OrgToModel(esOrg), nil -} - -func (u *UserMembership) getProjectByID(ctx context.Context, projID string) (*proj_model.Project, error) { - query, err := proj_view.ProjectByIDQuery(projID, 0) - if err != nil { - return nil, err - } - esProject := &proj_es_model.Project{ - ObjectRoot: es_models.ObjectRoot{ - AggregateID: projID, - }, - } - err = es_sdk.Filter(ctx, u.Eventstore().FilterEvents, esProject.AppendEvents, query) - if err != nil && !caos_errs.IsNotFound(err) { - return nil, err - } - if esProject.Sequence == 0 { - return nil, caos_errs.ThrowNotFound(nil, "EVENT-Bg32b", "Errors.Project.NotFound") - } - - return proj_es_model.ProjectToModel(esProject), nil -} diff --git a/internal/management/repository/eventsourcing/repository.go b/internal/management/repository/eventsourcing/repository.go index 04f2c210f3..a8d0f7242e 100644 --- a/internal/management/repository/eventsourcing/repository.go +++ b/internal/management/repository/eventsourcing/repository.go @@ -74,7 +74,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string, querie NotificationTranslationFileContents: make(map[string][]byte), Query: queries, }, - ProjectRepo: eventstore.ProjectRepo{es, conf.SearchLimit, view, roles, systemDefaults.IamID, assetsAPI}, + ProjectRepo: eventstore.ProjectRepo{es, conf.SearchLimit, view, roles, systemDefaults.IamID, assetsAPI, queries}, UserRepo: eventstore.UserRepo{es, conf.SearchLimit, view, systemDefaults, assetsAPI}, UserGrantRepo: eventstore.UserGrantRepo{conf.SearchLimit, view, assetsAPI}, IAMRepository: eventstore.IAMRepository{IAMV2Query: queries}, diff --git a/internal/management/repository/eventsourcing/view/external_idps.go b/internal/management/repository/eventsourcing/view/external_idps.go deleted file mode 100644 index 96c05c44c0..0000000000 --- a/internal/management/repository/eventsourcing/view/external_idps.go +++ /dev/null @@ -1,87 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/view" - "github.com/caos/zitadel/internal/user/repository/view/model" - global_view "github.com/caos/zitadel/internal/view/repository" -) - -const ( - externalIDPTable = "management.user_external_idps" -) - -func (v *View) ExternalIDPByExternalUserIDAndIDPConfigID(externalUserID, idpConfigID string) (*model.ExternalIDPView, error) { - return view.ExternalIDPByExternalUserIDAndIDPConfigID(v.Db, externalIDPTable, externalUserID, idpConfigID) -} - -func (v *View) ExternalIDPByExternalUserIDAndIDPConfigIDAndResourceOwner(externalUserID, idpConfigID, resourceOwner string) (*model.ExternalIDPView, error) { - return view.ExternalIDPByExternalUserIDAndIDPConfigIDAndResourceOwner(v.Db, externalIDPTable, externalUserID, idpConfigID, resourceOwner) -} - -func (v *View) ExternalIDPsByIDPConfigID(idpConfigID string) ([]*model.ExternalIDPView, error) { - return view.ExternalIDPsByIDPConfigID(v.Db, externalIDPTable, idpConfigID) -} - -func (v *View) ExternalIDPsByIDPConfigIDAndResourceOwner(idpConfigID, resourceOwner string) ([]*model.ExternalIDPView, error) { - return view.ExternalIDPsByIDPConfigIDAndResourceOwner(v.Db, externalIDPTable, idpConfigID, resourceOwner) -} -func (v *View) ExternalIDPsByUserID(userID string) ([]*model.ExternalIDPView, error) { - return view.ExternalIDPsByUserID(v.Db, externalIDPTable, userID) -} - -func (v *View) SearchExternalIDPs(request *usr_model.ExternalIDPSearchRequest) ([]*model.ExternalIDPView, uint64, error) { - return view.SearchExternalIDPs(v.Db, externalIDPTable, request) -} - -func (v *View) PutExternalIDP(externalIDP *model.ExternalIDPView, event *models.Event) error { - err := view.PutExternalIDP(v.Db, externalIDPTable, externalIDP) - if err != nil { - return err - } - return v.ProcessedExternalIDPSequence(event) -} - -func (v *View) PutExternalIDPs(event *models.Event, externalIDPs ...*model.ExternalIDPView) error { - err := view.PutExternalIDPs(v.Db, externalIDPTable, externalIDPs...) - if err != nil { - return err - } - return v.ProcessedExternalIDPSequence(event) -} - -func (v *View) DeleteExternalIDP(externalUserID, idpConfigID string, event *models.Event) error { - err := view.DeleteExternalIDP(v.Db, externalIDPTable, externalUserID, idpConfigID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedExternalIDPSequence(event) -} - -func (v *View) DeleteExternalIDPsByUserID(userID string, event *models.Event) error { - err := view.DeleteExternalIDPsByUserID(v.Db, externalIDPTable, userID) - if err != nil { - return err - } - return v.ProcessedExternalIDPSequence(event) -} -func (v *View) GetLatestExternalIDPSequence() (*global_view.CurrentSequence, error) { - return v.latestSequence(externalIDPTable) -} - -func (v *View) ProcessedExternalIDPSequence(event *models.Event) error { - return v.saveCurrentSequence(externalIDPTable, event) -} - -func (v *View) UpdateExternalIDPSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(externalIDPTable) -} -func (v *View) GetLatestExternalIDPFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { - return v.latestFailedEvent(externalIDPTable, sequence) -} - -func (v *View) ProcessedExternalIDPFailedEvent(failedEvent *global_view.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/management/repository/eventsourcing/view/idp_configs.go b/internal/management/repository/eventsourcing/view/idp_configs.go deleted file mode 100644 index f857124a8a..0000000000 --- a/internal/management/repository/eventsourcing/view/idp_configs.go +++ /dev/null @@ -1,58 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/view" - iam_es_model "github.com/caos/zitadel/internal/iam/repository/view/model" - global_view "github.com/caos/zitadel/internal/view/repository" -) - -const ( - idpConfigTable = "management.idp_configs" -) - -func (v *View) IDPConfigByID(idpID string) (*iam_es_model.IDPConfigView, error) { - return view.IDPByID(v.Db, idpConfigTable, idpID) -} - -func (v *View) SearchIDPConfigs(request *iam_model.IDPConfigSearchRequest) ([]*iam_es_model.IDPConfigView, uint64, error) { - return view.SearchIDPs(v.Db, idpConfigTable, request) -} - -func (v *View) PutIDPConfig(idp *iam_es_model.IDPConfigView, event *models.Event) error { - err := view.PutIDP(v.Db, idpConfigTable, idp) - if err != nil { - return err - } - return v.ProcessedIDPConfigSequence(event) -} - -func (v *View) DeleteIDPConfig(idpID string, event *models.Event) error { - err := view.DeleteIDP(v.Db, idpConfigTable, idpID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedIDPConfigSequence(event) -} - -func (v *View) GetLatestIDPConfigSequence() (*global_view.CurrentSequence, error) { - return v.latestSequence(idpConfigTable) -} - -func (v *View) ProcessedIDPConfigSequence(event *models.Event) error { - return v.saveCurrentSequence(idpConfigTable, event) -} - -func (v *View) UpdateIDPConfigSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(idpConfigTable) -} - -func (v *View) GetLatestIDPConfigFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { - return v.latestFailedEvent(idpConfigTable, sequence) -} - -func (v *View) ProcessedIDPConfigFailedEvent(failedEvent *global_view.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/management/repository/eventsourcing/view/idp_providers.go b/internal/management/repository/eventsourcing/view/idp_providers.go deleted file mode 100644 index 1a9ba11889..0000000000 --- a/internal/management/repository/eventsourcing/view/idp_providers.go +++ /dev/null @@ -1,78 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/view" - "github.com/caos/zitadel/internal/iam/repository/view/model" - global_view "github.com/caos/zitadel/internal/view/repository" -) - -const ( - idpProviderTable = "management.idp_providers" -) - -func (v *View) IDPProviderByAggregateAndIdpConfigID(aggregateID, idpConfigID string) (*model.IDPProviderView, error) { - return view.GetIDPProviderByAggregateIDAndConfigID(v.Db, idpProviderTable, aggregateID, idpConfigID) -} - -func (v *View) IDPProvidersByIdpConfigID(aggregateID, idpConfigID string) ([]*model.IDPProviderView, error) { - return view.IDPProvidersByIdpConfigID(v.Db, idpProviderTable, idpConfigID) -} - -func (v *View) SearchIDPProviders(request *iam_model.IDPProviderSearchRequest) ([]*model.IDPProviderView, uint64, error) { - return view.SearchIDPProviders(v.Db, idpProviderTable, request) -} - -func (v *View) PutIDPProvider(provider *model.IDPProviderView, event *models.Event) error { - err := view.PutIDPProvider(v.Db, idpProviderTable, provider) - if err != nil { - return err - } - return v.ProcessedIDPProviderSequence(event) -} - -func (v *View) PutIDPProviders(event *models.Event, providers ...*model.IDPProviderView) error { - err := view.PutIDPProviders(v.Db, idpProviderTable, providers...) - if err != nil { - return err - } - return v.ProcessedIDPProviderSequence(event) -} - -func (v *View) DeleteIDPProvider(aggregateID, idpConfigID string, event *models.Event) error { - err := view.DeleteIDPProvider(v.Db, idpProviderTable, aggregateID, idpConfigID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedIDPProviderSequence(event) -} - -func (v *View) DeleteIDPProvidersByAggregateID(aggregateID string, event *models.Event) error { - err := view.DeleteIDPProvidersByAggregateID(v.Db, idpProviderTable, aggregateID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedIDPProviderSequence(event) -} - -func (v *View) GetLatestIDPProviderSequence() (*global_view.CurrentSequence, error) { - return v.latestSequence(idpProviderTable) -} - -func (v *View) ProcessedIDPProviderSequence(event *models.Event) error { - return v.saveCurrentSequence(idpProviderTable, event) -} - -func (v *View) UpdateIDPProviderSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(idpProviderTable) -} - -func (v *View) GetLatestIDPProviderFailedEvent(sequence uint64) (*global_view.FailedEvent, error) { - return v.latestFailedEvent(idpProviderTable, sequence) -} - -func (v *View) ProcessedIDPProviderFailedEvent(failedEvent *global_view.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/management/repository/eventsourcing/view/org_member.go b/internal/management/repository/eventsourcing/view/org_member.go deleted file mode 100644 index 3a9f522a66..0000000000 --- a/internal/management/repository/eventsourcing/view/org_member.go +++ /dev/null @@ -1,78 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - org_model "github.com/caos/zitadel/internal/org/model" - "github.com/caos/zitadel/internal/org/repository/view" - "github.com/caos/zitadel/internal/org/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -const ( - orgMemberTable = "management.org_members" -) - -func (v *View) OrgMemberByIDs(orgID, userID string) (*model.OrgMemberView, error) { - return view.OrgMemberByIDs(v.Db, orgMemberTable, orgID, userID) -} - -func (v *View) SearchOrgMembers(request *org_model.OrgMemberSearchRequest) ([]*model.OrgMemberView, uint64, error) { - return view.SearchOrgMembers(v.Db, orgMemberTable, request) -} - -func (v *View) OrgMembersByUserID(userID string) ([]*model.OrgMemberView, error) { - return view.OrgMembersByUserID(v.Db, orgMemberTable, userID) -} - -func (v *View) PutOrgMember(member *model.OrgMemberView, event *models.Event) error { - err := view.PutOrgMember(v.Db, orgMemberTable, member) - if err != nil { - return err - } - return v.ProcessedOrgMemberSequence(event) -} - -func (v *View) PutOrgMembers(members []*model.OrgMemberView, event *models.Event) error { - err := view.PutOrgMembers(v.Db, orgMemberTable, members...) - if err != nil { - return err - } - return v.ProcessedOrgMemberSequence(event) -} - -func (v *View) DeleteOrgMember(orgID, userID string, event *models.Event) error { - err := view.DeleteOrgMember(v.Db, orgMemberTable, orgID, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedOrgMemberSequence(event) -} - -func (v *View) DeleteOrgMembersByUserID(userID string, event *models.Event) error { - err := view.DeleteOrgMembersByUserID(v.Db, orgMemberTable, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedOrgMemberSequence(event) -} - -func (v *View) GetLatestOrgMemberSequence() (*repository.CurrentSequence, error) { - return v.latestSequence(orgMemberTable) -} - -func (v *View) ProcessedOrgMemberSequence(event *models.Event) error { - return v.saveCurrentSequence(orgMemberTable, event) -} - -func (v *View) UpdateOrgMemberSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(orgMemberTable) -} - -func (v *View) GetLatestOrgMemberFailedEvent(sequence uint64) (*repository.FailedEvent, error) { - return v.latestFailedEvent(orgMemberTable, sequence) -} - -func (v *View) ProcessedOrgMemberFailedEvent(failedEvent *repository.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/management/repository/eventsourcing/view/project_grant_member.go b/internal/management/repository/eventsourcing/view/project_grant_member.go deleted file mode 100644 index b12da68849..0000000000 --- a/internal/management/repository/eventsourcing/view/project_grant_member.go +++ /dev/null @@ -1,82 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - proj_model "github.com/caos/zitadel/internal/project/model" - "github.com/caos/zitadel/internal/project/repository/view" - "github.com/caos/zitadel/internal/project/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -const ( - projectGrantMemberTable = "management.project_grant_members" -) - -func (v *View) ProjectGrantMemberByIDs(projectID, userID string) (*model.ProjectGrantMemberView, error) { - return view.ProjectGrantMemberByIDs(v.Db, projectGrantMemberTable, projectID, userID) -} - -func (v *View) ProjectGrantMembersByProjectID(projectID string) ([]*model.ProjectGrantMemberView, error) { - return view.ProjectGrantMembersByProjectID(v.Db, projectGrantMemberTable, projectID) -} - -func (v *View) SearchProjectGrantMembers(request *proj_model.ProjectGrantMemberSearchRequest) ([]*model.ProjectGrantMemberView, uint64, error) { - return view.SearchProjectGrantMembers(v.Db, projectGrantMemberTable, request) -} - -func (v *View) ProjectGrantMembersByUserID(userID string) ([]*model.ProjectGrantMemberView, error) { - return view.ProjectGrantMembersByUserID(v.Db, projectGrantMemberTable, userID) -} - -func (v *View) PutProjectGrantMember(member *model.ProjectGrantMemberView, event *models.Event) error { - err := view.PutProjectGrantMember(v.Db, projectGrantMemberTable, member) - if err != nil { - return err - } - return v.ProcessedProjectGrantMemberSequence(event) -} - -func (v *View) PutProjectGrantMembers(members []*model.ProjectGrantMemberView, event *models.Event) error { - err := view.PutProjectGrantMembers(v.Db, projectGrantMemberTable, members...) - if err != nil { - return err - } - return v.ProcessedProjectGrantMemberSequence(event) -} - -func (v *View) DeleteProjectGrantMember(grantID, userID string, event *models.Event) error { - err := view.DeleteProjectGrantMember(v.Db, projectGrantMemberTable, grantID, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedProjectGrantMemberSequence(event) -} - -func (v *View) DeleteProjectGrantMembersByProjectID(projectID string) error { - return view.DeleteProjectGrantMembersByProjectID(v.Db, projectGrantMemberTable, projectID) -} - -func (v *View) DeleteProjectGrantMembersByUserID(userID string) error { - return view.DeleteProjectGrantMembersByUserID(v.Db, projectGrantMemberTable, userID) -} - -func (v *View) GetLatestProjectGrantMemberSequence() (*repository.CurrentSequence, error) { - return v.latestSequence(projectGrantMemberTable) -} - -func (v *View) ProcessedProjectGrantMemberSequence(event *models.Event) error { - return v.saveCurrentSequence(projectGrantMemberTable, event) -} - -func (v *View) UpdateProjectGrantMemberSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(projectGrantMemberTable) -} - -func (v *View) GetLatestProjectGrantMemberFailedEvent(sequence uint64) (*repository.FailedEvent, error) { - return v.latestFailedEvent(projectGrantMemberTable, sequence) -} - -func (v *View) ProcessedProjectGrantMemberFailedEvent(failedEvent *repository.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/management/repository/eventsourcing/view/project_member.go b/internal/management/repository/eventsourcing/view/project_member.go deleted file mode 100644 index 78d4fcb793..0000000000 --- a/internal/management/repository/eventsourcing/view/project_member.go +++ /dev/null @@ -1,82 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - proj_model "github.com/caos/zitadel/internal/project/model" - "github.com/caos/zitadel/internal/project/repository/view" - "github.com/caos/zitadel/internal/project/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -const ( - projectMemberTable = "management.project_members" -) - -func (v *View) ProjectMemberByIDs(projectID, userID string) (*model.ProjectMemberView, error) { - return view.ProjectMemberByIDs(v.Db, projectMemberTable, projectID, userID) -} - -func (v *View) ProjectMembersByProjectID(projectID string) ([]*model.ProjectMemberView, error) { - return view.ProjectMembersByProjectID(v.Db, projectMemberTable, projectID) -} - -func (v *View) SearchProjectMembers(request *proj_model.ProjectMemberSearchRequest) ([]*model.ProjectMemberView, uint64, error) { - return view.SearchProjectMembers(v.Db, projectMemberTable, request) -} - -func (v *View) ProjectMembersByUserID(userID string) ([]*model.ProjectMemberView, error) { - return view.ProjectMembersByUserID(v.Db, projectMemberTable, userID) -} - -func (v *View) PutProjectMember(project *model.ProjectMemberView, event *models.Event) error { - err := view.PutProjectMember(v.Db, projectMemberTable, project) - if err != nil { - return err - } - return v.ProcessedProjectMemberSequence(event) -} - -func (v *View) PutProjectMembers(project []*model.ProjectMemberView, event *models.Event) error { - err := view.PutProjectMembers(v.Db, projectMemberTable, project...) - if err != nil { - return err - } - return v.ProcessedProjectMemberSequence(event) -} - -func (v *View) DeleteProjectMember(projectID, userID string, event *models.Event) error { - err := view.DeleteProjectMember(v.Db, projectMemberTable, projectID, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedProjectMemberSequence(event) -} - -func (v *View) DeleteProjectMembersByProjectID(projectID string) error { - return view.DeleteProjectMembersByProjectID(v.Db, projectMemberTable, projectID) -} - -func (v *View) DeleteProjectMembersByUserID(userID string) error { - return view.DeleteProjectMembersByUserID(v.Db, projectMemberTable, userID) -} - -func (v *View) GetLatestProjectMemberSequence() (*repository.CurrentSequence, error) { - return v.latestSequence(projectMemberTable) -} - -func (v *View) ProcessedProjectMemberSequence(event *models.Event) error { - return v.saveCurrentSequence(projectMemberTable, event) -} - -func (v *View) UpdateProjectMemberSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(projectMemberTable) -} - -func (v *View) GetLatestProjectMemberFailedEvent(sequence uint64) (*repository.FailedEvent, error) { - return v.latestFailedEvent(projectMemberTable, sequence) -} - -func (v *View) ProcessedProjectMemberFailedEvent(failedEvent *repository.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/management/repository/eventsourcing/view/user_membership.go b/internal/management/repository/eventsourcing/view/user_membership.go deleted file mode 100644 index 8d08b2f528..0000000000 --- a/internal/management/repository/eventsourcing/view/user_membership.go +++ /dev/null @@ -1,98 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/eventstore/v1/models" - usr_model "github.com/caos/zitadel/internal/user/model" - "github.com/caos/zitadel/internal/user/repository/view" - "github.com/caos/zitadel/internal/user/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -const ( - userMembershipTable = "management.user_memberships" -) - -func (v *View) UserMembershipByIDs(userID, aggregateID, objectID string, memberType usr_model.MemberType) (*model.UserMembershipView, error) { - return view.UserMembershipByIDs(v.Db, userMembershipTable, userID, aggregateID, objectID, memberType) -} - -func (v *View) UserMembershipsByAggregateID(aggregateID string) ([]*model.UserMembershipView, error) { - return view.UserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID) -} - -func (v *View) UserMembershipsByUserID(userID string) ([]*model.UserMembershipView, error) { - return view.UserMembershipsByUserID(v.Db, userMembershipTable, userID) -} - -func (v *View) SearchUserMemberships(request *usr_model.UserMembershipSearchRequest) ([]*model.UserMembershipView, uint64, error) { - return view.SearchUserMemberships(v.Db, userMembershipTable, request) -} - -func (v *View) PutUserMembership(membership *model.UserMembershipView, event *models.Event) error { - err := view.PutUserMembership(v.Db, userMembershipTable, membership) - if err != nil { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) BulkPutUserMemberships(memberships []*model.UserMembershipView, event *models.Event) error { - err := view.PutUserMemberships(v.Db, userMembershipTable, memberships...) - if err != nil { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) DeleteUserMembership(userID, aggregateID, objectID string, memberType usr_model.MemberType, event *models.Event) error { - err := view.DeleteUserMembership(v.Db, userMembershipTable, userID, aggregateID, objectID, memberType) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) DeleteUserMembershipsByUserID(userID string, event *models.Event) error { - err := view.DeleteUserMembershipsByUserID(v.Db, userMembershipTable, userID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) DeleteUserMembershipsByAggregateID(aggregateID string, event *models.Event) error { - err := view.DeleteUserMembershipsByAggregateID(v.Db, userMembershipTable, aggregateID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) DeleteUserMembershipsByAggregateIDAndObjectID(aggregateID, objectID string, event *models.Event) error { - err := view.DeleteUserMembershipsByAggregateIDAndObjectID(v.Db, userMembershipTable, aggregateID, objectID) - if err != nil && !errors.IsNotFound(err) { - return err - } - return v.ProcessedUserMembershipSequence(event) -} - -func (v *View) GetLatestUserMembershipSequence() (*repository.CurrentSequence, error) { - return v.latestSequence(userMembershipTable) -} - -func (v *View) ProcessedUserMembershipSequence(event *models.Event) error { - return v.saveCurrentSequence(userMembershipTable, event) -} - -func (v *View) UpdateUserMembershipSpoolerRunTimestamp() error { - return v.updateSpoolerRunSequence(userMembershipTable) -} - -func (v *View) GetLatestUserMembershipFailedEvent(sequence uint64) (*repository.FailedEvent, error) { - return v.latestFailedEvent(userMembershipTable, sequence) -} - -func (v *View) ProcessedUserMembershipFailedEvent(failedEvent *repository.FailedEvent) error { - return v.saveFailedEvent(failedEvent) -} diff --git a/internal/management/repository/org.go b/internal/management/repository/org.go index 12e06ff65f..b873390173 100644 --- a/internal/management/repository/org.go +++ b/internal/management/repository/org.go @@ -6,8 +6,6 @@ import ( "golang.org/x/text/language" - iam_model "github.com/caos/zitadel/internal/iam/model" - org_model "github.com/caos/zitadel/internal/org/model" ) @@ -15,8 +13,5 @@ type OrgRepository interface { Languages(ctx context.Context) ([]language.Tag, error) OrgChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (*org_model.OrgChanges, error) - GetOrgMemberRoles() []string - - SearchIDPProviders(ctx context.Context, request *iam_model.IDPProviderSearchRequest) (*iam_model.IDPProviderSearchResponse, error) - GetIDPProvidersByIDPConfigID(ctx context.Context, aggregateID, idpConfigID string) ([]*iam_model.IDPProviderView, error) + GetOrgMemberRoles(isGlobal bool) []string } diff --git a/internal/management/repository/project.go b/internal/management/repository/project.go index bddb282c69..61e41c9b41 100644 --- a/internal/management/repository/project.go +++ b/internal/management/repository/project.go @@ -4,8 +4,6 @@ import ( "context" "time" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/project/model" ) @@ -17,6 +15,4 @@ type ProjectRepository interface { ApplicationChanges(ctx context.Context, projectID string, appID string, lastSequence uint64, limit uint64, sortAscending bool, retention time.Duration) (*model.ApplicationChanges, error) GetProjectGrantMemberRoles() []string - - GetIAMByID(ctx context.Context) (*iam_model.IAM, error) } diff --git a/internal/management/repository/user.go b/internal/management/repository/user.go index b0ec05a48d..046f24c14c 100644 --- a/internal/management/repository/user.go +++ b/internal/management/repository/user.go @@ -28,16 +28,9 @@ type UserRepository interface { GetPasswordless(ctx context.Context, userID string) ([]*model.WebAuthNView, error) - SearchExternalIDPs(ctx context.Context, request *model.ExternalIDPSearchRequest) (*model.ExternalIDPSearchResponse, error) - ExternalIDPsByIDPConfigID(ctx context.Context, idpConfigID string) ([]*model.ExternalIDPView, error) - ExternalIDPsByIDPConfigIDAndResourceOwner(ctx context.Context, idpConfigID, resourceOwner string) ([]*model.ExternalIDPView, error) - EmailByID(ctx context.Context, userID string) (*model.Email, error) PhoneByID(ctx context.Context, userID string) (*model.Phone, error) AddressByID(ctx context.Context, userID string) (*model.Address, error) - - SearchUserMemberships(ctx context.Context, request *model.UserMembershipSearchRequest) (*model.UserMembershipSearchResponse, error) - UserMembershipsByUserID(ctx context.Context, userID string) ([]*model.UserMembershipView, error) } diff --git a/internal/project/repository/view/project_grant_view.go b/internal/project/repository/view/project_grant_view.go deleted file mode 100644 index 48a3e162b2..0000000000 --- a/internal/project/repository/view/project_grant_view.go +++ /dev/null @@ -1,88 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - proj_model "github.com/caos/zitadel/internal/project/model" - "github.com/caos/zitadel/internal/project/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" - "github.com/jinzhu/gorm" -) - -func ProjectGrantByProjectAndOrg(db *gorm.DB, table, projectID, orgID string) (*model.ProjectGrantView, error) { - projectGrant := new(model.ProjectGrantView) - - projectIDQuery := model.ProjectGrantSearchQuery{Key: proj_model.GrantedProjectSearchKeyProjectID, Value: projectID, Method: domain.SearchMethodEquals} - orgIDQuery := model.ProjectGrantSearchQuery{Key: proj_model.GrantedProjectSearchKeyOrgID, Value: orgID, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, projectIDQuery, orgIDQuery) - err := query(db, projectGrant) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-WR3z2", "Errors.Project.Grant.NotExisting") - } - return projectGrant, err -} - -func ProjectGrantByID(db *gorm.DB, table, grantID string) (*model.ProjectGrantView, error) { - projectGrant := new(model.ProjectGrantView) - grantIDQuery := model.ProjectGrantSearchQuery{Key: proj_model.GrantedProjectSearchKeyGrantID, Value: grantID, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, grantIDQuery) - err := query(db, projectGrant) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-EGdh4", "Errors.Project.Grant.NotFound") - } - return projectGrant, err -} - -func ProjectGrantsByProjectID(db *gorm.DB, table, projectID string) ([]*model.ProjectGrantView, error) { - projectGrants := make([]*model.ProjectGrantView, 0) - queries := []*proj_model.ProjectGrantViewSearchQuery{ - {Key: proj_model.GrantedProjectSearchKeyProjectID, Value: projectID, Method: domain.SearchMethodEquals}, - } - query := repository.PrepareSearchQuery(table, model.ProjectGrantSearchRequest{Queries: queries}) - _, err := query(db, &projectGrants) - return projectGrants, err -} - -func ProjectGrantsByProjectIDAndRoleKey(db *gorm.DB, table, projectID, roleKey string) ([]*model.ProjectGrantView, error) { - projectGrants := make([]*model.ProjectGrantView, 0) - queries := []*proj_model.ProjectGrantViewSearchQuery{ - {Key: proj_model.GrantedProjectSearchKeyProjectID, Value: projectID, Method: domain.SearchMethodEquals}, - {Key: proj_model.GrantedProjectSearchKeyRoleKeys, Value: roleKey, Method: domain.SearchMethodListContains}, - } - query := repository.PrepareSearchQuery(table, model.ProjectGrantSearchRequest{Queries: queries}) - _, err := query(db, &projectGrants) - - return projectGrants, err -} - -func SearchProjectGrants(db *gorm.DB, table string, req *proj_model.ProjectGrantViewSearchRequest) ([]*model.ProjectGrantView, uint64, error) { - projectGrants := make([]*model.ProjectGrantView, 0) - query := repository.PrepareSearchQuery(table, model.ProjectGrantSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries}) - count, err := query(db, &projectGrants) - - return projectGrants, count, err -} - -func PutProjectGrant(db *gorm.DB, table string, grant *model.ProjectGrantView) error { - save := repository.PrepareSave(table) - return save(db, grant) -} - -func PutProjectGrants(db *gorm.DB, table string, grants ...*model.ProjectGrantView) error { - save := repository.PrepareBulkSave(table) - g := make([]interface{}, len(grants)) - for i, grant := range grants { - g[i] = grant - } - return save(db, g...) -} - -func DeleteProjectGrant(db *gorm.DB, table, grantID string) error { - delete := repository.PrepareDeleteByKey(table, model.ProjectGrantSearchKey(proj_model.GrantedProjectSearchKeyGrantID), grantID) - return delete(db) -} - -func DeleteProjectGrantsByProjectID(db *gorm.DB, table, projectID string) error { - delete := repository.PrepareDeleteByKey(table, model.ProjectGrantSearchKey(proj_model.GrantedProjectSearchKeyProjectID), projectID) - return delete(db) -} diff --git a/internal/project/repository/view/project_member_view.go b/internal/project/repository/view/project_member_view.go deleted file mode 100644 index cc1dec40f6..0000000000 --- a/internal/project/repository/view/project_member_view.go +++ /dev/null @@ -1,91 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - proj_model "github.com/caos/zitadel/internal/project/model" - "github.com/caos/zitadel/internal/project/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" - "github.com/jinzhu/gorm" -) - -func ProjectMemberByIDs(db *gorm.DB, table, projectID, userID string) (*model.ProjectMemberView, error) { - role := new(model.ProjectMemberView) - - projectIDQuery := model.ProjectMemberSearchQuery{Key: proj_model.ProjectMemberSearchKeyProjectID, Value: projectID, Method: domain.SearchMethodEquals} - userIDQuery := model.ProjectMemberSearchQuery{Key: proj_model.ProjectMemberSearchKeyUserID, Value: userID, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, projectIDQuery, userIDQuery) - err := query(db, role) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-EgWQ2", "Errors.Project.Member.NotExisting") - } - return role, err -} - -func ProjectMembersByProjectID(db *gorm.DB, table, projectID string) ([]*model.ProjectMemberView, error) { - members := make([]*model.ProjectMemberView, 0) - queries := []*proj_model.ProjectMemberSearchQuery{ - &proj_model.ProjectMemberSearchQuery{Key: proj_model.ProjectMemberSearchKeyProjectID, Value: projectID, Method: domain.SearchMethodEquals}, - } - query := repository.PrepareSearchQuery(table, model.ProjectMemberSearchRequest{Queries: queries}) - _, err := query(db, &members) - if err != nil { - return nil, err - } - return members, nil -} - -func SearchProjectMembers(db *gorm.DB, table string, req *proj_model.ProjectMemberSearchRequest) ([]*model.ProjectMemberView, uint64, error) { - roles := make([]*model.ProjectMemberView, 0) - query := repository.PrepareSearchQuery(table, model.ProjectMemberSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries}) - count, err := query(db, &roles) - if err != nil { - return nil, 0, err - } - return roles, count, nil -} -func ProjectMembersByUserID(db *gorm.DB, table string, userID string) ([]*model.ProjectMemberView, error) { - members := make([]*model.ProjectMemberView, 0) - queries := []*proj_model.ProjectMemberSearchQuery{ - &proj_model.ProjectMemberSearchQuery{Key: proj_model.ProjectMemberSearchKeyUserID, Value: userID, Method: domain.SearchMethodEquals}, - } - query := repository.PrepareSearchQuery(table, model.ProjectMemberSearchRequest{Queries: queries}) - _, err := query(db, &members) - if err != nil { - return nil, err - } - return members, nil -} - -func PutProjectMember(db *gorm.DB, table string, role *model.ProjectMemberView) error { - save := repository.PrepareSave(table) - return save(db, role) -} - -func PutProjectMembers(db *gorm.DB, table string, members ...*model.ProjectMemberView) error { - save := repository.PrepareBulkSave(table) - m := make([]interface{}, len(members)) - for i, member := range members { - m[i] = member - } - return save(db, m...) -} - -func DeleteProjectMember(db *gorm.DB, table, projectID, userID string) error { - role, err := ProjectMemberByIDs(db, table, projectID, userID) - if err != nil { - return err - } - delete := repository.PrepareDeleteByObject(table, role) - return delete(db) -} - -func DeleteProjectMembersByProjectID(db *gorm.DB, table, projectID string) error { - delete := repository.PrepareDeleteByKey(table, model.ProjectMemberSearchKey(proj_model.ProjectMemberSearchKeyProjectID), projectID) - return delete(db) -} - -func DeleteProjectMembersByUserID(db *gorm.DB, table, userID string) error { - delete := repository.PrepareDeleteByKey(table, model.ProjectMemberSearchKey(proj_model.ProjectMemberSearchKeyUserID), userID) - return delete(db) -} diff --git a/internal/project/repository/view/project_view.go b/internal/project/repository/view/project_view.go deleted file mode 100644 index 92694410b3..0000000000 --- a/internal/project/repository/view/project_view.go +++ /dev/null @@ -1,55 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - proj_model "github.com/caos/zitadel/internal/project/model" - "github.com/caos/zitadel/internal/project/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" - "github.com/jinzhu/gorm" -) - -func ProjectByID(db *gorm.DB, table, projectID string) (*model.ProjectView, error) { - project := new(model.ProjectView) - - projectIDQuery := model.ProjectSearchQuery{Key: proj_model.ProjectViewSearchKeyProjectID, Value: projectID, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, projectIDQuery) - err := query(db, project) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-NEO7W", "Errors.Project.NotFound") - } - return project, err -} - -func ProjectsByResourceOwner(db *gorm.DB, table, orgID string) ([]*model.ProjectView, error) { - projects := make([]*model.ProjectView, 0) - queries := []*proj_model.ProjectViewSearchQuery{ - {Key: proj_model.ProjectViewSearchKeyResourceOwner, Value: orgID, Method: domain.SearchMethodEquals}, - } - query := repository.PrepareSearchQuery(table, model.ProjectSearchRequest{Queries: queries}) - _, err := query(db, &projects) - if err != nil { - return nil, err - } - return projects, nil -} - -func SearchProjects(db *gorm.DB, table string, req *proj_model.ProjectViewSearchRequest) ([]*model.ProjectView, uint64, error) { - projects := make([]*model.ProjectView, 0) - query := repository.PrepareSearchQuery(table, model.ProjectSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries}) - count, err := query(db, &projects) - if err != nil { - return nil, 0, err - } - return projects, count, nil -} - -func PutProject(db *gorm.DB, table string, project *model.ProjectView) error { - save := repository.PrepareSave(table) - return save(db, project) -} - -func DeleteProject(db *gorm.DB, table, projectID string) error { - delete := repository.PrepareDeleteByKey(table, model.ProjectSearchKey(proj_model.ProjectViewSearchKeyProjectID), projectID) - return delete(db) -} diff --git a/internal/query/idp.go b/internal/query/idp.go index 4af4554858..4fe23736c4 100644 --- a/internal/query/idp.go +++ b/internal/query/idp.go @@ -198,28 +198,17 @@ func (q *Queries) IDPByIDAndResourceOwner(ctx context.Context, id, resourceOwner return scan(row) } -//SearchIDPs searches executes the query in the context of the resource owner and IAM -func (q *Queries) SearchIDPs(ctx context.Context, resourceOwner string, queries *IDPSearchQueries) (idps *IDPs, err error) { +//IDPs searches idps matching the query +func (q *Queries) IDPs(ctx context.Context, queries *IDPSearchQueries) (idps *IDPs, err error) { query, scan := prepareIDPsQuery() - query = queries.toQuery(query) - query = query.Where( - sq.Or{ - sq.Eq{ - IDPResourceOwnerCol.identifier(): resourceOwner, - }, - sq.Eq{ - IDPResourceOwnerCol.identifier(): q.iamID, - }, - }, - ) stmt, args, err := queries.toQuery(query).ToSql() if err != nil { - return nil, errors.ThrowInvalidArgument(err, "QUERY-zC6gk", "Errors.Query.InvalidRequest") + return nil, errors.ThrowInvalidArgument(err, "QUERY-X6X7y", "Errors.Query.InvalidRequest") } rows, err := q.client.QueryContext(ctx, stmt, args...) if err != nil { - return nil, errors.ThrowInternal(err, "QUERY-YTug9", "Errors.Internal") + return nil, errors.ThrowInternal(err, "QUERY-xPlVH", "Errors.Internal") } idps, err = scan(rows) if err != nil { @@ -246,6 +235,10 @@ func NewIDPNameSearchQuery(method TextComparison, value string) (SearchQuery, er return NewTextQuery(IDPNameCol, value, method) } +func NewIDPResourceOwnerSearchQuery(value string) (SearchQuery, error) { + return NewTextQuery(IDPResourceOwnerCol, value, TextEquals) +} + func (q *IDPSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder { query = q.SearchRequest.toQuery(query) for _, q := range q.Queries { diff --git a/internal/query/idp_user_link.go b/internal/query/idp_user_link.go index 633b2c708c..e528e4bc9b 100644 --- a/internal/query/idp_user_link.go +++ b/internal/query/idp_user_link.go @@ -16,6 +16,7 @@ type IDPUserLink struct { IDPName string ProvidedUserID string ProvidedUsername string + ResourceOwner string IDPType domain.IDPConfigType } @@ -94,6 +95,10 @@ func (q *Queries) IDPUserLinks(ctx context.Context, queries *IDPUserLinksSearchQ return idps, err } +func NewIDPUserLinkIDPIDSearchQuery(value string) (SearchQuery, error) { + return NewTextQuery(IDPUserLinkIDPIDCol, value, TextEquals) +} + func NewIDPUserLinksUserIDSearchQuery(value string) (SearchQuery, error) { return NewTextQuery(IDPUserLinkUserIDCol, value, TextEquals) } @@ -110,6 +115,7 @@ func prepareIDPUserLinksQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPUserLink IDPUserLinkExternalUserIDCol.identifier(), IDPUserLinkDisplayNameCol.identifier(), IDPTypeCol.identifier(), + IDPUserLinkResourceOwnerCol.identifier(), countColumn.identifier()). From(idpUserLinkTable.identifier()). LeftJoin(join(IDPIDCol, IDPUserLinkIDPIDCol)).PlaceholderFormat(sq.Dollar), @@ -129,6 +135,7 @@ func prepareIDPUserLinksQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPUserLink &idp.ProvidedUserID, &idp.ProvidedUsername, &idpType, + &idp.ResourceOwner, &count, ) if err != nil { diff --git a/internal/query/idp_user_link_test.go b/internal/query/idp_user_link_test.go index b8137506c4..2993c6a057 100644 --- a/internal/query/idp_user_link_test.go +++ b/internal/query/idp_user_link_test.go @@ -18,6 +18,7 @@ var ( ` zitadel.projections.idp_user_links.external_user_id,` + ` zitadel.projections.idp_user_links.display_name,` + ` zitadel.projections.idps.type,` + + ` zitadel.projections.idp_user_links.resource_owner,` + ` COUNT(*) OVER ()` + ` FROM zitadel.projections.idp_user_links` + ` LEFT JOIN zitadel.projections.idps ON zitadel.projections.idp_user_links.idp_id = zitadel.projections.idps.id`) @@ -28,6 +29,7 @@ var ( "external_user_id", "display_name", "type", + "resource_owner", "count", } ) @@ -58,6 +60,7 @@ func Test_IDPUserLinkPrepares(t *testing.T) { "external-user-id", "display-name", domain.IDPConfigTypeJWT, + "ro", }, }, ), @@ -74,6 +77,7 @@ func Test_IDPUserLinkPrepares(t *testing.T) { ProvidedUserID: "external-user-id", ProvidedUsername: "display-name", IDPType: domain.IDPConfigTypeJWT, + ResourceOwner: "ro", }, }, }, @@ -93,6 +97,7 @@ func Test_IDPUserLinkPrepares(t *testing.T) { "external-user-id", "display-name", nil, + "ro", }, }, ), @@ -109,6 +114,7 @@ func Test_IDPUserLinkPrepares(t *testing.T) { ProvidedUserID: "external-user-id", ProvidedUsername: "display-name", IDPType: domain.IDPConfigTypeUnspecified, + ResourceOwner: "ro", }, }, }, diff --git a/internal/query/label_policy.go b/internal/query/label_policy.go index 9406e4d109..ff073861f1 100644 --- a/internal/query/label_policy.go +++ b/internal/query/label_policy.go @@ -276,9 +276,9 @@ func prepareLabelPolicyQuery() (sq.SelectBuilder, func(*sql.Row) (*LabelPolicy, ) if err != nil { if errs.Is(err, sql.ErrNoRows) { - return nil, errors.ThrowNotFound(err, "QUERY-bJEsm", "errors.policy.label.not_found") + return nil, errors.ThrowNotFound(err, "QUERY-bJEsm", "Errors.Org.PolicyNotExisting") } - return nil, errors.ThrowInternal(err, "QUERY-awLM6", "errors.internal") + return nil, errors.ThrowInternal(err, "QUERY-awLM6", "Errors.Internal") } policy.FontURL = fontURL.String diff --git a/internal/query/org.go b/internal/query/org.go index 4e9716228b..d2481a7414 100644 --- a/internal/query/org.go +++ b/internal/query/org.go @@ -157,6 +157,14 @@ func NewOrgNameSearchQuery(method TextComparison, value string) (SearchQuery, er return NewTextQuery(OrgColumnName, value, method) } +func NewOrgIDsSearchQuery(ids ...string) (SearchQuery, error) { + list := make([]interface{}, len(ids)) + for i, value := range ids { + list[i] = value + } + return NewListQuery(OrgColumnID, list, ListIn) +} + func prepareOrgsQuery() (sq.SelectBuilder, func(*sql.Rows) (*Orgs, error)) { return sq.Select( OrgColumnID.identifier(), diff --git a/internal/query/org_member.go b/internal/query/org_member.go index 136262ca59..f59f821417 100644 --- a/internal/query/org_member.go +++ b/internal/query/org_member.go @@ -110,9 +110,9 @@ func prepareOrgMembersQuery() (sq.SelectBuilder, func(*sql.Rows) (*Members, erro for rows.Next() { member := new(Member) - roles := pq.StringArray{} var ( + roles = pq.StringArray{} preferredLoginName = sql.NullString{} email = sql.NullString{} firstName = sql.NullString{} diff --git a/internal/user/repository/view/usermembership_view.go b/internal/user/repository/view/usermembership_view.go index 111d717bff..47e3e95d40 100644 --- a/internal/user/repository/view/usermembership_view.go +++ b/internal/user/repository/view/usermembership_view.go @@ -35,16 +35,6 @@ func UserMembershipsByAggregateID(db *gorm.DB, table, aggregateID string) ([]*mo return memberships, err } -func UserMembershipsByUserID(db *gorm.DB, table, userID string) ([]*model.UserMembershipView, error) { - memberships := make([]*model.UserMembershipView, 0) - aggregateIDQuery := &usr_model.UserMembershipSearchQuery{Key: usr_model.UserMembershipSearchKeyUserID, Value: userID, Method: domain.SearchMethodEquals} - query := repository.PrepareSearchQuery(table, model.UserMembershipSearchRequest{ - Queries: []*usr_model.UserMembershipSearchQuery{aggregateIDQuery}, - }) - _, err := query(db, &memberships) - return memberships, err -} - func UserMembershipsByResourceOwner(db *gorm.DB, table, resourceOwner string) ([]*model.UserMembershipView, error) { memberships := make([]*model.UserMembershipView, 0) aggregateIDQuery := &usr_model.UserMembershipSearchQuery{Key: usr_model.UserMembershipSearchKeyResourceOwner, Value: resourceOwner, Method: domain.SearchMethodEquals}