From 22fcf8a2baf9558f3585ab51f6b7f0b672d0fccd Mon Sep 17 00:00:00 2001 From: Louis Ruch Date: Thu, 18 Jan 2024 17:29:53 -0800 Subject: [PATCH] Projects do not have perm to attach/detach policy --- .../handlers/scopes/scope_service.go | 28 +++++++---- .../handlers/scopes/scope_service_test.go | 50 ++++++++++--------- 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/internal/daemon/controller/handlers/scopes/scope_service.go b/internal/daemon/controller/handlers/scopes/scope_service.go index 010d6b7e0..a55a7e2d5 100644 --- a/internal/daemon/controller/handlers/scopes/scope_service.go +++ b/internal/daemon/controller/handlers/scopes/scope_service.go @@ -335,13 +335,8 @@ func (s *Service) GetScope(ctx context.Context, req *pbs.GetScopeRequest) (*pbs. if outputFields.Has(globals.ScopeField) { outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } - act := IdActions - // Can't delete global so elide it - if p.GetPublicId() == scope.Global.String() { - act = action.Difference(act, action.NewActionSet(action.Delete)) - } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, p.GetPublicId(), act).Strings())) + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, p.GetPublicId(), idActionsById(p.GetPublicId())).Strings())) } if outputFields.Has(globals.AuthorizedCollectionActionsField) { collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, scopeCollectionTypeMapMap[p.Type], p.GetPublicId(), "") @@ -386,7 +381,7 @@ func (s *Service) CreateScope(ctx context.Context, req *pbs.CreateScopeRequest) outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, p.GetPublicId(), IdActions).Strings())) + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, p.GetPublicId(), idActionsById(p.GetPublicId())).Strings())) } if outputFields.Has(globals.AuthorizedCollectionActionsField) { collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, scopeCollectionTypeMapMap[p.Type], p.GetPublicId(), "") @@ -431,7 +426,7 @@ func (s *Service) UpdateScope(ctx context.Context, req *pbs.UpdateScopeRequest) outputOpts = append(outputOpts, handlers.WithScope(authResults.Scope)) } if outputFields.Has(globals.AuthorizedActionsField) { - outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, p.GetPublicId(), IdActions).Strings())) + outputOpts = append(outputOpts, handlers.WithAuthorizedActions(authResults.FetchActionSetForId(ctx, p.GetPublicId(), idActionsById(p.GetPublicId())).Strings())) } if outputFields.Has(globals.AuthorizedCollectionActionsField) { collectionActions, err := auth.CalculateAuthorizedCollectionActions(ctx, authResults, scopeCollectionTypeMapMap[p.Type], p.GetPublicId(), "") @@ -1129,7 +1124,7 @@ func newOutputOpts(ctx context.Context, item *iam.Scope, authResults auth.Verify ScopeId: item.GetParentId(), } - authorizedActions := authResults.FetchActionSetForId(ctx, item.GetPublicId(), IdActions, auth.WithResource(&res)).Strings() + authorizedActions := authResults.FetchActionSetForId(ctx, item.GetPublicId(), idActionsById(item.GetPublicId()), auth.WithResource(&res)).Strings() if len(authorizedActions) == 0 { return nil, true, nil } @@ -1153,3 +1148,18 @@ func newOutputOpts(ctx context.Context, item *iam.Scope, authResults auth.Verify return outputOpts, true, nil } + +func idActionsById(id string) action.ActionSet { + act := IdActions + switch { + case id == scope.Global.String(): + // Can't delete global so elide it + act = action.Difference(act, action.NewActionSet(action.Delete)) + + case strings.HasPrefix(id, fmt.Sprintf("%s_", scope.Project.Prefix())): + // Can't attach/detach storage policy to projects + act = action.Difference(act, action.NewActionSet(action.AttachStoragePolicy, action.DetachStoragePolicy)) + } + + return act +} diff --git a/internal/daemon/controller/handlers/scopes/scope_service_test.go b/internal/daemon/controller/handlers/scopes/scope_service_test.go index 46245ee90..f9cef4734 100644 --- a/internal/daemon/controller/handlers/scopes/scope_service_test.go +++ b/internal/daemon/controller/handlers/scopes/scope_service_test.go @@ -46,7 +46,11 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) -var testAuthorizedActions = []string{"no-op", "read", "update", "delete", "attach-storage-policy", "detach-storage-policy"} +var ( + testAuthorizedOrgActions = []string{"no-op", "read", "update", "delete", "attach-storage-policy", "detach-storage-policy"} + testAuthorizedPrjActions = []string{"no-op", "read", "update", "delete"} + testAuthorizedGlobalActions = []string{"no-op", "read", "update", "attach-storage-policy", "detach-storage-policy"} +) func createDefaultScopesRepoAndKms(t *testing.T) (*iam.Scope, *iam.Scope, func() (*iam.Repository, error), *kms.Kms) { t.Helper() @@ -265,7 +269,7 @@ func TestGet(t *testing.T) { UpdatedTime: org.UpdateTime.GetTimestamp(), Version: 2, Type: scope.Org.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedOrgActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, } @@ -279,7 +283,7 @@ func TestGet(t *testing.T) { UpdatedTime: proj.UpdateTime.GetTimestamp(), Version: 2, Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, } @@ -386,12 +390,12 @@ func TestList(t *testing.T) { oNoProjectsProto, err := scopes.ToProto(context.Background(), oNoProjects, handlers.WithOutputFields(outputFields)) require.NoError(t, err) oNoProjectsProto.Scope = globalScope - oNoProjectsProto.AuthorizedActions = testAuthorizedActions + oNoProjectsProto.AuthorizedActions = testAuthorizedOrgActions oNoProjectsProto.AuthorizedCollectionActions = orgAuthorizedCollectionActions oWithProjectsProto, err := scopes.ToProto(context.Background(), oWithProjects, handlers.WithOutputFields(outputFields)) require.NoError(t, err) oWithProjectsProto.Scope = globalScope - oWithProjectsProto.AuthorizedActions = testAuthorizedActions + oWithProjectsProto.AuthorizedActions = testAuthorizedOrgActions oWithProjectsProto.AuthorizedCollectionActions = orgAuthorizedCollectionActions initialOrgs = append(initialOrgs, oNoProjectsProto, oWithProjectsProto) @@ -500,7 +504,7 @@ func TestList(t *testing.T) { UpdatedTime: o.GetUpdateTime().GetTimestamp(), Version: 1, Type: scope.Org.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedOrgActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }) } @@ -524,7 +528,7 @@ func TestList(t *testing.T) { UpdatedTime: p.GetUpdateTime().GetTimestamp(), Version: 1, Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }) } @@ -717,7 +721,7 @@ func TestListPagination(t *testing.T) { UpdatedTime: p.GetUpdateTime().GetTimestamp(), Version: 1, Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: paginationAuthorizedCollectionActions, }) } @@ -860,7 +864,7 @@ func TestListPagination(t *testing.T) { UpdatedTime: p.GetUpdateTime().GetTimestamp(), Version: 1, Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: paginationAuthorizedCollectionActions, } // Add to the front of the slice since it's the most recently updated @@ -1115,7 +1119,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1139,7 +1143,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, Type: scope.Org.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedOrgActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }, }, @@ -1162,7 +1166,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1185,7 +1189,7 @@ func TestCreate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, Version: 1, Type: scope.Org.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedOrgActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }, }, @@ -1210,7 +1214,7 @@ func TestCreate(t *testing.T) { Name: &wrapperspb.StringValue{Value: "test org name with whitespace"}, // assert the whitespace is trimmed Version: 1, Type: scope.Org.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedOrgActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }, }, @@ -1496,7 +1500,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1523,7 +1527,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: org.GetCreateTime().GetTimestamp(), Type: scope.Org.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedOrgActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }, }, @@ -1550,7 +1554,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "new desc"}, CreatedTime: org.GetCreateTime().GetTimestamp(), Type: scope.Org.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedOrgActions, AuthorizedCollectionActions: orgAuthorizedCollectionActions, }, }, @@ -1576,7 +1580,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: global.GetCreateTime().GetTimestamp(), Type: scope.Global.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedGlobalActions, AuthorizedCollectionActions: globalAuthorizedCollectionActions, }, }, @@ -1602,7 +1606,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "desc"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1786,7 +1790,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "defaultProj"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1810,7 +1814,7 @@ func TestUpdate(t *testing.T) { Name: &wrappers.StringValue{Value: "defaultProj"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1836,7 +1840,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "defaultProj"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, }, @@ -1862,7 +1866,7 @@ func TestUpdate(t *testing.T) { Description: &wrapperspb.StringValue{Value: "notignored"}, CreatedTime: proj.GetCreateTime().GetTimestamp(), Type: scope.Project.String(), - AuthorizedActions: testAuthorizedActions, + AuthorizedActions: testAuthorizedPrjActions, AuthorizedCollectionActions: projectAuthorizedCollectionActions, }, },