From dfcb96d6a3e3734f9cfa28c5541594cb5bed80e5 Mon Sep 17 00:00:00 2001 From: Fabi <38692350+fgerschwiler@users.noreply.github.com> Date: Fri, 22 Jan 2021 13:31:52 +0100 Subject: [PATCH] feat: user grants command side (#1191) * fix: user grant command side * fix: user grant command side * fix: user grant command side check permissions * fix: unique constraint on user grants * fix: add usergrant * fix: add usergrant * fix: add usergrant * fix: user grant remove * Update internal/v2/command/auth_checks.go Co-authored-by: Livio Amstutz * Update internal/v2/command/auth_checks.go Co-authored-by: Livio Amstutz * Update internal/v2/command/project.go Co-authored-by: Livio Amstutz * Update internal/v2/command/user_grant.go Co-authored-by: Livio Amstutz * fix: project events Co-authored-by: Livio Amstutz --- cmd/zitadel/main.go | 1 + internal/api/grpc/management/user_grant.go | 31 +- .../grpc/management/user_grant_converter.go | 54 +-- .../eventsourcing/eventstore/user_grant.go | 118 ------- internal/management/repository/user_grant.go | 9 - .../eventsourcing/eventstore_mock_test.go | 14 +- .../eventsourcing/eventstore_test.go | 72 ++-- .../model/project_grant_member_test.go | 24 +- .../eventsourcing/model/project_grant_test.go | 26 +- .../repository/eventsourcing/project_test.go | 24 +- .../view/model/project_grant_member_test.go | 12 +- .../view/model/project_grant_test.go | 8 +- internal/static/i18n/de.yaml | 2 + internal/static/i18n/en.yaml | 2 + .../eventsourcing/model/user_grant_test.go | 6 +- internal/v2/command/auth_checks.go | 31 ++ internal/v2/command/command.go | 4 + internal/v2/command/project.go | 11 + internal/v2/command/project_model.go | 6 - internal/v2/command/user_grant.go | 236 ++++++++++++++ internal/v2/command/user_grant_converter.go | 14 + internal/v2/command/user_grant_model.go | 74 +++++ internal/v2/domain/user_grant.go | 26 ++ internal/v2/repository/project/eventstore.go | 9 + internal/v2/repository/project/project.go | 4 +- internal/v2/repository/usergrant/aggregate.go | 14 + .../v2/repository/usergrant/eventstore.go | 15 + .../v2/repository/usergrant/user_grant.go | 307 ++++++++++++++++++ migrations/cockroach/V1.27__unique_tables.sql | 2 + pkg/grpc/management/proto/management.proto | 11 +- 30 files changed, 890 insertions(+), 277 deletions(-) create mode 100644 internal/v2/command/auth_checks.go create mode 100644 internal/v2/command/user_grant.go create mode 100644 internal/v2/command/user_grant_converter.go create mode 100644 internal/v2/command/user_grant_model.go create mode 100644 internal/v2/domain/user_grant.go create mode 100644 internal/v2/repository/project/eventstore.go create mode 100644 internal/v2/repository/usergrant/aggregate.go create mode 100644 internal/v2/repository/usergrant/eventstore.go create mode 100644 internal/v2/repository/usergrant/user_grant.go diff --git a/cmd/zitadel/main.go b/cmd/zitadel/main.go index b3da9d8022..96b5e22653 100644 --- a/cmd/zitadel/main.go +++ b/cmd/zitadel/main.go @@ -97,6 +97,7 @@ func startZitadel(configPaths []string) { logging.Log("MAIN-FaF2r").OnError(err).Fatal("cannot read config") ctx := context.Background() + //TODO: new eventstore config for command sie es, err := es_int.Start(conf.Admin.Eventstore) if err != nil { return diff --git a/internal/api/grpc/management/user_grant.go b/internal/api/grpc/management/user_grant.go index 31ebf22bdf..29d14d936d 100644 --- a/internal/api/grpc/management/user_grant.go +++ b/internal/api/grpc/management/user_grant.go @@ -2,7 +2,6 @@ package management import ( "context" - "github.com/golang/protobuf/ptypes/empty" "github.com/caos/zitadel/internal/api/authz" @@ -28,42 +27,36 @@ func (s *Server) UserGrantByID(ctx context.Context, request *management.UserGran } func (s *Server) CreateUserGrant(ctx context.Context, in *management.UserGrantCreate) (*management.UserGrant, error) { - user, err := s.usergrant.AddUserGrant(ctx, userGrantCreateToModel(in)) + user, err := s.command.AddUserGrant(ctx, userGrantCreateToDomain(in), authz.GetCtxData(ctx).OrgID) if err != nil { return nil, err } - return usergrantFromModel(user), nil + return userGrantFromDomain(user), nil } func (s *Server) UpdateUserGrant(ctx context.Context, in *management.UserGrantUpdate) (*management.UserGrant, error) { - user, err := s.usergrant.ChangeUserGrant(ctx, userGrantUpdateToModel(in)) + user, err := s.command.ChangeUserGrant(ctx, userGrantUpdateToDomain(in), authz.GetCtxData(ctx).OrgID) if err != nil { return nil, err } - return usergrantFromModel(user), nil + return userGrantFromDomain(user), nil } -func (s *Server) DeactivateUserGrant(ctx context.Context, in *management.UserGrantID) (*management.UserGrant, error) { - user, err := s.usergrant.DeactivateUserGrant(ctx, in.Id) - if err != nil { - return nil, err - } - return usergrantFromModel(user), nil +func (s *Server) DeactivateUserGrant(ctx context.Context, in *management.UserGrantID) (*empty.Empty, error) { + err := s.command.DeactivateUserGrant(ctx, in.Id, authz.GetCtxData(ctx).OrgID) + return &empty.Empty{}, err } -func (s *Server) ReactivateUserGrant(ctx context.Context, in *management.UserGrantID) (*management.UserGrant, error) { - user, err := s.usergrant.ReactivateUserGrant(ctx, in.Id) - if err != nil { - return nil, err - } - return usergrantFromModel(user), nil +func (s *Server) ReactivateUserGrant(ctx context.Context, in *management.UserGrantID) (*empty.Empty, error) { + err := s.command.ReactivateUserGrant(ctx, in.Id, authz.GetCtxData(ctx).OrgID) + return &empty.Empty{}, err } func (s *Server) RemoveUserGrant(ctx context.Context, in *management.UserGrantID) (*empty.Empty, error) { - err := s.usergrant.RemoveUserGrant(ctx, in.Id) + err := s.command.RemoveUserGrant(ctx, in.Id, authz.GetCtxData(ctx).OrgID) return &empty.Empty{}, err } func (s *Server) BulkRemoveUserGrant(ctx context.Context, in *management.UserGrantRemoveBulk) (*empty.Empty, error) { - err := s.usergrant.BulkRemoveUserGrant(ctx, userGrantRemoveBulkToModel(in)...) + err := s.command.BulkRemoveUserGrant(ctx, userGrantRemoveBulkToModel(in), authz.GetCtxData(ctx).OrgID) return &empty.Empty{}, err } diff --git a/internal/api/grpc/management/user_grant_converter.go b/internal/api/grpc/management/user_grant_converter.go index 576e2a27f2..6273d97243 100644 --- a/internal/api/grpc/management/user_grant_converter.go +++ b/internal/api/grpc/management/user_grant_converter.go @@ -2,44 +2,39 @@ package management import ( "github.com/caos/logging" + "github.com/caos/zitadel/internal/v2/domain" "github.com/golang/protobuf/ptypes" + "google.golang.org/protobuf/types/known/timestamppb" "github.com/caos/zitadel/internal/eventstore/models" grant_model "github.com/caos/zitadel/internal/usergrant/model" "github.com/caos/zitadel/pkg/grpc/management" ) -func usergrantFromModel(grant *grant_model.UserGrant) *management.UserGrant { - creationDate, err := ptypes.TimestampProto(grant.CreationDate) - logging.Log("GRPC-ki9ds").OnError(err).Debug("unable to parse timestamp") - - changeDate, err := ptypes.TimestampProto(grant.ChangeDate) - logging.Log("GRPC-sl9ew").OnError(err).Debug("unable to parse timestamp") - +func userGrantFromDomain(grant *domain.UserGrant) *management.UserGrant { return &management.UserGrant{ - Id: grant.AggregateID, - UserId: grant.UserID, - State: usergrantStateFromModel(grant.State), - CreationDate: creationDate, - ChangeDate: changeDate, - Sequence: grant.Sequence, - ProjectId: grant.ProjectID, - RoleKeys: grant.RoleKeys, + Id: grant.AggregateID, + UserId: grant.UserID, + State: usergrantStateFromDomain(grant.State), + ChangeDate: timestamppb.New(grant.ChangeDate), + Sequence: grant.Sequence, + ProjectId: grant.ProjectID, + RoleKeys: grant.RoleKeys, } } -func userGrantCreateToModel(u *management.UserGrantCreate) *grant_model.UserGrant { - return &grant_model.UserGrant{ - ObjectRoot: models.ObjectRoot{AggregateID: u.UserId}, - UserID: u.UserId, - ProjectID: u.ProjectId, - RoleKeys: u.RoleKeys, - GrantID: u.GrantId, +func userGrantCreateToDomain(u *management.UserGrantCreate) *domain.UserGrant { + return &domain.UserGrant{ + ObjectRoot: models.ObjectRoot{AggregateID: u.UserId}, + UserID: u.UserId, + ProjectID: u.ProjectId, + RoleKeys: u.RoleKeys, + ProjectGrantID: u.GrantId, } } -func userGrantUpdateToModel(u *management.UserGrantUpdate) *grant_model.UserGrant { - return &grant_model.UserGrant{ +func userGrantUpdateToDomain(u *management.UserGrantUpdate) *domain.UserGrant { + return &domain.UserGrant{ ObjectRoot: models.ObjectRoot{AggregateID: u.Id}, RoleKeys: u.RoleKeys, } @@ -171,3 +166,14 @@ func usergrantStateFromModel(state grant_model.UserGrantState) management.UserGr return management.UserGrantState_USERGRANTSTATE_UNSPECIFIED } } + +func usergrantStateFromDomain(state domain.UserGrantState) management.UserGrantState { + switch state { + case domain.UserGrantStateActive: + return management.UserGrantState_USERGRANTSTATE_ACTIVE + case domain.UserGrantStateInactive: + return management.UserGrantState_USERGRANTSTATE_INACTIVE + default: + return management.UserGrantState_USERGRANTSTATE_UNSPECIFIED + } +} diff --git a/internal/management/repository/eventsourcing/eventstore/user_grant.go b/internal/management/repository/eventsourcing/eventstore/user_grant.go index d2f4f337e9..bf49bebe3c 100644 --- a/internal/management/repository/eventsourcing/eventstore/user_grant.go +++ b/internal/management/repository/eventsourcing/eventstore/user_grant.go @@ -5,7 +5,6 @@ import ( "github.com/caos/logging" "github.com/caos/zitadel/internal/api/authz" - caos_errors "github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/management/repository/eventsourcing/view" global_model "github.com/caos/zitadel/internal/model" grant_model "github.com/caos/zitadel/internal/usergrant/model" @@ -28,92 +27,6 @@ func (repo *UserGrantRepo) UserGrantByID(ctx context.Context, grantID string) (* return model.UserGrantToModel(grant), nil } -func (repo *UserGrantRepo) AddUserGrant(ctx context.Context, grant *grant_model.UserGrant) (*grant_model.UserGrant, error) { - err := checkExplicitPermission(ctx, grant.GrantID, grant.ProjectID) - if err != nil { - return nil, err - } - return repo.UserGrantEvents.AddUserGrant(ctx, grant) -} - -func (repo *UserGrantRepo) ChangeUserGrant(ctx context.Context, grant *grant_model.UserGrant) (*grant_model.UserGrant, error) { - err := checkExplicitPermission(ctx, grant.GrantID, grant.ProjectID) - if err != nil { - return nil, err - } - return repo.UserGrantEvents.ChangeUserGrant(ctx, grant) -} - -func (repo *UserGrantRepo) DeactivateUserGrant(ctx context.Context, grantID string) (*grant_model.UserGrant, error) { - grant, err := repo.UserGrantByID(ctx, grantID) - if err != nil { - return nil, err - } - err = checkExplicitPermission(ctx, grant.GrantID, grant.ProjectID) - if err != nil { - return nil, err - } - return repo.UserGrantEvents.DeactivateUserGrant(ctx, grantID) -} - -func (repo *UserGrantRepo) ReactivateUserGrant(ctx context.Context, grantID string) (*grant_model.UserGrant, error) { - grant, err := repo.UserGrantByID(ctx, grantID) - if err != nil { - return nil, err - } - err = checkExplicitPermission(ctx, grant.GrantID, grant.ProjectID) - if err != nil { - return nil, err - } - return repo.UserGrantEvents.ReactivateUserGrant(ctx, grantID) -} - -func (repo *UserGrantRepo) RemoveUserGrant(ctx context.Context, grantID string) error { - grant, err := repo.UserGrantByID(ctx, grantID) - if err != nil { - return err - } - err = checkExplicitPermission(ctx, grant.GrantID, grant.ProjectID) - if err != nil { - return err - } - return repo.UserGrantEvents.RemoveUserGrant(ctx, grantID) -} - -func (repo *UserGrantRepo) BulkAddUserGrant(ctx context.Context, grants ...*grant_model.UserGrant) error { - for _, grant := range grants { - err := checkExplicitPermission(ctx, grant.GrantID, grant.ProjectID) - if err != nil { - return err - } - } - return repo.UserGrantEvents.AddUserGrants(ctx, grants...) -} - -func (repo *UserGrantRepo) BulkChangeUserGrant(ctx context.Context, grants ...*grant_model.UserGrant) error { - for _, grant := range grants { - err := checkExplicitPermission(ctx, grant.GrantID, grant.ProjectID) - if err != nil { - return err - } - } - return repo.UserGrantEvents.ChangeUserGrants(ctx, grants...) -} - -func (repo *UserGrantRepo) BulkRemoveUserGrant(ctx context.Context, grantIDs ...string) error { - for _, grantID := range grantIDs { - grant, err := repo.UserGrantByID(ctx, grantID) - if err != nil { - return err - } - err = checkExplicitPermission(ctx, grant.GrantID, grant.ProjectID) - if err != nil { - return err - } - } - return repo.UserGrantEvents.RemoveUserGrants(ctx, grantIDs...) -} - func (repo *UserGrantRepo) SearchUserGrants(ctx context.Context, request *grant_model.UserGrantSearchRequest) (*grant_model.UserGrantSearchResponse, error) { request.EnsureLimit(repo.SearchLimit) sequence, sequenceErr := repo.View.GetLatestUserGrantSequence("") @@ -189,34 +102,3 @@ func checkContainsPermID(ids []string, query *grant_model.UserGrantSearchQuery, } return nil } - -func checkExplicitPermission(ctx context.Context, grantID, projectID string) error { - permissions := authz.GetRequestPermissionsFromCtx(ctx) - if authz.HasGlobalPermission(permissions) { - return nil - } - ids := authz.GetAllPermissionCtxIDs(permissions) - containsID := false - if grantID != "" { - containsID = listContainsID(ids, grantID) - if containsID { - return nil - } - } - containsID = listContainsID(ids, projectID) - if !containsID { - return caos_errors.ThrowPermissionDenied(nil, "EVENT-Shu7e", "Errors.UserGrant.NoPermissionForProject") - } - return nil -} - -func listContainsID(ids []string, id string) bool { - containsID := false - for _, i := range ids { - if i == id { - containsID = true - break - } - } - return containsID -} diff --git a/internal/management/repository/user_grant.go b/internal/management/repository/user_grant.go index 3222d660b0..18b7b179d3 100644 --- a/internal/management/repository/user_grant.go +++ b/internal/management/repository/user_grant.go @@ -7,14 +7,5 @@ import ( type UserGrantRepository interface { UserGrantByID(ctx context.Context, grantID string) (*model.UserGrantView, error) - AddUserGrant(ctx context.Context, grant *model.UserGrant) (*model.UserGrant, error) - ChangeUserGrant(ctx context.Context, grant *model.UserGrant) (*model.UserGrant, error) - DeactivateUserGrant(ctx context.Context, grantID string) (*model.UserGrant, error) - ReactivateUserGrant(ctx context.Context, grantID string) (*model.UserGrant, error) - RemoveUserGrant(ctx context.Context, grantID string) error SearchUserGrants(ctx context.Context, request *model.UserGrantSearchRequest) (*model.UserGrantSearchResponse, error) - - BulkAddUserGrant(ctx context.Context, grant ...*model.UserGrant) error - BulkChangeUserGrant(ctx context.Context, grant ...*model.UserGrant) error - BulkRemoveUserGrant(ctx context.Context, grantIDs ...string) error } diff --git a/internal/project/repository/eventsourcing/eventstore_mock_test.go b/internal/project/repository/eventsourcing/eventstore_mock_test.go index df0f1aaa5a..8c8f36d08e 100644 --- a/internal/project/repository/eventsourcing/eventstore_mock_test.go +++ b/internal/project/repository/eventsourcing/eventstore_mock_test.go @@ -170,7 +170,7 @@ func GetMockManipulateProjectWithSAMLApp(ctrl *gomock.Controller) *ProjectEvents func GetMockManipulateProjectWithGrant(ctrl *gomock.Controller) *ProjectEventstore { data, _ := json.Marshal(model.Project{Name: "Name"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "GrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) + grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) events := []*es_models.Event{ &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data}, &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantAdded, Data: grantData}, @@ -186,7 +186,7 @@ func GetMockManipulateProjectWithGrantExistingRole(ctrl *gomock.Controller) *Pro data, _ := json.Marshal(model.Project{Name: "Name"}) roleData, _ := json.Marshal(model.ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}) roleData2, _ := json.Marshal(model.ProjectRole{Key: "KeyChanged", DisplayName: "DisplayName", Group: "Group"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "GrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) + grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) events := []*es_models.Event{ &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data}, &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectRoleAdded, Data: roleData}, @@ -202,8 +202,8 @@ func GetMockManipulateProjectWithGrantExistingRole(ctrl *gomock.Controller) *Pro func GetMockManipulateProjectWithGrantMember(ctrl *gomock.Controller) *ProjectEventstore { data, _ := json.Marshal(model.Project{Name: "Name"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "GrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) - memberData, _ := json.Marshal(model.ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"Role"}}) + grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}) + memberData, _ := json.Marshal(model.ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}) events := []*es_models.Event{ &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data}, &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectGrantAdded, Data: grantData}, @@ -254,7 +254,7 @@ func GetMockProjectAppsByIDsOK(ctrl *gomock.Controller) *ProjectEventstore { func GetMockProjectGrantByIDsOK(ctrl *gomock.Controller) *ProjectEventstore { projectData, _ := json.Marshal(model.Project{Name: "Name"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "GrantID", GrantedOrgID: "GrantID", RoleKeys: []string{"Key"}}) + grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "ProjectGrantID", RoleKeys: []string{"Key"}}) events := []*es_models.Event{ &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: projectData}, @@ -267,8 +267,8 @@ func GetMockProjectGrantByIDsOK(ctrl *gomock.Controller) *ProjectEventstore { func GetMockProjectGrantMemberByIDsOK(ctrl *gomock.Controller) *ProjectEventstore { projectData, _ := json.Marshal(model.Project{Name: "Name"}) - grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "GrantID", GrantedOrgID: "GrantID", RoleKeys: []string{"Key"}}) - memberData, _ := json.Marshal(model.ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"Role"}}) + grantData, _ := json.Marshal(model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "ProjectGrantID", RoleKeys: []string{"Key"}}) + memberData, _ := json.Marshal(model.ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}) events := []*es_models.Event{ &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: projectData}, diff --git a/internal/project/repository/eventsourcing/eventstore_test.go b/internal/project/repository/eventsourcing/eventstore_test.go index 6c80a03291..3448f911c9 100644 --- a/internal/project/repository/eventsourcing/eventstore_test.go +++ b/internal/project/repository/eventsourcing/eventstore_test.go @@ -1950,11 +1950,11 @@ func TestProjectGrantByID(t *testing.T) { name: "get grant", args: args{ es: GetMockProjectGrantByIDsOK(ctrl), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "GrantID"}, + grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID"}, }, res: res{ grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}, }, @@ -1964,7 +1964,7 @@ func TestProjectGrantByID(t *testing.T) { name: "no events for project", args: args{ es: GetMockProjectByIDNoEvents(ctrl), - grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "GrantID"}, + grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID"}, }, res: res{ wantErr: true, @@ -2024,14 +2024,14 @@ func TestAddProjectGrant(t *testing.T) { es: GetMockManipulateProjectWithRole(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}, }, }, res: res{ result: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}, }, @@ -2043,7 +2043,7 @@ func TestAddProjectGrant(t *testing.T) { es: GetMockManipulateProject(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ @@ -2057,7 +2057,7 @@ func TestAddProjectGrant(t *testing.T) { es: GetMockManipulateProjectWithGrant(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", }, }, @@ -2072,7 +2072,7 @@ func TestAddProjectGrant(t *testing.T) { es: GetMockManipulateProject(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}, }, @@ -2088,7 +2088,7 @@ func TestAddProjectGrant(t *testing.T) { es: GetMockManipulateProjectNoEvents(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}, }, @@ -2135,7 +2135,7 @@ func TestRemoveProjectGrant(t *testing.T) { es: GetMockManipulateProjectWithGrant(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, }, @@ -2157,7 +2157,7 @@ func TestRemoveProjectGrant(t *testing.T) { es: GetMockManipulateProject(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ @@ -2171,7 +2171,7 @@ func TestRemoveProjectGrant(t *testing.T) { es: GetMockManipulateProjectNoEvents(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ @@ -2217,12 +2217,12 @@ func TestDeactivateProjectGrant(t *testing.T) { es: GetMockManipulateProjectWithGrant(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ result: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", State: model.ProjectGrantStateInactive, }, }, @@ -2245,7 +2245,7 @@ func TestDeactivateProjectGrant(t *testing.T) { es: GetMockManipulateProject(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ @@ -2259,7 +2259,7 @@ func TestDeactivateProjectGrant(t *testing.T) { es: GetMockManipulateProjectNoEvents(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ @@ -2311,12 +2311,12 @@ func TestReactivateProjectGrant(t *testing.T) { es: GetMockManipulateProjectWithGrant(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ result: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", State: model.ProjectGrantStateActive, }, }, @@ -2339,7 +2339,7 @@ func TestReactivateProjectGrant(t *testing.T) { es: GetMockManipulateProject(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ @@ -2353,7 +2353,7 @@ func TestReactivateProjectGrant(t *testing.T) { es: GetMockManipulateProjectNoEvents(ctrl), ctx: authz.NewMockContext("orgID", "userID"), grant: &model.ProjectGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", }, }, res: res{ @@ -2402,17 +2402,17 @@ func TestProjectGrantMemberByIDs(t *testing.T) { name: "projectgrant member from events, ok", args: args{ es: GetMockProjectGrantMemberByIDsOK(ctrl), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "GrantID", UserID: "UserID"}, + member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID", UserID: "UserID"}, }, res: res{ - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "GrantID", UserID: "UserID", Roles: []string{"Role"}}, + member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}, }, }, { name: "no project events", args: args{ es: GetMockProjectByIDNoEvents(ctrl), - member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "GrantID", UserID: "UserID"}, + member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, GrantID: "ProjectGrantID", UserID: "UserID"}, }, res: res{ wantErr: true, @@ -2475,14 +2475,14 @@ func TestAddProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectWithGrantExistingRole(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}, }, }, res: res{ result: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}, }, @@ -2508,7 +2508,7 @@ func TestAddProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectNoEvents(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}, }, @@ -2524,7 +2524,7 @@ func TestAddProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectWithGrantMember(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}, }, @@ -2543,7 +2543,7 @@ func TestAddProjectGrantMember(t *testing.T) { t.Errorf("result has no id") } if !tt.res.wantErr && result.GrantID != tt.res.result.GrantID { - t.Errorf("got wrong result GrantID: expected: %v, actual: %v ", tt.res.result.GrantID, result.GrantID) + t.Errorf("got wrong result ProjectGrantID: expected: %v, actual: %v ", tt.res.result.GrantID, result.GrantID) } if tt.res.wantErr && !tt.res.errFunc(err) { t.Errorf("got wrong err: %v ", err) @@ -2575,14 +2575,14 @@ func TestChangeProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectWithGrantMember(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"RoleChanged"}, }, }, res: res{ result: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"RoleChanged"}, }, @@ -2608,7 +2608,7 @@ func TestChangeProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectNoEvents(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}, }, @@ -2624,7 +2624,7 @@ func TestChangeProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectWithGrant(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}, }, @@ -2643,7 +2643,7 @@ func TestChangeProjectGrantMember(t *testing.T) { t.Errorf("result has no id") } if !tt.res.wantErr && result.GrantID != tt.res.result.GrantID { - t.Errorf("got wrong result GrantID: expected: %v, actual: %v ", tt.res.result.GrantID, result.GrantID) + t.Errorf("got wrong result ProjectGrantID: expected: %v, actual: %v ", tt.res.result.GrantID, result.GrantID) } if tt.res.wantErr && !tt.res.errFunc(err) { t.Errorf("got wrong err: %v ", err) @@ -2674,7 +2674,7 @@ func TestRemoveProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectWithGrantMember(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"RoleChanged"}, }, @@ -2700,7 +2700,7 @@ func TestRemoveProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectNoEvents(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}, }, @@ -2716,7 +2716,7 @@ func TestRemoveProjectGrantMember(t *testing.T) { es: GetMockManipulateProjectWithGrant(ctrl), ctx: authz.NewMockContext("orgID", "userID"), member: &model.ProjectGrantMember{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID", Sequence: 1}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}, }, diff --git a/internal/project/repository/eventsourcing/model/project_grant_member_test.go b/internal/project/repository/eventsourcing/model/project_grant_member_test.go index 6bb6e92b7e..7bdf0d1ef4 100644 --- a/internal/project/repository/eventsourcing/model/project_grant_member_test.go +++ b/internal/project/repository/eventsourcing/model/project_grant_member_test.go @@ -21,17 +21,17 @@ func TestAppendAddGrantMemberEvent(t *testing.T) { name: "append add grant member", args: args{ project: &Project{Grants: []*ProjectGrant{ - &ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, - member: &ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"Role"}}, + &ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, + member: &ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}, event: &es_models.Event{}, }, result: &Project{ Grants: []*ProjectGrant{ &ProjectGrant{ - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}, - Members: []*ProjectGrantMember{&ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"Role"}}}}}, + Members: []*ProjectGrantMember{&ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}}}}, }, }, } @@ -69,21 +69,21 @@ func TestAppendChangeGrantMemberEvent(t *testing.T) { project: &Project{ Grants: []*ProjectGrant{ &ProjectGrant{ - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}, - Members: []*ProjectGrantMember{&ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"Role"}}}}}, + Members: []*ProjectGrantMember{&ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}}}}, }, - member: &ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"RoleChanged"}}, + member: &ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"RoleChanged"}}, event: &es_models.Event{}, }, result: &Project{ Grants: []*ProjectGrant{ &ProjectGrant{ - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}, - Members: []*ProjectGrantMember{&ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"RoleChanged"}}}}}, + Members: []*ProjectGrantMember{&ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"RoleChanged"}}}}}, }, }, } @@ -120,12 +120,12 @@ func TestAppendRemoveGrantMemberEvent(t *testing.T) { project: &Project{ Grants: []*ProjectGrant{ &ProjectGrant{ - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}, - Members: []*ProjectGrantMember{&ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"Role"}}}}}, + Members: []*ProjectGrantMember{&ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Role"}}}}}, }, - member: &ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: []string{"RoleChanged"}}, + member: &ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"RoleChanged"}}, event: &es_models.Event{}, }, }, diff --git a/internal/project/repository/eventsourcing/model/project_grant_test.go b/internal/project/repository/eventsourcing/model/project_grant_test.go index ed59a1075f..8b64b927f9 100644 --- a/internal/project/repository/eventsourcing/model/project_grant_test.go +++ b/internal/project/repository/eventsourcing/model/project_grant_test.go @@ -22,10 +22,10 @@ func TestAppendAddGrantEvent(t *testing.T) { name: "append add grant event", args: args{ project: &Project{}, - role: &ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}, + role: &ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}, event: &es_models.Event{}, }, - result: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, + result: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, }, } for _, tt := range tests { @@ -59,11 +59,11 @@ func TestAppendChangeGrantEvent(t *testing.T) { { name: "append change grant event", args: args{ - project: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, - grant: &ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"KeyChanged"}}, + project: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, + grant: &ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"KeyChanged"}}, event: &es_models.Event{}, }, - result: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"KeyChanged"}}}}, + result: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"KeyChanged"}}}}, }, } for _, tt := range tests { @@ -97,8 +97,8 @@ func TestAppendRemoveGrantEvent(t *testing.T) { { name: "append remove role event", args: args{ - project: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, - grant: &ProjectGrant{GrantID: "GrantID"}, + project: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, + grant: &ProjectGrant{GrantID: "ProjectGrantID"}, event: &es_models.Event{}, }, result: &Project{Grants: []*ProjectGrant{}}, @@ -133,22 +133,22 @@ func TestAppendGrantStateEvent(t *testing.T) { { name: "append deactivate grant event", args: args{ - project: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, - grant: &ProjectGrantID{GrantID: "GrantID"}, + project: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, + grant: &ProjectGrantID{GrantID: "ProjectGrantID"}, event: &es_models.Event{}, state: model.ProjectGrantStateInactive, }, - result: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}, State: int32(model.ProjectGrantStateInactive)}}}, + result: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}, State: int32(model.ProjectGrantStateInactive)}}}, }, { name: "append reactivate grant event", args: args{ - project: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, - grant: &ProjectGrantID{GrantID: "GrantID"}, + project: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}}}}, + grant: &ProjectGrantID{GrantID: "ProjectGrantID"}, event: &es_models.Event{}, state: model.ProjectGrantStateActive, }, - result: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}, State: int32(model.ProjectGrantStateActive)}}}, + result: &Project{Grants: []*ProjectGrant{&ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"Key"}, State: int32(model.ProjectGrantStateActive)}}}, }, } for _, tt := range tests { diff --git a/internal/project/repository/eventsourcing/project_test.go b/internal/project/repository/eventsourcing/project_test.go index 67bd4f915d..8d6ebf2b1e 100644 --- a/internal/project/repository/eventsourcing/project_test.go +++ b/internal/project/repository/eventsourcing/project_test.go @@ -908,10 +908,10 @@ func TestProjectRoleRemovedAggregate(t *testing.T) { ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive), - Grants: []*model.ProjectGrant{{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"ROLE"}}}, + Grants: []*model.ProjectGrant{{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{"ROLE"}}}, }, newProject: &model.ProjectRole{ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"}, Key: "Key"}, - grants: []*model.ProjectGrant{{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "GrantID", GrantedOrgID: "OrgID", RoleKeys: []string{}}}, + grants: []*model.ProjectGrant{{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "ProjectGrantID", GrantedOrgID: "OrgID", RoleKeys: []string{}}}, aggCreator: models.NewAggregateCreator("Test"), }, res: res{ @@ -1611,7 +1611,7 @@ func TestProjectGrantAddedAggregate(t *testing.T) { args: args{ ctx: authz.NewMockContext("orgID", "userID"), existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectGrant{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "GrantID", GrantedOrgID: "OrgID"}, + newProject: &model.ProjectGrant{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "ProjectGrantID", GrantedOrgID: "OrgID"}, aggCreator: models.NewAggregateCreator("Test"), }, res: res{ @@ -1696,11 +1696,11 @@ func TestProjectGrantChangedAggregate(t *testing.T) { Name: "ProjectName", State: int32(proj_model.ProjectStateActive), Grants: []*model.ProjectGrant{ - {GrantID: "GrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}, + {GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"Key"}}, }}, newProject: &model.ProjectGrant{ ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"KeyChanged"}, }, @@ -1787,11 +1787,11 @@ func TestProjectGrantRemovedAggregate(t *testing.T) { Name: "ProjectName", State: int32(proj_model.ProjectStateActive), Grants: []*model.ProjectGrant{ - {GrantID: "GrantID", GrantedOrgID: "GrantedOrgID"}, + {GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID"}, }}, newProject: &model.ProjectGrant{ ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"KeyChanged"}, }, @@ -1878,11 +1878,11 @@ func TestProjectGrantDeactivatedAggregate(t *testing.T) { Name: "ProjectName", State: int32(proj_model.ProjectStateActive), Grants: []*model.ProjectGrant{ - {GrantID: "GrantID", GrantedOrgID: "GrantedOrgID"}, + {GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID"}, }}, newProject: &model.ProjectGrant{ ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"KeyChanged"}, }, @@ -1969,11 +1969,11 @@ func TestProjectGrantReactivatedAggregate(t *testing.T) { Name: "ProjectName", State: int32(proj_model.ProjectStateInactive), Grants: []*model.ProjectGrant{ - {GrantID: "GrantID", GrantedOrgID: "GrantedOrgID"}, + {GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID"}, }}, newProject: &model.ProjectGrant{ ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, - GrantID: "GrantID", + GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: []string{"KeyChanged"}, }, @@ -2056,7 +2056,7 @@ func TestProjectGrantMemberAddedAggregate(t *testing.T) { args: args{ ctx: authz.NewMockContext("orgID", "userID"), existingProject: &model.Project{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, Name: "ProjectName", State: int32(proj_model.ProjectStateActive)}, - newProject: &model.ProjectGrantMember{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "GrantID", UserID: "UserID", Roles: []string{"Roles"}}, + newProject: &model.ProjectGrantMember{ObjectRoot: models.ObjectRoot{AggregateID: "ID"}, GrantID: "ProjectGrantID", UserID: "UserID", Roles: []string{"Roles"}}, aggCreator: models.NewAggregateCreator("Test"), }, res: res{ diff --git a/internal/project/repository/view/model/project_grant_member_test.go b/internal/project/repository/view/model/project_grant_member_test.go index 229a9ba7fc..2710e2f149 100644 --- a/internal/project/repository/view/model/project_grant_member_test.go +++ b/internal/project/repository/view/model/project_grant_member_test.go @@ -27,18 +27,18 @@ func TestGrantedProjectMemberAppendEvent(t *testing.T) { { name: "append added member event", args: args{ - event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantMemberAdded, ResourceOwner: "OrgID", Data: mockProjectGrantMemberData(&es_model.ProjectGrantMember{GrantID: "GrantID", UserID: "UserID", Roles: pq.StringArray{"Role"}})}, + event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantMemberAdded, ResourceOwner: "OrgID", Data: mockProjectGrantMemberData(&es_model.ProjectGrantMember{GrantID: "ProjectGrantID", UserID: "UserID", Roles: pq.StringArray{"Role"}})}, member: &ProjectGrantMemberView{}, }, - result: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "GrantID", Roles: pq.StringArray{"Role"}}, + result: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: pq.StringArray{"Role"}}, }, { name: "append changed member event", args: args{ - event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantMemberAdded, ResourceOwner: "OrgID", Data: mockProjectGrantMemberData(&es_model.ProjectGrantMember{GrantID: "GrantID", Roles: pq.StringArray{"RoleChanged"}})}, - member: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "GrantID", Roles: pq.StringArray{"Role"}}, + event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantMemberAdded, ResourceOwner: "OrgID", Data: mockProjectGrantMemberData(&es_model.ProjectGrantMember{GrantID: "ProjectGrantID", Roles: pq.StringArray{"RoleChanged"}})}, + member: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: pq.StringArray{"Role"}}, }, - result: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "GrantID", Roles: pq.StringArray{"RoleChanged"}}, + result: &ProjectGrantMemberView{ProjectID: "AggregateID", UserID: "UserID", GrantID: "ProjectGrantID", Roles: pq.StringArray{"RoleChanged"}}, }, } for _, tt := range tests { @@ -51,7 +51,7 @@ func TestGrantedProjectMemberAppendEvent(t *testing.T) { t.Errorf("got wrong result userID: expected: %v, actual: %v ", tt.result.UserID, tt.args.member.UserID) } if tt.args.member.GrantID != tt.result.GrantID { - t.Errorf("got wrong result GrantID: expected: %v, actual: %v ", tt.result.GrantID, tt.args.member.GrantID) + t.Errorf("got wrong result ProjectGrantID: expected: %v, actual: %v ", tt.result.GrantID, tt.args.member.GrantID) } if !reflect.DeepEqual(tt.args.member.Roles, tt.result.Roles) { t.Errorf("got wrong result Roles: expected: %v, actual: %v ", tt.result.Roles, tt.args.member.Roles) diff --git a/internal/project/repository/view/model/project_grant_test.go b/internal/project/repository/view/model/project_grant_test.go index 70e91c1e8e..98e0f1c6ca 100644 --- a/internal/project/repository/view/model/project_grant_test.go +++ b/internal/project/repository/view/model/project_grant_test.go @@ -33,7 +33,7 @@ func TestProjectGrantAppendEvent(t *testing.T) { { name: "append added project grant event", args: args{ - event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantAdded, ResourceOwner: "OrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "GrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: pq.StringArray{"Role"}})}, + event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantAdded, ResourceOwner: "OrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID", GrantedOrgID: "GrantedOrgID", RoleKeys: pq.StringArray{"Role"}})}, project: &ProjectGrantView{}, }, result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "OrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"Role"}}, @@ -41,7 +41,7 @@ func TestProjectGrantAppendEvent(t *testing.T) { { name: "append change project grant event", args: args{ - event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantChanged, ResourceOwner: "OrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "GrantID", RoleKeys: pq.StringArray{"RoleChanged"}})}, + event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantChanged, ResourceOwner: "OrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID", RoleKeys: pq.StringArray{"RoleChanged"}})}, project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "OrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"Role"}}, }, result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "OrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"RoleChanged"}}, @@ -49,7 +49,7 @@ func TestProjectGrantAppendEvent(t *testing.T) { { name: "append deactivate project grant event", args: args{ - event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantDeactivated, ResourceOwner: "OrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "GrantID"})}, + event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantDeactivated, ResourceOwner: "OrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID"})}, project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "OrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"Role"}}, }, result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "OrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateInactive), GrantedRoleKeys: pq.StringArray{"Role"}}, @@ -57,7 +57,7 @@ func TestProjectGrantAppendEvent(t *testing.T) { { name: "append reactivate project grant event", args: args{ - event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantReactivated, ResourceOwner: "OrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "GrantID"})}, + event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: es_model.ProjectGrantReactivated, ResourceOwner: "OrgID", Data: mockProjectGrantData(&es_model.ProjectGrant{GrantID: "ProjectGrantID"})}, project: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "OrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateInactive), GrantedRoleKeys: pq.StringArray{"Role"}}, }, result: &ProjectGrantView{ProjectID: "AggregateID", ResourceOwner: "OrgID", OrgID: "GrantedOrgID", State: int32(model.ProjectStateActive), GrantedRoleKeys: pq.StringArray{"Role"}}, diff --git a/internal/static/i18n/de.yaml b/internal/static/i18n/de.yaml index 552414f556..216f018ade 100644 --- a/internal/static/i18n/de.yaml +++ b/internal/static/i18n/de.yaml @@ -248,8 +248,10 @@ Errors: Policy: AlreadyExists: Policy existiert bereits UserGrant: + AlreadyExists: Benutzer Berechtigung existiert bereits NotFound: Benutzer Berechtigung konnte nicht gefunden werden Invalid: Benutzer Berechtigung ist ungültig + NotChanged: Benutzer Berechtigung wurde nicht verändert IDMissing: Id fehlt NotActive: Benutzer Berechtigung ist nicht aktiv NotInactive: Benutzer Berechtigung ist nicht deaktiviert diff --git a/internal/static/i18n/en.yaml b/internal/static/i18n/en.yaml index c04914945a..ed91ff7b45 100644 --- a/internal/static/i18n/en.yaml +++ b/internal/static/i18n/en.yaml @@ -245,8 +245,10 @@ Errors: Policy: AlreadyExists: Policy already exists UserGrant: + AlreadyExists: User grant already exists NotFound: User grant not found Invalid: User grant is invalid + NotChanged: User grant has not been changed IDMissing: Id missing NotActive: User grant is not active NotInactive: User grant is not deactivated diff --git a/internal/usergrant/repository/eventsourcing/model/user_grant_test.go b/internal/usergrant/repository/eventsourcing/model/user_grant_test.go index 46415b5d90..580cf8ffdb 100644 --- a/internal/usergrant/repository/eventsourcing/model/user_grant_test.go +++ b/internal/usergrant/repository/eventsourcing/model/user_grant_test.go @@ -23,7 +23,7 @@ func TestAppendGrantStateEvent(t *testing.T) { name: "append deactivate grant event", args: args{ grant: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}}, - grantID: &UserGrantID{GrantID: "GrantID"}, + grantID: &UserGrantID{GrantID: "ProjectGrantID"}, event: &es_models.Event{}, state: model.UserGrantStateInactive, }, @@ -33,7 +33,7 @@ func TestAppendGrantStateEvent(t *testing.T) { name: "append reactivate grant event", args: args{ grant: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}}, - grantID: &UserGrantID{GrantID: "GrantID"}, + grantID: &UserGrantID{GrantID: "ProjectGrantID"}, event: &es_models.Event{}, state: model.UserGrantStateActive, }, @@ -43,7 +43,7 @@ func TestAppendGrantStateEvent(t *testing.T) { name: "append remove grant event", args: args{ grant: &UserGrant{ObjectRoot: es_models.ObjectRoot{AggregateID: "ID"}, UserID: "UserID", ProjectID: "ProjectID", RoleKeys: []string{"Key"}}, - grantID: &UserGrantID{GrantID: "GrantID"}, + grantID: &UserGrantID{GrantID: "ProjectGrantID"}, event: &es_models.Event{}, state: model.UserGrantStateRemoved, }, diff --git a/internal/v2/command/auth_checks.go b/internal/v2/command/auth_checks.go new file mode 100644 index 0000000000..bdf0540511 --- /dev/null +++ b/internal/v2/command/auth_checks.go @@ -0,0 +1,31 @@ +package command + +import ( + "context" + "github.com/caos/zitadel/internal/api/authz" + caos_errors "github.com/caos/zitadel/internal/errors" +) + +func checkExplicitProjectPermission(ctx context.Context, grantID, projectID string) error { + permissions := authz.GetRequestPermissionsFromCtx(ctx) + if authz.HasGlobalPermission(permissions) { + return nil + } + ids := authz.GetAllPermissionCtxIDs(permissions) + if grantID != "" && listContainsID(ids, grantID) { + return nil + } + if listContainsID(ids, projectID) { + return nil + } + return caos_errors.ThrowPermissionDenied(nil, "EVENT-Shu7e", "Errors.UserGrant.NoPermissionForProject") +} + +func listContainsID(ids []string, id string) bool { + for _, i := range ids { + if i == id { + return true + } + } + return false +} diff --git a/internal/v2/command/command.go b/internal/v2/command/command.go index 53ef01010b..160a19875c 100644 --- a/internal/v2/command/command.go +++ b/internal/v2/command/command.go @@ -12,7 +12,9 @@ import ( "github.com/caos/zitadel/internal/telemetry/tracing" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" "github.com/caos/zitadel/internal/v2/repository/org" + proj_repo "github.com/caos/zitadel/internal/v2/repository/project" usr_repo "github.com/caos/zitadel/internal/v2/repository/user" + usr_grant_repo "github.com/caos/zitadel/internal/v2/repository/usergrant" webauthn_helper "github.com/caos/zitadel/internal/webauthn" ) @@ -53,6 +55,8 @@ func StartCommandSide(config *Config) (repo *CommandSide, err error) { iam_repo.RegisterEventMappers(repo.eventstore) org.RegisterEventMappers(repo.eventstore) usr_repo.RegisterEventMappers(repo.eventstore) + usr_grant_repo.RegisterEventMappers(repo.eventstore) + proj_repo.RegisterEventMappers(repo.eventstore) //TODO: simplify!!!! repo.idpConfigSecretCrypto, err = crypto.NewAESCrypto(config.SystemDefaults.IDPConfigVerificationKey) diff --git a/internal/v2/command/project.go b/internal/v2/command/project.go index d4cb2c6d18..f2740ff1d1 100644 --- a/internal/v2/command/project.go +++ b/internal/v2/command/project.go @@ -54,6 +54,17 @@ func (r *CommandSide) getProjectByID(ctx context.Context, projectID, resourceOwn return projectWriteModelToProject(projectWriteModel), nil } +func (r *CommandSide) checkProjectExists(ctx context.Context, projectID, resourceOwner string) error { + projectWriteModel, err := r.getProjectWriteModelByID(ctx, projectID, resourceOwner) + if err != nil { + return err + } + if projectWriteModel.State == domain.ProjectStateUnspecified || projectWriteModel.State == domain.ProjectStateRemoved { + return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.Project.NotFound") + } + return nil +} + func (r *CommandSide) getProjectWriteModelByID(ctx context.Context, projectID, resourceOwner string) (*ProjectWriteModel, error) { projectWriteModel := NewProjectWriteModel(projectID, resourceOwner) err := r.eventstore.FilterToQueryReducer(ctx, projectWriteModel) diff --git a/internal/v2/command/project_model.go b/internal/v2/command/project_model.go index 67e4232665..b1261c5de2 100644 --- a/internal/v2/command/project_model.go +++ b/internal/v2/command/project_model.go @@ -26,12 +26,6 @@ func NewProjectWriteModel(projectID string, resourceOwner string) *ProjectWriteM func (wm *ProjectWriteModel) AppendEvents(events ...eventstore.EventReader) { wm.WriteModel.AppendEvents(events...) - for _, event := range events { - switch e := event.(type) { - case *project.ProjectAddedEvent: - wm.WriteModel.AppendEvents(e) - } - } } func (wm *ProjectWriteModel) Reduce() error { diff --git a/internal/v2/command/user_grant.go b/internal/v2/command/user_grant.go new file mode 100644 index 0000000000..8b50291c84 --- /dev/null +++ b/internal/v2/command/user_grant.go @@ -0,0 +1,236 @@ +package command + +import ( + "context" + caos_errs "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/telemetry/tracing" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/usergrant" + "reflect" +) + +func (r *CommandSide) AddUserGrant(ctx context.Context, usergrant *domain.UserGrant, resourceOwner string) (_ *domain.UserGrant, err error) { + userGrantAgg, addedUserGrant, err := r.addUserGrant(ctx, usergrant, resourceOwner) + if err != nil { + return nil, err + } + err = r.eventstore.PushAggregate(ctx, addedUserGrant, userGrantAgg) + if err != nil { + return nil, err + } + + return userGrantWriteModelToUserGrant(addedUserGrant), nil +} + +func (r *CommandSide) addUserGrant(ctx context.Context, userGrant *domain.UserGrant, resourceOwner string) (_ *usergrant.Aggregate, _ *UserGrantWriteModel, err error) { + err = checkExplicitProjectPermission(ctx, userGrant.ProjectGrantID, userGrant.ProjectID) + if err != nil { + return nil, nil, err + } + if !userGrant.IsValid() { + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.UserGrant.Invalid") + } + exists, err := r.checkUserExists(ctx, userGrant.UserID, resourceOwner) + if err != nil { + return nil, nil, err + } + if !exists { + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.User.NotFound") + } + err = r.checkProjectExists(ctx, userGrant.ProjectID, resourceOwner) + if err != nil { + return nil, nil, err + } + userGrant.AggregateID, err = r.idGenerator.Next() + if err != nil { + return nil, nil, err + } + addedUserGrant := NewUserGrantWriteModel(userGrant.AggregateID, resourceOwner) + userGrantAgg := UserGrantAggregateFromWriteModel(&addedUserGrant.WriteModel) + + userGrantAgg.PushEvents( + usergrant.NewUserGrantAddedEvent( + ctx, + resourceOwner, + userGrant.UserID, + userGrant.ProjectID, + userGrant.ProjectGrantID, + userGrant.RoleKeys, + ), + ) + return userGrantAgg, addedUserGrant, nil +} + +func (r *CommandSide) ChangeUserGrant(ctx context.Context, userGrant *domain.UserGrant, resourceOwner string) (_ *domain.UserGrant, err error) { + userGrantAgg, addedUserGrant, err := r.changeUserGrant(ctx, userGrant, resourceOwner, false) + if err != nil { + return nil, err + } + err = r.eventstore.PushAggregate(ctx, addedUserGrant, userGrantAgg) + if err != nil { + return nil, err + } + + return userGrantWriteModelToUserGrant(addedUserGrant), nil +} + +func (r *CommandSide) changeUserGrant(ctx context.Context, userGrant *domain.UserGrant, resourceOwner string, cascade bool) (_ *usergrant.Aggregate, _ *UserGrantWriteModel, err error) { + err = checkExplicitProjectPermission(ctx, userGrant.ProjectGrantID, userGrant.ProjectID) + if err != nil { + return nil, nil, err + } + if userGrant.IsValid() { + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M0sd", "Errors.UserGrant.Invalid") + } + + existingUserGrant, err := r.userGrantWriteModelByID(ctx, userGrant.AggregateID, userGrant.ResourceOwner) + if err != nil { + return nil, nil, err + } + if existingUserGrant.State == domain.UserGrantStateUnspecified || existingUserGrant.State == domain.UserGrantStateRemoved { + return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.UserGrant.NotFound") + } + if reflect.DeepEqual(existingUserGrant.RoleKeys, userGrant.RoleKeys) { + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Rs8fy", "Errors.UserGrant.NotChanged") + } + + changedUserGrant := NewUserGrantWriteModel(userGrant.AggregateID, resourceOwner) + userGrantAgg := UserGrantAggregateFromWriteModel(&changedUserGrant.WriteModel) + + if !cascade { + userGrantAgg.PushEvents( + usergrant.NewUserGrantChangedEvent(ctx, userGrant.RoleKeys), + ) + } else { + userGrantAgg.PushEvents( + usergrant.NewUserGrantCascadeChangedEvent(ctx, userGrant.RoleKeys), + ) + } + + return userGrantAgg, changedUserGrant, nil +} + +func (r *CommandSide) DeactivateUserGrant(ctx context.Context, grantID, resourceOwner string) (err error) { + if grantID == "" || resourceOwner == "" { + return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-M0dsf", "Errors.UserGrant.IDMissing") + } + + existingUserGrant, err := r.userGrantWriteModelByID(ctx, grantID, resourceOwner) + if err != nil { + return err + } + err = checkExplicitProjectPermission(ctx, existingUserGrant.ProjectGrantID, existingUserGrant.ProjectID) + if err != nil { + return err + } + if existingUserGrant.State == domain.UserGrantStateUnspecified || existingUserGrant.State == domain.UserGrantStateRemoved { + return caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.UserGrant.NotFound") + } + if existingUserGrant.State != domain.UserGrantStateActive { + return caos_errs.ThrowNotFound(nil, "COMMAND-1S9gx", "Errors.UserGrant.NotActive") + } + + deactivateUserGrant := NewUserGrantWriteModel(grantID, resourceOwner) + userGrantAgg := UserGrantAggregateFromWriteModel(&deactivateUserGrant.WriteModel) + userGrantAgg.PushEvents( + usergrant.NewUserGrantDeactivatedEvent(ctx), + ) + + return r.eventstore.PushAggregate(ctx, deactivateUserGrant, userGrantAgg) +} + +func (r *CommandSide) ReactivateUserGrant(ctx context.Context, grantID, resourceOwner string) (err error) { + if grantID == "" || resourceOwner == "" { + return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-Qxy8v", "Errors.UserGrant.IDMissing") + } + + existingUserGrant, err := r.userGrantWriteModelByID(ctx, grantID, resourceOwner) + if err != nil { + return err + } + err = checkExplicitProjectPermission(ctx, existingUserGrant.ProjectGrantID, existingUserGrant.ProjectID) + if err != nil { + return err + } + if existingUserGrant.State == domain.UserGrantStateUnspecified || existingUserGrant.State == domain.UserGrantStateRemoved { + return caos_errs.ThrowNotFound(nil, "COMMAND-Lp0gs", "Errors.UserGrant.NotFound") + } + if existingUserGrant.State != domain.UserGrantStateInactive { + return caos_errs.ThrowNotFound(nil, "COMMAND-1ML0v", "Errors.UserGrant.NotInactive") + } + + deactivateUserGrant := NewUserGrantWriteModel(grantID, resourceOwner) + userGrantAgg := UserGrantAggregateFromWriteModel(&deactivateUserGrant.WriteModel) + userGrantAgg.PushEvents( + usergrant.NewUserGrantReactivatedEvent(ctx), + ) + + return r.eventstore.PushAggregate(ctx, deactivateUserGrant, userGrantAgg) +} + +func (r *CommandSide) RemoveUserGrant(ctx context.Context, grantID, resourceOwner string) (err error) { + userGrantAgg, removeUserGrant, err := r.removeUserGrant(ctx, grantID, resourceOwner, false) + if err != nil { + return nil + } + + return r.eventstore.PushAggregate(ctx, removeUserGrant, userGrantAgg) +} + +func (r *CommandSide) BulkRemoveUserGrant(ctx context.Context, grantIDs []string, resourceOwner string) (err error) { + aggregates := make([]eventstore.Aggregater, len(grantIDs)) + for i, grantID := range grantIDs { + userGrantAgg, _, err := r.removeUserGrant(ctx, grantID, resourceOwner, false) + if err != nil { + return nil + } + aggregates[i] = userGrantAgg + } + _, err = r.eventstore.PushAggregates(ctx, aggregates...) + return err +} + +func (r *CommandSide) removeUserGrant(ctx context.Context, grantID, resourceOwner string, cascade bool) (_ *usergrant.Aggregate, _ *UserGrantWriteModel, err error) { + if grantID == "" || resourceOwner == "" { + return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-J9sc5", "Errors.UserGrant.IDMissing") + } + + existingUserGrant, err := r.userGrantWriteModelByID(ctx, grantID, resourceOwner) + if err != nil { + return nil, nil, err + } + err = checkExplicitProjectPermission(ctx, existingUserGrant.ProjectGrantID, existingUserGrant.ProjectID) + if err != nil { + return nil, nil, err + } + if existingUserGrant.State == domain.UserGrantStateUnspecified || existingUserGrant.State == domain.UserGrantStateRemoved { + return nil, nil, caos_errs.ThrowNotFound(nil, "COMMAND-1My0t", "Errors.UserGrant.NotFound") + } + + //TODO: Remove Uniqueness + removeUserGrant := NewUserGrantWriteModel(grantID, resourceOwner) + userGrantAgg := UserGrantAggregateFromWriteModel(&removeUserGrant.WriteModel) + if !cascade { + userGrantAgg.PushEvents( + usergrant.NewUserGrantRemovedEvent(ctx, existingUserGrant.ResourceOwner, existingUserGrant.UserID, existingUserGrant.ProjectID), + ) + } else { + userGrantAgg.PushEvents( + usergrant.NewUserGrantCascadeRemovedEvent(ctx, existingUserGrant.ResourceOwner, existingUserGrant.UserID, existingUserGrant.ProjectID), + ) + } + + return userGrantAgg, removeUserGrant, nil +} +func (r *CommandSide) userGrantWriteModelByID(ctx context.Context, userGrantID, resourceOwner string) (writeModel *UserGrantWriteModel, err error) { + ctx, span := tracing.NewSpan(ctx) + defer func() { span.EndWithError(err) }() + + writeModel = NewUserGrantWriteModel(userGrantID, resourceOwner) + err = r.eventstore.FilterToQueryReducer(ctx, writeModel) + if err != nil { + return nil, err + } + return writeModel, nil +} diff --git a/internal/v2/command/user_grant_converter.go b/internal/v2/command/user_grant_converter.go new file mode 100644 index 0000000000..da7e09e574 --- /dev/null +++ b/internal/v2/command/user_grant_converter.go @@ -0,0 +1,14 @@ +package command + +import "github.com/caos/zitadel/internal/v2/domain" + +func userGrantWriteModelToUserGrant(writeModel *UserGrantWriteModel) *domain.UserGrant { + return &domain.UserGrant{ + ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel), + UserID: writeModel.UserID, + ProjectID: writeModel.ProjectID, + ProjectGrantID: writeModel.ProjectGrantID, + RoleKeys: writeModel.RoleKeys, + State: writeModel.State, + } +} diff --git a/internal/v2/command/user_grant_model.go b/internal/v2/command/user_grant_model.go new file mode 100644 index 0000000000..94d9b90fda --- /dev/null +++ b/internal/v2/command/user_grant_model.go @@ -0,0 +1,74 @@ +package command + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/v2/domain" + "github.com/caos/zitadel/internal/v2/repository/usergrant" +) + +type UserGrantWriteModel struct { + eventstore.WriteModel + + UserID string + ProjectID string + ProjectGrantID string + RoleKeys []string + State domain.UserGrantState +} + +func NewUserGrantWriteModel(userGrantID string, resourceOwner string) *UserGrantWriteModel { + return &UserGrantWriteModel{ + WriteModel: eventstore.WriteModel{ + AggregateID: userGrantID, + ResourceOwner: resourceOwner, + }, + } +} + +func (wm *UserGrantWriteModel) AppendEvents(events ...eventstore.EventReader) { + wm.WriteModel.AppendEvents(events...) +} + +func (wm *UserGrantWriteModel) Reduce() error { + for _, event := range wm.Events { + switch e := event.(type) { + case *usergrant.UserGrantAddedEvent: + wm.UserID = e.UserID + wm.ProjectID = e.ProjectID + wm.ProjectGrantID = e.ProjectGrantID + wm.RoleKeys = e.RoleKeys + wm.State = domain.UserGrantStateActive + case *usergrant.UserGrantChangedEvent: + wm.RoleKeys = e.RoleKeys + case *usergrant.UserGrantCascadeChangedEvent: + wm.RoleKeys = e.RoleKeys + case *usergrant.UserGrantDeactivatedEvent: + if wm.State == domain.UserGrantStateRemoved { + continue + } + wm.State = domain.UserGrantStateInactive + case *usergrant.UserGrantReactivatedEvent: + if wm.State == domain.UserGrantStateRemoved { + continue + } + wm.State = domain.UserGrantStateActive + case *usergrant.UserGrantRemovedEvent: + wm.State = domain.UserGrantStateRemoved + case *usergrant.UserGrantCascadeRemovedEvent: + wm.State = domain.UserGrantStateRemoved + } + } + return nil +} + +func (wm *UserGrantWriteModel) Query() *eventstore.SearchQueryBuilder { + return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, usergrant.AggregateType). + AggregateIDs(wm.AggregateID). + ResourceOwner(wm.ResourceOwner) +} + +func UserGrantAggregateFromWriteModel(wm *eventstore.WriteModel) *usergrant.Aggregate { + return &usergrant.Aggregate{ + Aggregate: *eventstore.AggregateFromWriteModel(wm, usergrant.AggregateType, usergrant.AggregateVersion), + } +} diff --git a/internal/v2/domain/user_grant.go b/internal/v2/domain/user_grant.go new file mode 100644 index 0000000000..0545ab18a1 --- /dev/null +++ b/internal/v2/domain/user_grant.go @@ -0,0 +1,26 @@ +package domain + +import es_models "github.com/caos/zitadel/internal/eventstore/models" + +type UserGrant struct { + es_models.ObjectRoot + + State UserGrantState + UserID string + ProjectID string + ProjectGrantID string + RoleKeys []string +} + +type UserGrantState int32 + +const ( + UserGrantStateUnspecified UserGrantState = iota + UserGrantStateActive + UserGrantStateInactive + UserGrantStateRemoved +) + +func (u *UserGrant) IsValid() bool { + return u.ProjectID != "" && u.UserID != "" +} diff --git a/internal/v2/repository/project/eventstore.go b/internal/v2/repository/project/eventstore.go new file mode 100644 index 0000000000..722788f47e --- /dev/null +++ b/internal/v2/repository/project/eventstore.go @@ -0,0 +1,9 @@ +package project + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" +) + +func RegisterEventMappers(es *eventstore.Eventstore) { + es.RegisterFilterEventMapper(ProjectAddedType, ProjectAddedEventMapper) +} diff --git a/internal/v2/repository/project/project.go b/internal/v2/repository/project/project.go index 875d5571ae..2bf1fb6aa5 100644 --- a/internal/v2/repository/project/project.go +++ b/internal/v2/repository/project/project.go @@ -12,7 +12,7 @@ import ( const ( uniqueProjectnameTable = "project_names" projectEventTypePrefix = eventstore.EventType("project.") - ProjectAdded = projectEventTypePrefix + "added" + ProjectAddedType = projectEventTypePrefix + "added" ProjectChanged = projectEventTypePrefix + "changed" ProjectDeactivated = projectEventTypePrefix + "deactivated" ProjectReactivated = projectEventTypePrefix + "reactivated" @@ -52,7 +52,7 @@ func NewProjectAddedEvent(ctx context.Context, name, resourceOwner string) *Proj return &ProjectAddedEvent{ BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( ctx, - ProjectAdded, + ProjectAddedType, resourceOwner, ), Name: name, diff --git a/internal/v2/repository/usergrant/aggregate.go b/internal/v2/repository/usergrant/aggregate.go new file mode 100644 index 0000000000..93a89e4224 --- /dev/null +++ b/internal/v2/repository/usergrant/aggregate.go @@ -0,0 +1,14 @@ +package usergrant + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" +) + +const ( + AggregateType = "usergrant" + AggregateVersion = "v1" +) + +type Aggregate struct { + eventstore.Aggregate +} diff --git a/internal/v2/repository/usergrant/eventstore.go b/internal/v2/repository/usergrant/eventstore.go new file mode 100644 index 0000000000..c79222aa01 --- /dev/null +++ b/internal/v2/repository/usergrant/eventstore.go @@ -0,0 +1,15 @@ +package usergrant + +import ( + "github.com/caos/zitadel/internal/eventstore/v2" +) + +func RegisterEventMappers(es *eventstore.Eventstore) { + es.RegisterFilterEventMapper(UserGrantAddedType, UserGrantAddedEventMapper). + RegisterFilterEventMapper(UserGrantChangedType, UserGrantChangedEventMapper). + RegisterFilterEventMapper(UserGrantCascadeChangedType, UserGrantCascadeChangedEventMapper). + RegisterFilterEventMapper(UserGrantRemovedType, UserGrantRemovedEventMapper). + RegisterFilterEventMapper(UserGrantCascadeRemovedType, UserGrantCascadeRemovedEventMapper). + RegisterFilterEventMapper(UserGrantDeactivatedType, UserGrantDeactivatedEventMapper). + RegisterFilterEventMapper(UserGrantReactivatedType, UserGrantReactivatedEventMapper) +} diff --git a/internal/v2/repository/usergrant/user_grant.go b/internal/v2/repository/usergrant/user_grant.go new file mode 100644 index 0000000000..ea41e98a67 --- /dev/null +++ b/internal/v2/repository/usergrant/user_grant.go @@ -0,0 +1,307 @@ +package usergrant + +import ( + "context" + "encoding/json" + "fmt" + "github.com/caos/zitadel/internal/errors" + "github.com/caos/zitadel/internal/eventstore/v2" + "github.com/caos/zitadel/internal/eventstore/v2/repository" +) + +const ( + uniqueUserGrant = "user_grant" + userGrantEventTypePrefix = eventstore.EventType("user.grant") + UserGrantAddedType = userGrantEventTypePrefix + "added" + UserGrantChangedType = userGrantEventTypePrefix + "changed" + UserGrantCascadeChangedType = userGrantEventTypePrefix + "cascade.changed" + UserGrantRemovedType = userGrantEventTypePrefix + "removed" + UserGrantCascadeRemovedType = userGrantEventTypePrefix + "cascade.removed" + UserGrantDeactivatedType = userGrantEventTypePrefix + "deactivated" + UserGrantReactivatedType = userGrantEventTypePrefix + "reactivated" +) + +func NewAddUserGrantUniqueConstraint(resourceOwner, userID, projectID string) *eventstore.EventUniqueConstraint { + return eventstore.NewAddEventUniqueConstraint( + uniqueUserGrant, + fmt.Sprintf("%s:%s:%s", resourceOwner, userID, projectID), + "Errors.UserGrant.AlreadyExists") +} + +func NewRemoveUserGrantUniqueConstraint(resourceOwner, userID, projectID string) *eventstore.EventUniqueConstraint { + return eventstore.NewRemoveEventUniqueConstraint( + uniqueUserGrant, + fmt.Sprintf("%s:%s:%s", resourceOwner, userID, projectID)) +} + +type UserGrantAddedEvent struct { + eventstore.BaseEvent `json:"-"` + + UserID string `json:"userId,omitempty"` + ProjectID string `json:"projectId,omitempty"` + ProjectGrantID string `json:"grantId,omitempty"` + RoleKeys []string `json:"roleKeys,omitempty"` +} + +func (e *UserGrantAddedEvent) Data() interface{} { + return e +} + +func (e *UserGrantAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return []*eventstore.EventUniqueConstraint{NewAddUserGrantUniqueConstraint(e.ResourceOwner(), e.UserID, e.ProjectID)} +} + +func NewUserGrantAddedEvent( + ctx context.Context, + resourceOwner, + userID, + projectID, + projectGrantID string, + roleKeys []string) *UserGrantAddedEvent { + return &UserGrantAddedEvent{ + BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + ctx, + UserGrantAddedType, + resourceOwner, + ), + UserID: userID, + ProjectID: projectID, + ProjectGrantID: projectGrantID, + RoleKeys: roleKeys, + } +} + +func UserGrantAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &UserGrantAddedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "UGRANT-2M9fs", "unable to unmarshal user grant") + } + + return e, nil +} + +type UserGrantChangedEvent struct { + eventstore.BaseEvent `json:"-"` + RoleKeys []string `json:"roleKeys,omitempty"` +} + +func (e *UserGrantChangedEvent) Data() interface{} { + return e +} + +func (e *UserGrantChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewUserGrantChangedEvent( + ctx context.Context, + roleKeys []string) *UserGrantChangedEvent { + return &UserGrantChangedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + UserGrantChangedType, + ), + RoleKeys: roleKeys, + } +} + +func UserGrantChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &UserGrantChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "UGRANT-4M0sd", "unable to unmarshal user grant") + } + + return e, nil +} + +type UserGrantCascadeChangedEvent struct { + eventstore.BaseEvent `json:"-"` + RoleKeys []string `json:"roleKeys,omitempty"` +} + +func (e *UserGrantCascadeChangedEvent) Data() interface{} { + return e +} + +func (e *UserGrantCascadeChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewUserGrantCascadeChangedEvent( + ctx context.Context, + roleKeys []string) *UserGrantCascadeChangedEvent { + return &UserGrantCascadeChangedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + UserGrantCascadeChangedType, + ), + RoleKeys: roleKeys, + } +} + +func UserGrantCascadeChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &UserGrantChangedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "UGRANT-Gs9df", "unable to unmarshal user grant") + } + + return e, nil +} + +type UserGrantRemovedEvent struct { + eventstore.BaseEvent `json:"-"` + userID string + projectID string +} + +func (e *UserGrantRemovedEvent) Data() interface{} { + return e +} + +func (e *UserGrantRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID)} +} + +func NewUserGrantRemovedEvent(ctx context.Context, resourceOwner, userID, projectID string) *UserGrantRemovedEvent { + return &UserGrantRemovedEvent{ + BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + ctx, + UserGrantRemovedType, + resourceOwner, + ), + userID: userID, + projectID: projectID, + } +} + +func UserGrantRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &UserGrantRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "UGRANT-M0sdf", "unable to unmarshal user grant") + } + + return e, nil +} + +type UserGrantCascadeRemovedEvent struct { + eventstore.BaseEvent `json:"-"` + userID string + projectID string +} + +func (e *UserGrantCascadeRemovedEvent) Data() interface{} { + return e +} + +func (e *UserGrantCascadeRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID)} +} + +func NewUserGrantCascadeRemovedEvent(ctx context.Context, resourceOwner, userID, projectID string) *UserGrantRemovedEvent { + return &UserGrantRemovedEvent{ + BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( + ctx, + UserGrantRemovedType, + resourceOwner, + ), + userID: userID, + projectID: projectID, + } +} + +func UserGrantCascadeRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &UserGrantRemovedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "UGRANT-E7urs", "unable to unmarshal user grant") + } + + return e, nil +} + +type UserGrantDeactivatedEvent struct { + eventstore.BaseEvent `json:"-"` +} + +func (e *UserGrantDeactivatedEvent) Data() interface{} { + return e +} + +func (e *UserGrantDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewUserGrantDeactivatedEvent(ctx context.Context) *UserGrantDeactivatedEvent { + return &UserGrantDeactivatedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + UserGrantDeactivatedType, + ), + } +} + +func UserGrantDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &UserGrantDeactivatedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "UGRANT-pL0ds", "unable to unmarshal user grant") + } + + return e, nil +} + +type UserGrantReactivatedEvent struct { + eventstore.BaseEvent `json:"-"` +} + +func (e *UserGrantReactivatedEvent) Data() interface{} { + return e +} + +func (e *UserGrantReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { + return nil +} + +func NewUserGrantReactivatedEvent(ctx context.Context) *UserGrantReactivatedEvent { + return &UserGrantReactivatedEvent{ + BaseEvent: *eventstore.NewBaseEventForPush( + ctx, + UserGrantReactivatedType, + ), + } +} + +func UserGrantReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { + e := &UserGrantReactivatedEvent{ + BaseEvent: *eventstore.BaseEventFromRepo(event), + } + + err := json.Unmarshal(event.Data, e) + if err != nil { + return nil, errors.ThrowInternal(err, "UGRANT-M0sdf", "unable to unmarshal user grant") + } + + return e, nil +} diff --git a/migrations/cockroach/V1.27__unique_tables.sql b/migrations/cockroach/V1.27__unique_tables.sql index 45a1b9d7f6..b232b6cf48 100644 --- a/migrations/cockroach/V1.27__unique_tables.sql +++ b/migrations/cockroach/V1.27__unique_tables.sql @@ -3,3 +3,5 @@ CREATE TABLE eventstore.unique_constraints ( unique_field TEXT, PRIMARY KEY (unique_type, unique_field) ); + +GRANT DELETE ON TABLE eventstore.unique_constraints to adminapi; \ No newline at end of file diff --git a/pkg/grpc/management/proto/management.proto b/pkg/grpc/management/proto/management.proto index 1b211ab8c5..da35048008 100644 --- a/pkg/grpc/management/proto/management.proto +++ b/pkg/grpc/management/proto/management.proto @@ -1189,7 +1189,7 @@ service ManagementService { }; } - rpc DeactivateUserGrant(UserGrantID) returns (UserGrant) { + rpc DeactivateUserGrant(UserGrantID) returns (google.protobuf.Empty) { option (google.api.http) = { put: "/users/{user_id}/grants/{id}/_deactivate" body: "*" @@ -1200,7 +1200,7 @@ service ManagementService { }; } - rpc ReactivateUserGrant(UserGrantID) returns (UserGrant) { + rpc ReactivateUserGrant(UserGrantID) returns (google.protobuf.Empty) { option (google.api.http) = { put: "/users/{user_id}/grants/{id}/_reactivate" body: "*" @@ -2833,10 +2833,9 @@ message UserGrant { string project_id = 4; repeated string role_keys = 5; UserGrantState state = 6; - google.protobuf.Timestamp creation_date = 7; - google.protobuf.Timestamp change_date = 8; - uint64 sequence = 9; - string grant_id = 10; + google.protobuf.Timestamp change_date = 7; + uint64 sequence = 8; + string grant_id = 9; } message UserGrantCreate {