From d7417b6ef68ab524d0b593315f5d30687f1e4e19 Mon Sep 17 00:00:00 2001 From: Livio Amstutz Date: Mon, 29 Nov 2021 18:38:11 +0100 Subject: [PATCH] fix: filter of users uniqueness (#2753) --- .../repository/eventsourcing/view/user.go | 4 -- internal/api/grpc/management/user.go | 10 ++++- .../repository/eventsourcing/view/user.go | 4 -- .../eventsourcing/eventstore/user.go | 4 +- .../repository/eventsourcing/view/user.go | 4 +- internal/management/repository/user.go | 2 +- internal/user/repository/view/user_view.go | 42 +++++++++++++++++-- 7 files changed, 53 insertions(+), 17 deletions(-) diff --git a/internal/admin/repository/eventsourcing/view/user.go b/internal/admin/repository/eventsourcing/view/user.go index 31fc70df5b..a0c9122793 100644 --- a/internal/admin/repository/eventsourcing/view/user.go +++ b/internal/admin/repository/eventsourcing/view/user.go @@ -33,10 +33,6 @@ func (v *View) UserIDsByDomain(domain string) ([]string, error) { return view.UserIDsByDomain(v.Db, userTable, domain) } -func (v *View) IsUserUnique(userName, email string) (bool, error) { - return view.IsUserUnique(v.Db, userTable, userName, email) -} - func (v *View) UserMFAs(userID string) ([]*usr_model.MultiFactor, error) { return view.UserMFAs(v.Db, userTable, userID) } diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go index 3ef8d3e612..d0c06a7315 100644 --- a/internal/api/grpc/management/user.go +++ b/internal/api/grpc/management/user.go @@ -71,7 +71,15 @@ func (s *Server) ListUserChanges(ctx context.Context, req *mgmt_pb.ListUserChang } func (s *Server) IsUserUnique(ctx context.Context, req *mgmt_pb.IsUserUniqueRequest) (*mgmt_pb.IsUserUniqueResponse, error) { - unique, err := s.user.IsUserUnique(ctx, req.UserName, req.Email) + orgID := authz.GetCtxData(ctx).OrgID + policy, err := s.query.OrgIAMPolicyByOrg(ctx, orgID) + if err != nil { + return nil, err + } + if !policy.UserLoginMustBeDomain { + orgID = "" + } + unique, err := s.user.IsUserUnique(ctx, req.UserName, req.Email, orgID) if err != nil { return nil, err } diff --git a/internal/auth/repository/eventsourcing/view/user.go b/internal/auth/repository/eventsourcing/view/user.go index 9b6ab25bd4..85b25ea232 100644 --- a/internal/auth/repository/eventsourcing/view/user.go +++ b/internal/auth/repository/eventsourcing/view/user.go @@ -45,10 +45,6 @@ func (v *View) GetGlobalUserByLoginName(email string) (*model.UserView, error) { return view.GetGlobalUserByLoginName(v.Db, userTable, email) } -func (v *View) IsUserUnique(userName, email string) (bool, error) { - return view.IsUserUnique(v.Db, userTable, userName, email) -} - func (v *View) UserMFAs(userID string) ([]*usr_model.MultiFactor, error) { return view.UserMFAs(v.Db, userTable, userID) } diff --git a/internal/management/repository/eventsourcing/eventstore/user.go b/internal/management/repository/eventsourcing/eventstore/user.go index bb2b16841a..68c335d632 100644 --- a/internal/management/repository/eventsourcing/eventstore/user.go +++ b/internal/management/repository/eventsourcing/eventstore/user.go @@ -151,8 +151,8 @@ func (repo *UserRepo) GetUserByLoginNameGlobal(ctx context.Context, loginName st return model.UserToModel(user, repo.PrefixAvatarURL), nil } -func (repo *UserRepo) IsUserUnique(ctx context.Context, userName, email string) (bool, error) { - return repo.View.IsUserUnique(userName, email) +func (repo *UserRepo) IsUserUnique(ctx context.Context, userName, email, orgID string) (bool, error) { + return repo.View.IsUserUnique(userName, email, orgID) } func (repo *UserRepo) GetMetadataByKey(ctx context.Context, userID, resourceOwner, key string) (*domain.Metadata, error) { diff --git a/internal/management/repository/eventsourcing/view/user.go b/internal/management/repository/eventsourcing/view/user.go index ab90d1200f..17fbf15535 100644 --- a/internal/management/repository/eventsourcing/view/user.go +++ b/internal/management/repository/eventsourcing/view/user.go @@ -37,8 +37,8 @@ func (v *View) UserIDsByDomain(domain string) ([]string, error) { return view.UserIDsByDomain(v.Db, userTable, domain) } -func (v *View) IsUserUnique(userName, email string) (bool, error) { - return view.IsUserUnique(v.Db, userTable, userName, email) +func (v *View) IsUserUnique(userName, email, orgID string) (bool, error) { + return view.IsUserUnique(v.Db, userTable, userName, email, orgID) } func (v *View) UserMFAs(userID string) ([]*usr_model.MultiFactor, error) { diff --git a/internal/management/repository/user.go b/internal/management/repository/user.go index b0e5ea22d7..31d3040322 100644 --- a/internal/management/repository/user.go +++ b/internal/management/repository/user.go @@ -16,7 +16,7 @@ type UserRepository interface { UserIDsByDomain(ctx context.Context, domain string) ([]string, error) GetUserByLoginNameGlobal(ctx context.Context, email string) (*model.UserView, error) - IsUserUnique(ctx context.Context, userName, email string) (bool, error) + IsUserUnique(ctx context.Context, userName, email, orgID string) (bool, error) GetMetadataByKey(ctx context.Context, userID, resourceOwner, key string) (*domain.Metadata, error) SearchMetadata(ctx context.Context, userID, resourceOwner string, req *domain.MetadataSearchRequest) (*domain.MetadataSearchResponse, error) diff --git a/internal/user/repository/view/user_view.go b/internal/user/repository/view/user_view.go index b863a6be8a..a060d21495 100644 --- a/internal/user/repository/view/user_view.go +++ b/internal/user/repository/view/user_view.go @@ -150,13 +150,13 @@ func GetGlobalUserByLoginName(db *gorm.DB, table, loginName string) (*model.User return user, err } -func IsUserUnique(db *gorm.DB, table, userName, email string) (bool, error) { +func IsUserUnique(db *gorm.DB, table, userName, email, orgID string) (bool, error) { user := new(model.UserView) emailUnique := email == "" userNameUnique := userName == "" if email != "" { - query := repository.PrepareGetByKey(table, model.UserSearchKey(usr_model.UserSearchKeyEmail), email) + query := repository.PrepareGetByQuery(table, uniqueEmailQuery(userName, orgID)...) err := query(db, user) if err != nil && !caos_errs.IsNotFound(err) { return false, err @@ -166,7 +166,7 @@ func IsUserUnique(db *gorm.DB, table, userName, email string) (bool, error) { } } if userName != "" { - query := repository.PrepareGetByKey(table, model.UserSearchKey(usr_model.UserSearchKeyUserName), userName) + query := repository.PrepareGetByQuery(table, uniqueUsernameQuery(userName, orgID)...) err := query(db, user) if err != nil && !caos_errs.IsNotFound(err) { return false, err @@ -179,6 +179,42 @@ func IsUserUnique(db *gorm.DB, table, userName, email string) (bool, error) { return emailUnique && userNameUnique, nil } +func uniqueEmailQuery(email, orgID string) []repository.SearchQuery { + queries := []repository.SearchQuery{ + &model.UserSearchQuery{ + Key: usr_model.UserSearchKeyEmail, + Method: domain.SearchMethodEquals, + Value: email, + }, + } + if orgID == "" { + return queries + } + return append(queries, &model.UserSearchQuery{ + Key: usr_model.UserSearchKeyResourceOwner, + Method: domain.SearchMethodEquals, + Value: orgID, + }) + +} +func uniqueUsernameQuery(userName, orgID string) []repository.SearchQuery { + queries := []repository.SearchQuery{ + &model.UserSearchQuery{ + Key: usr_model.UserSearchKeyUserName, + Method: domain.SearchMethodEquals, + Value: userName, + }, + } + if orgID == "" { + return queries + } + return append(queries, &model.UserSearchQuery{ + Key: usr_model.UserSearchKeyResourceOwner, + Method: domain.SearchMethodEquals, + Value: orgID, + }) +} + func UserMFAs(db *gorm.DB, table, userID string) ([]*usr_model.MultiFactor, error) { user, err := UserByID(db, table, userID) if err != nil {