diff --git a/src/common/security/robot/context.go b/src/common/security/robot/context.go index 2754f90fb288..5c175046d94a 100644 --- a/src/common/security/robot/context.go +++ b/src/common/security/robot/context.go @@ -111,7 +111,8 @@ func (s *SecurityContext) Can(ctx context.Context, action types.Action, resource } if len(sysPolicies) != 0 { evaluators = evaluators.Add(system.NewEvaluator(s.GetUsername(), sysPolicies)) - } else if len(proPolicies) != 0 { + } + if len(proPolicies) != 0 { evaluators = evaluators.Add(rbac_project.NewEvaluator(s.ctl, rbac_project.NewBuilderForPolicies(s.GetUsername(), proPolicies))) } s.evaluator = evaluators @@ -119,7 +120,6 @@ func (s *SecurityContext) Can(ctx context.Context, action types.Action, resource s.evaluator = rbac_project.NewEvaluator(s.ctl, rbac_project.NewBuilderForPolicies(s.GetUsername(), accesses, filterRobotPolicies)) } }) - return s.evaluator != nil && s.evaluator.HasPermission(ctx, resource, action) } diff --git a/src/common/security/robot/context_test.go b/src/common/security/robot/context_test.go index c499ed24b7d1..ed7074145598 100644 --- a/src/common/security/robot/context_test.go +++ b/src/common/security/robot/context_test.go @@ -17,6 +17,7 @@ package robot import ( "context" "fmt" + "github.com/goharbor/harbor/src/common/rbac/system" "reflect" "testing" @@ -198,6 +199,57 @@ func TestHasPushPullPerm(t *testing.T) { assert.True(t, ctx.Can(context.TODO(), rbac.ActionPush, resource) && ctx.Can(context.TODO(), rbac.ActionPull, resource)) } +func TestSysAndProPerm(t *testing.T) { + robot := &robot.Robot{ + Level: "system", + Robot: model.Robot{ + Name: "test_robot_4", + Description: "desc", + }, + Permissions: []*robot.Permission{ + { + Kind: "system", + Namespace: "/", + Access: []*types.Policy{ + { + Resource: rbac.Resource(fmt.Sprintf("system/%s", rbac.ResourceRepository)), + Action: rbac.ActionList, + }, + { + Resource: rbac.Resource(fmt.Sprintf("system/%s", rbac.ResourceGarbageCollection)), + Action: rbac.ActionCreate, + }, + }, + }, + { + Kind: "project", + Namespace: "library", + Access: []*types.Policy{ + { + Resource: rbac.Resource(fmt.Sprintf("project/%d/repository", private.ProjectID)), + Action: rbac.ActionPush, + }, + { + Resource: rbac.Resource(fmt.Sprintf("project/%d/repository", private.ProjectID)), + Action: rbac.ActionPull, + }, + }, + }, + }, + } + + ctl := &projecttesting.Controller{} + mock.OnAnything(ctl, "Get").Return(private, nil) + + ctx := NewSecurityContext(robot) + ctx.ctl = ctl + resource := project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository) + assert.True(t, ctx.Can(context.TODO(), rbac.ActionPush, resource) && ctx.Can(context.TODO(), rbac.ActionPull, resource)) + + resource = system.NewNamespace().Resource(rbac.ResourceGarbageCollection) + assert.True(t, ctx.Can(context.TODO(), rbac.ActionCreate, resource)) +} + func Test_filterRobotPolicies(t *testing.T) { type args struct { p *proModels.Project