diff --git a/internal/api/grpc/management/user.go b/internal/api/grpc/management/user.go index fed9c42863..e6268d24b3 100644 --- a/internal/api/grpc/management/user.go +++ b/internal/api/grpc/management/user.go @@ -20,7 +20,7 @@ import ( ) func (s *Server) GetUserByID(ctx context.Context, req *mgmt_pb.GetUserByIDRequest) (*mgmt_pb.GetUserByIDResponse, error) { - user, err := s.user.UserByID(ctx, req.Id) + user, err := s.user.UserByIDAndResourceOwner(ctx, req.Id, authz.GetCtxData(ctx).OrgID) if err != nil { return nil, err } diff --git a/internal/management/repository/eventsourcing/eventstore/user.go b/internal/management/repository/eventsourcing/eventstore/user.go index 4a26830f6a..74e0609598 100644 --- a/internal/management/repository/eventsourcing/eventstore/user.go +++ b/internal/management/repository/eventsourcing/eventstore/user.go @@ -63,6 +63,35 @@ func (repo *UserRepo) UserByID(ctx context.Context, id string) (*usr_model.UserV return model.UserToModel(&userCopy, repo.PrefixAvatarURL), nil } +func (repo *UserRepo) UserByIDAndResourceOwner(ctx context.Context, id, resourceOwner string) (*usr_model.UserView, error) { + user, viewErr := repo.View.UserByIDAndResourceOwner(id, resourceOwner) + if viewErr != nil && !caos_errs.IsNotFound(viewErr) { + return nil, viewErr + } + if caos_errs.IsNotFound(viewErr) { + user = new(model.UserView) + } + + events, esErr := repo.getUserEvents(ctx, id, user.Sequence) + if caos_errs.IsNotFound(viewErr) && len(events) == 0 { + return nil, caos_errs.ThrowNotFound(nil, "EVENT-Lsoj7", "Errors.User.NotFound") + } + if esErr != nil { + logging.Log("EVENT-PSoc3").WithError(esErr).Debug("error retrieving new events") + return model.UserToModel(user, repo.PrefixAvatarURL), nil + } + userCopy := *user + for _, event := range events { + if err := userCopy.AppendEvent(event); err != nil { + return model.UserToModel(user, repo.PrefixAvatarURL), nil + } + } + if userCopy.State == int32(usr_model.UserStateDeleted) || userCopy.ResourceOwner != resourceOwner { + return nil, caos_errs.ThrowNotFound(nil, "EVENT-4Fm9s", "Errors.User.NotFound") + } + return model.UserToModel(&userCopy, repo.PrefixAvatarURL), nil +} + func (repo *UserRepo) SearchUsers(ctx context.Context, request *usr_model.UserSearchRequest, ensureLimit bool) (*usr_model.UserSearchResponse, error) { if ensureLimit { err := request.EnsureLimit(repo.SearchLimit) diff --git a/internal/management/repository/eventsourcing/view/user.go b/internal/management/repository/eventsourcing/view/user.go index ed10966d2f..ab90d1200f 100644 --- a/internal/management/repository/eventsourcing/view/user.go +++ b/internal/management/repository/eventsourcing/view/user.go @@ -17,6 +17,10 @@ func (v *View) UserByID(userID string) (*model.UserView, error) { return view.UserByID(v.Db, userTable, userID) } +func (v *View) UserByIDAndResourceOwner(userID, resourceOwner string) (*model.UserView, error) { + return view.UserByIDAndResourceOwner(v.Db, userTable, userID, resourceOwner) +} + func (v *View) SearchUsers(request *usr_model.UserSearchRequest) ([]*model.UserView, uint64, error) { return view.SearchUsers(v.Db, userTable, request) } diff --git a/internal/management/repository/user.go b/internal/management/repository/user.go index 23edab42c1..b0e5ea22d7 100644 --- a/internal/management/repository/user.go +++ b/internal/management/repository/user.go @@ -11,6 +11,7 @@ import ( type UserRepository interface { UserByID(ctx context.Context, id string) (*model.UserView, error) + UserByIDAndResourceOwner(ctx context.Context, id, resourceOwner string) (*model.UserView, error) SearchUsers(ctx context.Context, request *model.UserSearchRequest, ensureLimit bool) (*model.UserSearchResponse, error) UserIDsByDomain(ctx context.Context, domain string) ([]string, error) diff --git a/internal/user/repository/view/user_view.go b/internal/user/repository/view/user_view.go index cd8b52f091..d0ef803be1 100644 --- a/internal/user/repository/view/user_view.go +++ b/internal/user/repository/view/user_view.go @@ -22,6 +22,27 @@ func UserByID(db *gorm.DB, table, userID string) (*model.UserView, error) { return user, err } +func UserByIDAndResourceOwner(db *gorm.DB, table, userID, resourceOwner string) (*model.UserView, error) { + user := new(model.UserView) + userIDQuery := &model.UserSearchQuery{ + Key: usr_model.UserSearchKeyUserID, + Method: domain.SearchMethodListContains, + Value: userID, + } + resourceOwnerQuery := &model.UserSearchQuery{ + Key: usr_model.UserSearchKeyResourceOwner, + Method: domain.SearchMethodEquals, + Value: resourceOwner, + } + query := repository.PrepareGetByQuery(table, userIDQuery, resourceOwnerQuery) + err := query(db, user) + if caos_errs.IsNotFound(err) { + return nil, caos_errs.ThrowNotFound(nil, "VIEW-fb93Fs", "Errors.User.NotFound") + } + user.SetEmptyUserType() + return user, err +} + func UserByUserName(db *gorm.DB, table, userName string) (*model.UserView, error) { user := new(model.UserView) query := repository.PrepareGetByKey(table, model.UserSearchKey(usr_model.UserSearchKeyUserName), userName)