From 4d19652cd96be2882226f622223c7261b368f345 Mon Sep 17 00:00:00 2001 From: Fabi <38692350+fgerschwiler@users.noreply.github.com> Date: Wed, 7 Apr 2021 11:40:31 +0200 Subject: [PATCH] fix: list granted project roles (#1537) --- internal/api/grpc/management/project.go | 20 ++++++++++++ .../api/grpc/management/project_converter.go | 16 ++++++++++ .../eventsourcing/eventstore/project.go | 31 +++++++++++++++++++ internal/management/repository/project.go | 1 + internal/project/model/project_role_view.go | 4 +++ proto/zitadel/management.proto | 26 ++++++++++++++++ 6 files changed, 98 insertions(+) diff --git a/internal/api/grpc/management/project.go b/internal/api/grpc/management/project.go index 6935d67b07..50e9e89cc6 100644 --- a/internal/api/grpc/management/project.go +++ b/internal/api/grpc/management/project.go @@ -71,6 +71,26 @@ func (s *Server) ListGrantedProjects(ctx context.Context, req *mgmt_pb.ListGrant }, nil } +func (s *Server) ListGrantedProjectRoles(ctx context.Context, req *mgmt_pb.ListGrantedProjectRolesRequest) (*mgmt_pb.ListGrantedProjectRolesResponse, error) { + queries, err := ListGrantedProjectRolesRequestToModel(req) + if err != nil { + return nil, err + } + queries.AppendMyOrgQuery(authz.GetCtxData(ctx).OrgID) + roles, err := s.project.SearchProjectGrantRoles(ctx, req.ProjectId, req.GrantId, queries) + if err != nil { + return nil, err + } + return &mgmt_pb.ListGrantedProjectRolesResponse{ + Result: project_grpc.RolesToPb(roles.Result), + Details: object_grpc.ToListDetails( + roles.TotalResult, + roles.Sequence, + roles.Timestamp, + ), + }, nil +} + func (s *Server) ListProjectChanges(ctx context.Context, req *mgmt_pb.ListProjectChangesRequest) (*mgmt_pb.ListProjectChangesResponse, error) { sequence, limit, asc := change_grpc.ChangeQueryToModel(req.Query) features, err := s.features.GetOrgFeatures(ctx, authz.GetCtxData(ctx).OrgID) diff --git a/internal/api/grpc/management/project_converter.go b/internal/api/grpc/management/project_converter.go index 25cc34c470..703d151a15 100644 --- a/internal/api/grpc/management/project_converter.go +++ b/internal/api/grpc/management/project_converter.go @@ -111,6 +111,7 @@ func ListGrantedProjectsRequestToModel(req *mgmt_pb.ListGrantedProjectsRequest) Queries: queries, }, nil } + func ListProjectRolesRequestToModel(req *mgmt_pb.ListProjectRolesRequest) (*proj_model.ProjectRoleSearchRequest, error) { offset, limit, asc := object.ListQueryToModel(req.Query) queries, err := proj_grpc.RoleQueriesToModel(req.Queries) @@ -126,6 +127,21 @@ func ListProjectRolesRequestToModel(req *mgmt_pb.ListProjectRolesRequest) (*proj }, nil } +func ListGrantedProjectRolesRequestToModel(req *mgmt_pb.ListGrantedProjectRolesRequest) (*proj_model.ProjectRoleSearchRequest, error) { + offset, limit, asc := object.ListQueryToModel(req.Query) + queries, err := proj_grpc.RoleQueriesToModel(req.Queries) + if err != nil { + return nil, err + } + return &proj_model.ProjectRoleSearchRequest{ + Offset: offset, + Limit: limit, + Asc: asc, + //SortingColumn: //TODO: sorting + Queries: queries, + }, nil +} + func ListProjectMembersRequestToModel(req *mgmt_pb.ListProjectMembersRequest) (*proj_model.ProjectMemberSearchRequest, error) { offset, limit, asc := object.ListQueryToModel(req.Query) queries := member_grpc.MemberQueriesToProjectMember(req.Queries) diff --git a/internal/management/repository/eventsourcing/eventstore/project.go b/internal/management/repository/eventsourcing/eventstore/project.go index b624cf84f8..5878d17a3d 100644 --- a/internal/management/repository/eventsourcing/eventstore/project.go +++ b/internal/management/repository/eventsourcing/eventstore/project.go @@ -442,6 +442,37 @@ func (repo *ProjectRepo) ProjectGrantMemberByID(ctx context.Context, projectID, return model.ProjectGrantMemberToModel(member), nil } +func (repo *ProjectRepo) SearchProjectGrantRoles(ctx context.Context, projectID, grantID string, request *proj_model.ProjectRoleSearchRequest) (*proj_model.ProjectRoleSearchResponse, error) { + projectGrant, err := repo.ProjectGrantByID(ctx, grantID) + if err != nil { + return nil, err + } + err = request.EnsureLimit(repo.SearchLimit) + if err != nil { + return nil, err + } + request.AppendProjectQuery(projectID) + request.AppendRoleKeysQuery(projectGrant.GrantedRoleKeys) + sequence, sequenceErr := repo.View.GetLatestProjectRoleSequence() + logging.Log("EVENT-3M9fs").OnError(sequenceErr).Warn("could not read latest project role sequence") + roles, count, err := repo.View.SearchProjectRoles(request) + if err != nil { + return nil, err + } + + result := &proj_model.ProjectRoleSearchResponse{ + Offset: request.Offset, + Limit: request.Limit, + TotalResult: count, + Result: model.ProjectRolesToModel(roles), + } + if sequenceErr == nil { + result.Sequence = sequence.CurrentSequence + result.Timestamp = sequence.LastSuccessfulSpoolerRun + } + return result, nil +} + func (repo *ProjectRepo) SearchProjectGrantMembers(ctx context.Context, request *proj_model.ProjectGrantMemberSearchRequest) (*proj_model.ProjectGrantMemberSearchResponse, error) { err := request.EnsureLimit(repo.SearchLimit) if err != nil { diff --git a/internal/management/repository/project.go b/internal/management/repository/project.go index 7516195c47..155ae53636 100644 --- a/internal/management/repository/project.go +++ b/internal/management/repository/project.go @@ -34,6 +34,7 @@ type ProjectRepository interface { ProjectGrantByID(ctx context.Context, grantID string) (*model.ProjectGrantView, error) SearchProjectGrantMembers(ctx context.Context, request *model.ProjectGrantMemberSearchRequest) (*model.ProjectGrantMemberSearchResponse, error) + SearchProjectGrantRoles(ctx context.Context, projectID, grantID string, request *model.ProjectRoleSearchRequest) (*model.ProjectRoleSearchResponse, error) ProjectGrantMemberByID(ctx context.Context, projectID, userID string) (*model.ProjectGrantMemberView, error) GetProjectGrantMemberRoles() []string diff --git a/internal/project/model/project_role_view.go b/internal/project/model/project_role_view.go index 1294785c17..620d5bfaa0 100644 --- a/internal/project/model/project_role_view.go +++ b/internal/project/model/project_role_view.go @@ -60,6 +60,10 @@ func (r *ProjectRoleSearchRequest) AppendProjectQuery(projectID string) { r.Queries = append(r.Queries, &ProjectRoleSearchQuery{Key: ProjectRoleSearchKeyProjectID, Method: domain.SearchMethodEquals, Value: projectID}) } +func (r *ProjectRoleSearchRequest) AppendRoleKeysQuery(keys []string) { + r.Queries = append(r.Queries, &ProjectRoleSearchQuery{Key: ProjectRoleSearchKeyKey, Method: domain.SearchMethodIsOneOf, Value: keys}) +} + func (r *ProjectRoleSearchRequest) EnsureLimit(limit uint64) error { if r.Limit > limit { return caos_errors.ThrowInvalidArgument(nil, "SEARCH-92hNf", "Errors.Limit.ExceedsDefault") diff --git a/proto/zitadel/management.proto b/proto/zitadel/management.proto index a48cf26055..da0f4d8b56 100644 --- a/proto/zitadel/management.proto +++ b/proto/zitadel/management.proto @@ -741,6 +741,18 @@ service ManagementService { }; } + // returns all roles of a project grant + rpc ListGrantedProjectRoles(ListGrantedProjectRolesRequest) returns (ListGrantedProjectRolesResponse) { + option (google.api.http) = { + get: "/granted_projects/{project_id}/grants/{grant_id}/roles/_search" + }; + + option (zitadel.v1.auth_option) = { + permission: "project.role.read" + check_field_name: "GrantId" + }; + } + rpc ListProjectChanges(ListProjectChangesRequest) returns (ListProjectChangesResponse) { option (google.api.http) = { post: "/projects/{project_id}/changes/_search" @@ -2578,6 +2590,20 @@ message ListProjectRolesResponse { repeated zitadel.project.v1.Role result = 2; } +message ListGrantedProjectRolesRequest { + string project_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}]; + string grant_id = 2 [(validate.rules).string = {min_len: 1, max_len: 200}]; + //list limitations and ordering + zitadel.v1.ListQuery query = 3; + //criterias the client is looking for + repeated zitadel.project.v1.RoleQuery queries = 4; +} + +message ListGrantedProjectRolesResponse { + zitadel.v1.ListDetails details = 1; + repeated zitadel.project.v1.Role result = 2; +} + message ListProjectMembersRequest { string project_id = 1 [(validate.rules).string = {min_len: 1, max_len: 200}]; //list limitations and ordering