diff --git a/internal/api/api.go b/internal/api/api.go index c053dea910..561b1a7f71 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -21,7 +21,6 @@ import ( "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/domain" "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/query" "github.com/caos/zitadel/internal/telemetry/metrics" "github.com/caos/zitadel/internal/telemetry/metrics/otel" @@ -46,7 +45,7 @@ type API struct { type health interface { Health(ctx context.Context) error - IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) + IAMByID(ctx context.Context, id string) (*query.IAM, error) VerifierClientID(ctx context.Context, appName string) (string, string, error) } @@ -112,10 +111,10 @@ func (a *API) healthHandler() http.Handler { if err != nil && !errors.IsNotFound(err) { return errors.ThrowPreconditionFailed(err, "API-dsgT2", "IAM SETUP CHECK FAILED") } - if iam == nil || iam.SetUpStarted < domain.StepCount-1 { + if iam == nil || iam.SetupStarted < domain.StepCount-1 { return errors.ThrowPreconditionFailed(nil, "API-HBfs3", "IAM NOT SET UP") } - if iam.SetUpDone < domain.StepCount-1 { + if iam.SetupDone < domain.StepCount-1 { return errors.ThrowPreconditionFailed(nil, "API-DASs2", "IAM SETUP RUNNING") } return nil diff --git a/internal/api/grpc/auth/language.go b/internal/api/grpc/auth/language.go index f794d4c9ea..a1c4fc1798 100644 --- a/internal/api/grpc/auth/language.go +++ b/internal/api/grpc/auth/language.go @@ -8,7 +8,7 @@ import ( ) func (s *Server) GetSupportedLanguages(ctx context.Context, req *auth_pb.GetSupportedLanguagesRequest) (*auth_pb.GetSupportedLanguagesResponse, error) { - langs, err := s.repo.Languages(ctx) + langs, err := s.query.Languages(ctx) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/language.go b/internal/api/grpc/management/language.go index 68327bfd14..015a923bdf 100644 --- a/internal/api/grpc/management/language.go +++ b/internal/api/grpc/management/language.go @@ -8,7 +8,7 @@ import ( ) func (s *Server) GetSupportedLanguages(ctx context.Context, req *mgmt_pb.GetSupportedLanguagesRequest) (*mgmt_pb.GetSupportedLanguagesResponse, error) { - langs, err := s.org.Languages(ctx) + langs, err := s.query.Languages(ctx) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/org.go b/internal/api/grpc/management/org.go index 2252486ee3..e4312a6164 100644 --- a/internal/api/grpc/management/org.go +++ b/internal/api/grpc/management/org.go @@ -207,7 +207,7 @@ 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) { - iam, err := s.iam.IAMByID(ctx, domain.IAMID) + iam, err := s.query.IAMByID(ctx, domain.IAMID) if err != nil { return nil, err } diff --git a/internal/api/grpc/management/server.go b/internal/api/grpc/management/server.go index ddf8c8ce44..e9c79e39fc 100644 --- a/internal/api/grpc/management/server.go +++ b/internal/api/grpc/management/server.go @@ -26,7 +26,6 @@ type Server struct { project repository.ProjectRepository org repository.OrgRepository user repository.UserRepository - iam repository.IamRepository systemDefaults systemdefaults.SystemDefaults assetAPIPrefix string } @@ -42,7 +41,6 @@ func CreateServer(command *command.Commands, query *query.Queries, repo reposito project: repo, org: repo, user: repo, - iam: repo, systemDefaults: sd, assetAPIPrefix: assetAPIPrefix, } diff --git a/internal/auth/repository/eventsourcing/eventstore/iam.go b/internal/auth/repository/eventsourcing/eventstore/iam.go deleted file mode 100644 index b5d37c705b..0000000000 --- a/internal/auth/repository/eventsourcing/eventstore/iam.go +++ /dev/null @@ -1,38 +0,0 @@ -package eventstore - -import ( - "context" - "net/http" - - "github.com/caos/logging" - "golang.org/x/text/language" - - "github.com/caos/zitadel/internal/i18n" - "github.com/caos/zitadel/internal/query" - - "github.com/caos/zitadel/internal/iam/model" -) - -type IAMRepository struct { - IAMID string - LoginDir http.FileSystem - - IAMV2QuerySide *query.Queries - supportedLangs []language.Tag -} - -func (repo *IAMRepository) Languages(ctx context.Context) ([]language.Tag, error) { - if len(repo.supportedLangs) == 0 { - langs, err := i18n.SupportedLanguages(repo.LoginDir) - if err != nil { - logging.Log("ADMIN-tiMWs").WithError(err).Debug("unable to parse language") - return nil, err - } - repo.supportedLangs = langs - } - return repo.supportedLangs, nil -} - -func (repo *IAMRepository) GetIAM(ctx context.Context) (*model.IAM, error) { - return repo.IAMV2QuerySide.IAMByID(ctx, repo.IAMID) -} diff --git a/internal/auth/repository/eventsourcing/repository.go b/internal/auth/repository/eventsourcing/repository.go index a7549d30b2..eb00722b30 100644 --- a/internal/auth/repository/eventsourcing/repository.go +++ b/internal/auth/repository/eventsourcing/repository.go @@ -3,9 +3,6 @@ package eventsourcing import ( "context" - "github.com/caos/logging" - "github.com/rakyll/statik/fs" - "github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/auth/repository/eventsourcing/eventstore" "github.com/caos/zitadel/internal/auth/repository/eventsourcing/spooler" @@ -44,7 +41,6 @@ type EsRepository struct { eventstore.UserSessionRepo eventstore.UserGrantRepo eventstore.OrgRepository - eventstore.IAMRepository } func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, command *command.Commands, queries *query.Queries, authZRepo *authz_repo.EsRepository, esV2 *es2.Eventstore) (*EsRepository, error) { @@ -76,9 +72,6 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co return nil, err } - statikLoginFS, err := fs.NewWithNamespace("login") - logging.Log("CONFI-20opp").OnError(err).Panic("unable to start login statik dir") - spool := spooler.StartSpooler(conf.Spooler, es, view, sqlClient, systemDefaults, queries) userRepo := eventstore.UserRepo{ @@ -161,11 +154,6 @@ func Start(conf Config, authZ authz.Config, systemDefaults sd.SystemDefaults, co Eventstore: es, Query: queries, }, - eventstore.IAMRepository{ - IAMID: systemDefaults.IamID, - LoginDir: statikLoginFS, - IAMV2QuerySide: queries, - }, }, nil } diff --git a/internal/auth/repository/iam.go b/internal/auth/repository/iam.go deleted file mode 100644 index fb0ba1885f..0000000000 --- a/internal/auth/repository/iam.go +++ /dev/null @@ -1,14 +0,0 @@ -package repository - -import ( - "context" - - "golang.org/x/text/language" - - "github.com/caos/zitadel/internal/iam/model" -) - -type IAMRepository interface { - Languages(ctx context.Context) ([]language.Tag, error) - GetIAM(ctx context.Context) (*model.IAM, error) -} diff --git a/internal/auth/repository/repository.go b/internal/auth/repository/repository.go index fee6594207..0e35656a9a 100644 --- a/internal/auth/repository/repository.go +++ b/internal/auth/repository/repository.go @@ -13,6 +13,5 @@ type Repository interface { UserSessionRepository UserGrantRepository OrgRepository - IAMRepository RefreshTokenRepository } diff --git a/internal/iam/repository/eventsourcing/cache.go b/internal/iam/repository/eventsourcing/cache.go deleted file mode 100644 index 3bf3c7afde..0000000000 --- a/internal/iam/repository/eventsourcing/cache.go +++ /dev/null @@ -1,35 +0,0 @@ -package eventsourcing - -import ( - "github.com/caos/logging" - "github.com/caos/zitadel/internal/cache" - "github.com/caos/zitadel/internal/cache/config" - "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" -) - -type IAMCache struct { - iamCache cache.Cache -} - -func StartCache(conf *config.CacheConfig) (*IAMCache, error) { - iamCache, err := conf.Config.NewCache() - logging.Log("EVENT-9siew").OnError(err).Panic("unable to create iam cache") - - return &IAMCache{iamCache: iamCache}, nil -} - -func (c *IAMCache) getIAM(ID string) *model.IAM { - user := &model.IAM{ObjectRoot: models.ObjectRoot{AggregateID: ID}} - if err := c.iamCache.Get(ID, user); err != nil { - logging.Log("EVENT-slo9x").WithError(err).Debug("error in getting cache") - } - return user -} - -func (c *IAMCache) cacheIAM(iam *model.IAM) { - err := c.iamCache.Set(iam.AggregateID, iam) - if err != nil { - logging.Log("EVENT-os03w").WithError(err).Debug("error in setting iam cache") - } -} diff --git a/internal/iam/repository/eventsourcing/eventstore.go b/internal/iam/repository/eventsourcing/eventstore.go deleted file mode 100644 index ad78d4ae08..0000000000 --- a/internal/iam/repository/eventsourcing/eventstore.go +++ /dev/null @@ -1,11 +0,0 @@ -package eventsourcing - -import ( - "github.com/caos/zitadel/internal/cache/config" - "github.com/caos/zitadel/internal/eventstore/v1" -) - -type IAMConfig struct { - v1.Eventstore - Cache *config.CacheConfig -} diff --git a/internal/iam/repository/eventsourcing/iam.go b/internal/iam/repository/eventsourcing/iam.go deleted file mode 100644 index a4bdf6b674..0000000000 --- a/internal/iam/repository/eventsourcing/iam.go +++ /dev/null @@ -1,30 +0,0 @@ -package eventsourcing - -import ( - "context" - - "github.com/caos/zitadel/internal/errors" - es_models "github.com/caos/zitadel/internal/eventstore/v1/models" - "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model" -) - -func IAMByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) { - if id == "" { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-0soe4", "Errors.IAM.IDMissing") - } - return IAMQuery(latestSequence). - AggregateIDFilter(id), nil -} - -func IAMQuery(latestSequence uint64) *es_models.SearchQuery { - return es_models.NewSearchQuery(). - AggregateTypeFilter(model.IAMAggregate). - LatestSequenceFilter(latestSequence) -} - -func IAMAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, iam *model.IAM) (*es_models.Aggregate, error) { - if iam == nil { - return nil, errors.ThrowPreconditionFailed(nil, "EVENT-lo04e", "Errors.Internal") - } - return aggCreator.NewAggregate(ctx, iam.AggregateID, model.IAMAggregate, model.IAMVersion, iam.Sequence) -} diff --git a/internal/iam/repository/view/custom_text_view.go b/internal/iam/repository/view/custom_text_view.go deleted file mode 100644 index dddcdfdd76..0000000000 --- a/internal/iam/repository/view/custom_text_view.go +++ /dev/null @@ -1,96 +0,0 @@ -package view - -import ( - "github.com/jinzhu/gorm" - - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -func GetCustomTexts(db *gorm.DB, table string, aggregateID, template, lang string) ([]*model.CustomTextView, error) { - texts := make([]*model.CustomTextView, 0) - queries := []*iam_model.CustomTextSearchQuery{ - { - Key: iam_model.CustomTextSearchKeyAggregateID, - Value: aggregateID, - Method: domain.SearchMethodEquals, - }, - { - Key: iam_model.CustomTextSearchKeyTemplate, - Value: template, - Method: domain.SearchMethodEquals, - }, - { - Key: iam_model.CustomTextSearchKeyLanguage, - Value: lang, - Method: domain.SearchMethodEquals, - }, - } - query := repository.PrepareSearchQuery(table, model.CustomTextSearchRequest{Queries: queries}) - _, err := query(db, &texts) - if err != nil { - return nil, err - } - return texts, nil -} - -func GetCustomTextsByAggregateIDAndTemplate(db *gorm.DB, table string, aggregateID, template string) ([]*model.CustomTextView, error) { - texts := make([]*model.CustomTextView, 0) - queries := []*iam_model.CustomTextSearchQuery{ - { - Key: iam_model.CustomTextSearchKeyAggregateID, - Value: aggregateID, - Method: domain.SearchMethodEquals, - }, - { - Key: iam_model.CustomTextSearchKeyTemplate, - Value: template, - Method: domain.SearchMethodEquals, - }, - } - query := repository.PrepareSearchQuery(table, model.CustomTextSearchRequest{Queries: queries}) - _, err := query(db, &texts) - if err != nil { - return nil, err - } - return texts, nil -} - -func CustomTextByIDs(db *gorm.DB, table, aggregateID, template, lang, key string) (*model.CustomTextView, error) { - customText := new(model.CustomTextView) - aggregateIDQuery := &model.CustomTextSearchQuery{Key: iam_model.CustomTextSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals} - textTypeQuery := &model.CustomTextSearchQuery{Key: iam_model.CustomTextSearchKeyTemplate, Value: template, Method: domain.SearchMethodEquals} - languageQuery := &model.CustomTextSearchQuery{Key: iam_model.CustomTextSearchKeyLanguage, Value: lang, Method: domain.SearchMethodEquals} - keyQuery := &model.CustomTextSearchQuery{Key: iam_model.CustomTextSearchKeyKey, Value: key, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, aggregateIDQuery, textTypeQuery, languageQuery, keyQuery) - err := query(db, customText) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-8nUU3", "Errors.CustomCustomText.NotExisting") - } - return customText, err -} - -func PutCustomText(db *gorm.DB, table string, customText *model.CustomTextView) error { - save := repository.PrepareSave(table) - return save(db, customText) -} - -func DeleteCustomText(db *gorm.DB, table, aggregateID, template, lang, key string) error { - aggregateIDSearch := repository.Key{Key: model.CustomTextSearchKey(iam_model.CustomTextSearchKeyAggregateID), Value: aggregateID} - templateSearch := repository.Key{Key: model.CustomTextSearchKey(iam_model.CustomTextSearchKeyTemplate), Value: template} - languageSearch := repository.Key{Key: model.CustomTextSearchKey(iam_model.CustomTextSearchKeyLanguage), Value: lang} - keySearch := repository.Key{Key: model.CustomTextSearchKey(iam_model.CustomTextSearchKeyKey), Value: key} - delete := repository.PrepareDeleteByKeys(table, aggregateIDSearch, templateSearch, keySearch, languageSearch) - return delete(db) -} - -func DeleteCustomTextTemplate(db *gorm.DB, table, aggregateID, template, lang string) error { - aggregateIDSearch := repository.Key{Key: model.CustomTextSearchKey(iam_model.CustomTextSearchKeyAggregateID), Value: aggregateID} - templateSearch := repository.Key{Key: model.CustomTextSearchKey(iam_model.CustomTextSearchKeyTemplate), Value: template} - languageSearch := repository.Key{Key: model.CustomTextSearchKey(iam_model.CustomTextSearchKeyLanguage), Value: lang} - delete := repository.PrepareDeleteByKeys(table, aggregateIDSearch, templateSearch, languageSearch) - return delete(db) -} diff --git a/internal/iam/repository/view/iam_member_view.go b/internal/iam/repository/view/iam_member_view.go deleted file mode 100644 index 49932403f2..0000000000 --- a/internal/iam/repository/view/iam_member_view.go +++ /dev/null @@ -1,77 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" - "github.com/jinzhu/gorm" -) - -func IAMMemberByIDs(db *gorm.DB, table, orgID, userID string) (*model.IAMMemberView, error) { - member := new(model.IAMMemberView) - - iamIDQuery := &model.IAMMemberSearchQuery{Key: iam_model.IAMMemberSearchKeyIamID, Value: orgID, Method: domain.SearchMethodEquals} - userIDQuery := &model.IAMMemberSearchQuery{Key: iam_model.IAMMemberSearchKeyUserID, Value: userID, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, iamIDQuery, userIDQuery) - err := query(db, member) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-Ahq2s", "Errors.IAM.MemberNotExisting") - } - return member, err -} - -func SearchIAMMembers(db *gorm.DB, table string, req *iam_model.IAMMemberSearchRequest) ([]*model.IAMMemberView, uint64, error) { - members := make([]*model.IAMMemberView, 0) - query := repository.PrepareSearchQuery(table, model.IAMMemberSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries}) - count, err := query(db, &members) - if err != nil { - return nil, 0, err - } - return members, count, nil -} -func IAMMembersByUserID(db *gorm.DB, table string, userID string) ([]*model.IAMMemberView, error) { - members := make([]*model.IAMMemberView, 0) - queries := []*iam_model.IAMMemberSearchQuery{ - { - Key: iam_model.IAMMemberSearchKeyUserID, - Value: userID, - Method: domain.SearchMethodEquals, - }, - } - query := repository.PrepareSearchQuery(table, model.IAMMemberSearchRequest{Queries: queries}) - _, err := query(db, &members) - if err != nil { - return nil, err - } - return members, nil -} - -func PutIAMMember(db *gorm.DB, table string, role *model.IAMMemberView) error { - save := repository.PrepareSave(table) - return save(db, role) -} - -func PutIAMMembers(db *gorm.DB, table string, members ...*model.IAMMemberView) error { - save := repository.PrepareBulkSave(table) - m := make([]interface{}, len(members)) - for i, member := range members { - m[i] = member - } - return save(db, m...) -} - -func DeleteIAMMember(db *gorm.DB, table, orgID, userID string) error { - member, err := IAMMemberByIDs(db, table, orgID, userID) - if err != nil { - return err - } - delete := repository.PrepareDeleteByObject(table, member) - return delete(db) -} - -func DeleteIAMMembersByUserID(db *gorm.DB, table, userID string) error { - delete := repository.PrepareDeleteByKey(table, model.IAMMemberSearchKey(iam_model.IAMMemberSearchKeyUserID), userID) - return delete(db) -} diff --git a/internal/iam/repository/view/message_text_view.go b/internal/iam/repository/view/message_text_view.go deleted file mode 100644 index 345664904f..0000000000 --- a/internal/iam/repository/view/message_text_view.go +++ /dev/null @@ -1,54 +0,0 @@ -package view - -import ( - "github.com/jinzhu/gorm" - - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/iam/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -func GetMessageTexts(db *gorm.DB, table string, aggregateID string) ([]*model.MessageTextView, error) { - texts := make([]*model.MessageTextView, 0) - queries := []*iam_model.MessageTextSearchQuery{ - { - Key: iam_model.MessageTextSearchKeyAggregateID, - Value: aggregateID, - Method: domain.SearchMethodEquals, - }, - } - query := repository.PrepareSearchQuery(table, model.MessageTextSearchRequest{Queries: queries}) - _, err := query(db, &texts) - if err != nil { - return nil, err - } - return texts, nil -} - -func GetMessageTextByIDs(db *gorm.DB, table, aggregateID, textType, lang string) (*model.MessageTextView, error) { - mailText := new(model.MessageTextView) - aggregateIDQuery := &model.MessageTextSearchQuery{Key: iam_model.MessageTextSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals} - textTypeQuery := &model.MessageTextSearchQuery{Key: iam_model.MessageTextSearchKeyMessageTextType, Value: textType, Method: domain.SearchMethodEquals} - languageQuery := &model.MessageTextSearchQuery{Key: iam_model.MessageTextSearchKeyLanguage, Value: lang, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, aggregateIDQuery, textTypeQuery, languageQuery) - err := query(db, mailText) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-IiJjm", "Errors.IAM.CustomMessageText.NotExisting") - } - return mailText, err -} - -func PutMessageText(db *gorm.DB, table string, mailText *model.MessageTextView) error { - save := repository.PrepareSave(table) - return save(db, mailText) -} - -func DeleteMessageText(db *gorm.DB, table, aggregateID, textType, lang string) error { - aggregateIDSearch := repository.Key{Key: model.MessageTextSearchKey(iam_model.MessageTextSearchKeyAggregateID), Value: aggregateID} - textTypeSearch := repository.Key{Key: model.MessageTextSearchKey(iam_model.MessageTextSearchKeyMessageTextType), Value: textType} - languageSearch := repository.Key{Key: model.MessageTextSearchKey(iam_model.MessageTextSearchKeyLanguage), Value: lang} - delete := repository.PrepareDeleteByKeys(table, aggregateIDSearch, textTypeSearch, languageSearch) - return delete(db) -} diff --git a/internal/iam/repository/view/metadata_view.go b/internal/iam/repository/view/metadata_view.go deleted file mode 100644 index c378019dd3..0000000000 --- a/internal/iam/repository/view/metadata_view.go +++ /dev/null @@ -1,80 +0,0 @@ -package view - -import ( - "github.com/jinzhu/gorm" - - "github.com/caos/zitadel/internal/domain" - caos_errs "github.com/caos/zitadel/internal/errors" - "github.com/caos/zitadel/internal/iam/repository/view/model" - "github.com/caos/zitadel/internal/view/repository" -) - -func GetMetadataList(db *gorm.DB, table string, aggregateID string) ([]*model.MetadataView, error) { - metadatas := make([]*model.MetadataView, 0) - queries := []*domain.MetadataSearchQuery{ - { - Key: domain.MetadataSearchKeyAggregateID, - Value: aggregateID, - Method: domain.SearchMethodEquals, - }, - } - query := repository.PrepareSearchQuery(table, model.MetadataSearchRequest{Queries: queries}) - _, err := query(db, &metadatas) - if err != nil { - return nil, err - } - return metadatas, nil -} - -func MetadataByKey(db *gorm.DB, table, aggregateID, key string) (*model.MetadataView, error) { - metadata := new(model.MetadataView) - aggregateIDQuery := &model.MetadataSearchQuery{Key: domain.MetadataSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals} - keyQuery := &model.MetadataSearchQuery{Key: domain.MetadataSearchKeyKey, Value: key, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, aggregateIDQuery, keyQuery) - err := query(db, metadata) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-m0pes", "Errors.Metadata.NotExisting") - } - return metadata, err -} - -func MetadataByKeyAndResourceOwner(db *gorm.DB, table, aggregateID, resourceOwner, key string) (*model.MetadataView, error) { - metadata := new(model.MetadataView) - aggregateIDQuery := &model.MetadataSearchQuery{Key: domain.MetadataSearchKeyAggregateID, Value: aggregateID, Method: domain.SearchMethodEquals} - resourceOwnerQuery := &model.MetadataSearchQuery{Key: domain.MetadataSearchKeyResourceOwner, Value: resourceOwner, Method: domain.SearchMethodEquals} - keyQuery := &model.MetadataSearchQuery{Key: domain.MetadataSearchKeyKey, Value: key, Method: domain.SearchMethodEquals} - query := repository.PrepareGetByQuery(table, aggregateIDQuery, resourceOwnerQuery, keyQuery) - err := query(db, metadata) - if caos_errs.IsNotFound(err) { - return nil, caos_errs.ThrowNotFound(nil, "VIEW-29kkd", "Errors.Metadata.NotExisting") - } - return metadata, err -} - -func SearchMetadata(db *gorm.DB, table string, req *domain.MetadataSearchRequest) ([]*model.MetadataView, uint64, error) { - metadata := make([]*model.MetadataView, 0) - query := repository.PrepareSearchQuery(table, model.MetadataSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries}) - count, err := query(db, &metadata) - if err != nil { - return nil, 0, err - } - return metadata, count, nil -} - -func PutMetadata(db *gorm.DB, table string, customText *model.MetadataView) error { - save := repository.PrepareSave(table) - return save(db, customText) -} - -func DeleteMetadata(db *gorm.DB, table, aggregateID, key string) error { - aggregateIDQuery := repository.Key{Key: model.MetadataSearchKey(domain.MetadataSearchKeyAggregateID), Value: aggregateID} - keyQuery := repository.Key{Key: model.MetadataSearchKey(domain.MetadataSearchKeyKey), Value: key} - deleteMD := repository.PrepareDeleteByKeys(table, aggregateIDQuery, keyQuery) - return deleteMD(db) -} - -func DeleteMetadataByAggregateID(db *gorm.DB, table, aggregateID string) error { - aggregateIDQuery := repository.Key{Key: model.MetadataSearchKey(domain.MetadataSearchKeyAggregateID), Value: aggregateID} - deleteMD := repository.PrepareDeleteByKeys(table, aggregateIDQuery) - return deleteMD(db) -} diff --git a/internal/management/repository/eventsourcing/eventstore/iam.go b/internal/management/repository/eventsourcing/eventstore/iam.go deleted file mode 100644 index 89380fa7d7..0000000000 --- a/internal/management/repository/eventsourcing/eventstore/iam.go +++ /dev/null @@ -1,16 +0,0 @@ -package eventstore - -import ( - "context" - - iam_model "github.com/caos/zitadel/internal/iam/model" - "github.com/caos/zitadel/internal/query" -) - -type IAMRepository struct { - IAMV2Query *query.Queries -} - -func (repo *IAMRepository) IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) { - return repo.IAMV2Query.IAMByID(ctx, id) -} diff --git a/internal/management/repository/eventsourcing/eventstore/org.go b/internal/management/repository/eventsourcing/eventstore/org.go index 591c57e00e..d081eb7acf 100644 --- a/internal/management/repository/eventsourcing/eventstore/org.go +++ b/internal/management/repository/eventsourcing/eventstore/org.go @@ -16,7 +16,6 @@ import ( "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/i18n" 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" @@ -38,18 +37,6 @@ type OrgRepository struct { supportedLangs []language.Tag } -func (repo *OrgRepository) Languages(ctx context.Context) ([]language.Tag, error) { - if len(repo.supportedLangs) == 0 { - langs, err := i18n.SupportedLanguages(repo.LoginDir) - if err != nil { - logging.Log("ADMIN-tiMWs").WithError(err).Debug("unable to parse language") - return nil, err - } - repo.supportedLangs = langs - } - return repo.supportedLangs, nil -} - func (repo *OrgRepository) OrgChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool, auditLogRetention time.Duration) (*org_model.OrgChanges, error) { changes, err := repo.getOrgChanges(ctx, id, lastSequence, limit, sortAscending, auditLogRetention) if err != nil { diff --git a/internal/management/repository/eventsourcing/repository.go b/internal/management/repository/eventsourcing/repository.go index 4ba6037c89..bd3223b20c 100644 --- a/internal/management/repository/eventsourcing/repository.go +++ b/internal/management/repository/eventsourcing/repository.go @@ -24,7 +24,6 @@ type EsRepository struct { eventstore.OrgRepository eventstore.ProjectRepo eventstore.UserRepo - eventstore.IAMRepository } func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string, queries *query.Queries, staticStorage static.Storage) (*EsRepository, error) { @@ -55,8 +54,7 @@ func Start(conf Config, systemDefaults sd.SystemDefaults, roles []string, querie NotificationTranslationFileContents: make(map[string][]byte), Query: queries, }, - ProjectRepo: eventstore.ProjectRepo{es, roles, systemDefaults.IamID, assetsAPI, queries}, - UserRepo: eventstore.UserRepo{es, queries, systemDefaults, assetsAPI}, - IAMRepository: eventstore.IAMRepository{IAMV2Query: queries}, + ProjectRepo: eventstore.ProjectRepo{es, roles, systemDefaults.IamID, assetsAPI, queries}, + UserRepo: eventstore.UserRepo{es, queries, systemDefaults, assetsAPI}, }, nil } diff --git a/internal/management/repository/iam.go b/internal/management/repository/iam.go deleted file mode 100644 index 1846575204..0000000000 --- a/internal/management/repository/iam.go +++ /dev/null @@ -1,10 +0,0 @@ -package repository - -import ( - "context" - iam_model "github.com/caos/zitadel/internal/iam/model" -) - -type IamRepository interface { - IAMByID(ctx context.Context, id string) (*iam_model.IAM, error) -} diff --git a/internal/management/repository/org.go b/internal/management/repository/org.go index b873390173..3182d864bb 100644 --- a/internal/management/repository/org.go +++ b/internal/management/repository/org.go @@ -4,13 +4,10 @@ import ( "context" "time" - "golang.org/x/text/language" - org_model "github.com/caos/zitadel/internal/org/model" ) 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(isGlobal bool) []string diff --git a/internal/management/repository/repository.go b/internal/management/repository/repository.go index 496a80ed9b..2b8511d81f 100644 --- a/internal/management/repository/repository.go +++ b/internal/management/repository/repository.go @@ -4,5 +4,4 @@ type Repository interface { ProjectRepository OrgRepository UserRepository - IamRepository } diff --git a/internal/notification/repository/eventsourcing/view/message_text.go b/internal/notification/repository/eventsourcing/view/message_text.go deleted file mode 100644 index 486895a475..0000000000 --- a/internal/notification/repository/eventsourcing/view/message_text.go +++ /dev/null @@ -1,10 +0,0 @@ -package view - -import ( - "github.com/caos/zitadel/internal/iam/repository/view" - "github.com/caos/zitadel/internal/iam/repository/view/model" -) - -func (v *View) MessageTextByIDs(aggregateID, textType, lang, messageTextTableVar string) (*model.MessageTextView, error) { - return view.GetMessageTextByIDs(v.Db, messageTextTableVar, aggregateID, textType, lang) -} diff --git a/internal/query/iam.go b/internal/query/iam.go new file mode 100644 index 0000000000..a1dfb8460a --- /dev/null +++ b/internal/query/iam.go @@ -0,0 +1,116 @@ +package query + +import ( + "context" + "database/sql" + errs "errors" + "time" + + sq "github.com/Masterminds/squirrel" + "github.com/caos/zitadel/internal/domain" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/query/projection" +) + +var ( + iamTable = table{ + name: projection.IAMProjectionTable, + } + IAMColumnID = Column{ + name: projection.IAMColumnID, + table: iamTable, + } + IAMColumnChangeDate = Column{ + name: projection.IAMColumnChangeDate, + table: iamTable, + } + IAMColumnSequence = Column{ + name: projection.IAMColumnSequence, + table: iamTable, + } + IAMColumnGlobalOrgID = Column{ + name: projection.IAMColumnGlobalOrgID, + table: iamTable, + } + IAMColumnProjectID = Column{ + name: projection.IAMColumnProjectID, + table: iamTable, + } + IAMColumnSetupStarted = Column{ + name: projection.IAMColumnSetUpStarted, + table: iamTable, + } + IAMColumnSetupDone = Column{ + name: projection.IAMColumnSetUpDone, + table: iamTable, + } +) + +type IAM struct { + ID string + ChangeDate time.Time + Sequence uint64 + + GlobalOrgID string + IAMProjectID string + SetupStarted domain.Step + SetupDone domain.Step +} + +type IAMSearchQueries struct { + SearchRequest + Queries []SearchQuery +} + +func (q *IAMSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder { + query = q.SearchRequest.toQuery(query) + for _, q := range q.Queries { + query = q.toQuery(query) + } + return query +} + +func (q *Queries) IAMByID(ctx context.Context, id string) (*IAM, error) { + stmt, scan := prepareIAMQuery() + query, args, err := stmt.Where(sq.Eq{ + IAMColumnID.identifier(): id, + }).ToSql() + if err != nil { + return nil, errors.ThrowInternal(err, "QUERY-d9ngs", "Errors.Query.SQLStatement") + } + + row := q.client.QueryRowContext(ctx, query, args...) + return scan(row) +} + +func prepareIAMQuery() (sq.SelectBuilder, func(*sql.Row) (*IAM, error)) { + return sq.Select( + IAMColumnID.identifier(), + IAMColumnChangeDate.identifier(), + IAMColumnSequence.identifier(), + IAMColumnGlobalOrgID.identifier(), + IAMColumnProjectID.identifier(), + IAMColumnSetupStarted.identifier(), + IAMColumnSetupDone.identifier(), + ). + From(iamTable.identifier()).PlaceholderFormat(sq.Dollar), + func(row *sql.Row) (*IAM, error) { + o := new(IAM) + err := row.Scan( + &o.ID, + &o.ChangeDate, + &o.Sequence, + &o.GlobalOrgID, + &o.IAMProjectID, + &o.SetupStarted, + &o.SetupDone, + ) + if err != nil { + if errs.Is(err, sql.ErrNoRows) { + return nil, errors.ThrowNotFound(err, "QUERY-n0wng", "Errors.IAM.NotFound") + } + return nil, errors.ThrowInternal(err, "QUERY-d9nw", "Errors.Internal") + } + return o, nil + } +} diff --git a/internal/query/iam_test.go b/internal/query/iam_test.go new file mode 100644 index 0000000000..e5f7a92593 --- /dev/null +++ b/internal/query/iam_test.go @@ -0,0 +1,124 @@ +package query + +import ( + "database/sql" + "database/sql/driver" + "errors" + "fmt" + "regexp" + "testing" + + "github.com/caos/zitadel/internal/domain" + errs "github.com/caos/zitadel/internal/errors" +) + +func Test_IAMPrepares(t *testing.T) { + type want struct { + sqlExpectations sqlExpectation + err checkErr + } + tests := []struct { + name string + prepare interface{} + want want + object interface{} + }{ + { + name: "prepareIAMQuery no result", + prepare: prepareIAMQuery, + want: want{ + sqlExpectations: mockQueries( + regexp.QuoteMeta(`SELECT zitadel.projections.iam.id,`+ + ` zitadel.projections.iam.change_date,`+ + ` zitadel.projections.iam.sequence,`+ + ` zitadel.projections.iam.global_org_id,`+ + ` zitadel.projections.iam.iam_project_id,`+ + ` zitadel.projections.iam.setup_started,`+ + ` zitadel.projections.iam.setup_done`+ + ` FROM zitadel.projections.iam`), + nil, + nil, + ), + err: func(err error) (error, bool) { + if !errs.IsNotFound(err) { + return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false + } + return nil, true + }, + }, + object: (*IAM)(nil), + }, + { + name: "prepareIAMQuery found", + prepare: prepareIAMQuery, + want: want{ + sqlExpectations: mockQuery( + regexp.QuoteMeta(`SELECT zitadel.projections.iam.id,`+ + ` zitadel.projections.iam.change_date,`+ + ` zitadel.projections.iam.sequence,`+ + ` zitadel.projections.iam.global_org_id,`+ + ` zitadel.projections.iam.iam_project_id,`+ + ` zitadel.projections.iam.setup_started,`+ + ` zitadel.projections.iam.setup_done`+ + ` FROM zitadel.projections.iam`), + []string{ + "id", + "change_date", + "sequence", + "global_org_id", + "iam_project_id", + "setup_started", + "setup_done", + }, + []driver.Value{ + "id", + testNow, + uint64(20211108), + "global-org-id", + "project-id", + domain.Step2, + domain.Step1, + }, + ), + }, + object: &IAM{ + ID: "id", + ChangeDate: testNow, + Sequence: 20211108, + GlobalOrgID: "global-org-id", + IAMProjectID: "project-id", + SetupStarted: domain.Step2, + SetupDone: domain.Step1, + }, + }, + { + name: "prepareIAMQuery sql err", + prepare: prepareIAMQuery, + want: want{ + sqlExpectations: mockQueryErr( + regexp.QuoteMeta(`SELECT zitadel.projections.iam.id,`+ + ` zitadel.projections.iam.change_date,`+ + ` zitadel.projections.iam.sequence,`+ + ` zitadel.projections.iam.global_org_id,`+ + ` zitadel.projections.iam.iam_project_id,`+ + ` zitadel.projections.iam.setup_started,`+ + ` zitadel.projections.iam.setup_done`+ + ` FROM zitadel.projections.iam`), + sql.ErrConnDone, + ), + err: func(err error) (error, bool) { + if !errors.Is(err, sql.ErrConnDone) { + return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false + } + return nil, true + }, + }, + object: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err) + }) + } +} diff --git a/internal/query/languages.go b/internal/query/languages.go new file mode 100644 index 0000000000..1ead8dc31b --- /dev/null +++ b/internal/query/languages.go @@ -0,0 +1,21 @@ +package query + +import ( + "context" + + "github.com/caos/logging" + "github.com/caos/zitadel/internal/i18n" + "golang.org/x/text/language" +) + +func (q *Queries) Languages(ctx context.Context) ([]language.Tag, error) { + if len(q.supportedLangs) == 0 { + langs, err := i18n.SupportedLanguages(q.LoginDir) + if err != nil { + logging.Log("ADMIN-tiMWs").WithError(err).Debug("unable to parse language") + return nil, err + } + q.supportedLangs = langs + } + return q.supportedLangs, nil +} diff --git a/internal/query/query.go b/internal/query/query.go index 04531ed0af..23fb6f2511 100644 --- a/internal/query/query.go +++ b/internal/query/query.go @@ -10,7 +10,6 @@ import ( sd "github.com/caos/zitadel/internal/config/systemdefaults" "github.com/caos/zitadel/internal/config/types" "github.com/caos/zitadel/internal/eventstore" - iam_model "github.com/caos/zitadel/internal/iam/model" "github.com/caos/zitadel/internal/query/projection" "github.com/caos/zitadel/internal/repository/action" iam_repo "github.com/caos/zitadel/internal/repository/iam" @@ -19,7 +18,6 @@ import ( "github.com/caos/zitadel/internal/repository/project" usr_repo "github.com/caos/zitadel/internal/repository/user" "github.com/caos/zitadel/internal/repository/usergrant" - "github.com/caos/zitadel/internal/telemetry/tracing" "github.com/rakyll/statik/fs" "golang.org/x/text/language" ) @@ -35,6 +33,7 @@ type Queries struct { mutex sync.Mutex LoginTranslationFileContents map[string][]byte NotificationTranslationFileContents map[string][]byte + supportedLangs []language.Tag } type Config struct { @@ -78,25 +77,3 @@ func StartQueries(ctx context.Context, es *eventstore.Eventstore, projections pr return repo, nil } - -func (r *Queries) IAMByID(ctx context.Context, id string) (_ *iam_model.IAM, err error) { - readModel, err := r.iamByID(ctx, id) - if err != nil { - return nil, err - } - - return readModelToIAM(readModel), nil -} - -func (r *Queries) iamByID(ctx context.Context, id string) (_ *ReadModel, err error) { - ctx, span := tracing.NewSpan(ctx) - defer func() { span.EndWithError(err) }() - - readModel := NewReadModel(id) - err = r.eventstore.FilterToQueryReducer(ctx, readModel) - if err != nil { - return nil, err - } - - return readModel, nil -} diff --git a/internal/ui/login/handler/custom_action.go b/internal/ui/login/handler/custom_action.go index 0d7b48743a..20c2241d5e 100644 --- a/internal/ui/login/handler/custom_action.go +++ b/internal/ui/login/handler/custom_action.go @@ -16,7 +16,7 @@ func (l *Login) customExternalUserMapping(ctx context.Context, user *domain.Exte resourceOwner = config.AggregateID } if resourceOwner == domain.IAMID { - iam, err := l.authRepo.GetIAM(ctx) + iam, err := l.query.IAMByID(ctx, domain.IAMID) if err != nil { return nil, err } diff --git a/internal/ui/login/handler/external_login_handler.go b/internal/ui/login/handler/external_login_handler.go index 0c25992e6d..f9338eebad 100644 --- a/internal/ui/login/handler/external_login_handler.go +++ b/internal/ui/login/handler/external_login_handler.go @@ -203,7 +203,7 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R if errors.IsNotFound(err) { err = nil } - iam, err := l.authRepo.GetIAM(r.Context()) + iam, err := l.query.IAMByID(r.Context(), domain.IAMID) if err != nil { l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return @@ -248,13 +248,13 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R l.renderNextStep(w, r, authReq) } -func (l *Login) renderExternalNotFoundOption(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, iam *iam_model.IAM, orgIAMPolicy *query.OrgIAMPolicy, human *domain.Human, externalIDP *domain.UserIDPLink, err error) { +func (l *Login) renderExternalNotFoundOption(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, iam *query.IAM, orgIAMPolicy *query.OrgIAMPolicy, human *domain.Human, externalIDP *domain.UserIDPLink, err error) { var errID, errMessage string if err != nil { errID, errMessage = l.getErrorMessage(r, err) } if orgIAMPolicy == nil { - iam, err = l.authRepo.GetIAM(r.Context()) + iam, err = l.query.IAMByID(r.Context(), domain.IAMID) if err != nil { l.renderError(w, r, authReq, err) return @@ -335,7 +335,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http } func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest) { - iam, err := l.authRepo.GetIAM(r.Context()) + iam, err := l.query.IAMByID(r.Context(), domain.IAMID) if err != nil { l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err) return diff --git a/internal/ui/login/handler/external_register_handler.go b/internal/ui/login/handler/external_register_handler.go index 9382d43db3..bd8f90f840 100644 --- a/internal/ui/login/handler/external_register_handler.go +++ b/internal/ui/login/handler/external_register_handler.go @@ -111,7 +111,7 @@ func (l *Login) handleExternalRegisterCallback(w http.ResponseWriter, r *http.Re } func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, idpConfig *iam_model.IDPConfigView, userAgentID string, tokens *oidc.Tokens) { - iam, err := l.authRepo.GetIAM(r.Context()) + iam, err := l.query.IAMByID(r.Context(), domain.IAMID) if err != nil { l.renderRegisterOption(w, r, authReq, err) return @@ -137,7 +137,7 @@ func (l *Login) handleExternalUserRegister(w http.ResponseWriter, r *http.Reques l.registerExternalUser(w, r, authReq, iam, user, externalIDP) } -func (l *Login) registerExternalUser(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, iam *iam_model.IAM, user *domain.Human, externalIDP *domain.UserIDPLink) { +func (l *Login) registerExternalUser(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, iam *query.IAM, user *domain.Human, externalIDP *domain.UserIDPLink) { resourceOwner := iam.GlobalOrgID memberRoles := []string{domain.RoleSelfManagementGlobal} @@ -194,7 +194,7 @@ func (l *Login) handleExternalRegisterCheck(w http.ResponseWriter, r *http.Reque return } - iam, err := l.authRepo.GetIAM(r.Context()) + iam, err := l.query.IAMByID(r.Context(), domain.IAMID) if err != nil { l.renderRegisterOption(w, r, authReq, err) return diff --git a/internal/ui/login/handler/register_handler.go b/internal/ui/login/handler/register_handler.go index 4e501504cb..580fffc570 100644 --- a/internal/ui/login/handler/register_handler.go +++ b/internal/ui/login/handler/register_handler.go @@ -61,7 +61,7 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) { l.renderRegister(w, r, authRequest, data, err) return } - iam, err := l.authRepo.GetIAM(r.Context()) + iam, err := l.query.IAMByID(r.Context(), domain.IAMID) if err != nil { l.renderRegister(w, r, authRequest, data, err) return @@ -115,7 +115,7 @@ func (l *Login) renderRegister(w http.ResponseWriter, r *http.Request, authReque } if resourceOwner == "" { - iam, err := l.authRepo.GetIAM(r.Context()) + iam, err := l.query.IAMByID(r.Context(), domain.IAMID) if err != nil { l.renderRegister(w, r, authRequest, formData, err) return