refractor project rbac (#13924)

As the system rbac introduced, move the code of project rbac into project directory

Signed-off-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
Wang Yan 2021-01-11 11:27:26 +08:00 committed by GitHub
parent 64e61c0d11
commit 2d4456c630
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 495 additions and 478 deletions

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package rbac
package project
import (
"context"
@ -26,15 +26,15 @@ import (
"github.com/goharbor/harbor/src/pkg/permission/types"
)
// ProjectRBACUserBuilder builder to make types.RBACUser for the project
type ProjectRBACUserBuilder func(context.Context, *models.Project) types.RBACUser
// RBACUserBuilder builder to make types.RBACUser for the project
type RBACUserBuilder func(context.Context, *models.Project) types.RBACUser
// NewBuilderForUser create a builder for the local user
func NewBuilderForUser(user *models.User, ctl project.Controller) ProjectRBACUserBuilder {
func NewBuilderForUser(user *models.User, ctl project.Controller) RBACUserBuilder {
return func(ctx context.Context, p *models.Project) types.RBACUser {
if user == nil {
// anonymous access
return &projectRBACUser{
return &rbacUser{
project: p,
username: "anonymous",
}
@ -46,7 +46,7 @@ func NewBuilderForUser(user *models.User, ctl project.Controller) ProjectRBACUse
return nil
}
return &projectRBACUser{
return &rbacUser{
project: p,
username: user.Username,
projectRoles: roles,
@ -56,14 +56,14 @@ func NewBuilderForUser(user *models.User, ctl project.Controller) ProjectRBACUse
// NewBuilderForPolicies create a builder for the policies
func NewBuilderForPolicies(username string, policies []*types.Policy,
filters ...func(*models.Project, []*types.Policy) []*types.Policy) ProjectRBACUserBuilder {
filters ...func(*models.Project, []*types.Policy) []*types.Policy) RBACUserBuilder {
return func(ctx context.Context, p *models.Project) types.RBACUser {
for _, filter := range filters {
policies = filter(p, policies)
}
return &projectRBACUser{
return &rbacUser{
project: p,
username: username,
policies: policies,
@ -71,9 +71,9 @@ func NewBuilderForPolicies(username string, policies []*types.Policy,
}
}
// NewProjectEvaluator create evaluator for the project by builders
func NewProjectEvaluator(ctl project.Controller, builders ...ProjectRBACUserBuilder) evaluator.Evaluator {
return namespace.New(ProjectNamespaceKind, func(ctx context.Context, ns types.Namespace) evaluator.Evaluator {
// NewEvaluator create evaluator for the project by builders
func NewEvaluator(ctl project.Controller, builders ...RBACUserBuilder) evaluator.Evaluator {
return namespace.New(NamespaceKind, func(ctx context.Context, ns types.Namespace) evaluator.Evaluator {
p, err := ctl.Get(ctx, ns.Identity().(int64), project.Metadata(true))
if err != nil {
if err != nil {

View File

@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package rbac
package project
import (
"context"
"github.com/goharbor/harbor/src/common/rbac"
"testing"
"github.com/goharbor/harbor/src/common"
@ -53,10 +54,10 @@ func TestAnonymousAccess(t *testing.T) {
ctl := &projecttesting.Controller{}
mock.OnAnything(ctl, "Get").Return(public, nil)
resource := NewProjectNamespace(public.ProjectID).Resource(ResourceRepository)
resource := NewNamespace(public.ProjectID).Resource(rbac.ResourceRepository)
evaluator := NewProjectEvaluator(ctl, NewBuilderForUser(nil, ctl))
assert.True(evaluator.HasPermission(context.TODO(), resource, ActionPull))
evaluator := NewEvaluator(ctl, NewBuilderForUser(nil, ctl))
assert.True(evaluator.HasPermission(context.TODO(), resource, rbac.ActionPull))
}
{
@ -64,10 +65,10 @@ func TestAnonymousAccess(t *testing.T) {
ctl := &projecttesting.Controller{}
mock.OnAnything(ctl, "Get").Return(private, nil)
resource := NewProjectNamespace(private.ProjectID).Resource(ResourceRepository)
resource := NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
evaluator := NewProjectEvaluator(ctl, NewBuilderForUser(nil, ctl))
assert.False(evaluator.HasPermission(context.TODO(), resource, ActionPull))
evaluator := NewEvaluator(ctl, NewBuilderForUser(nil, ctl))
assert.False(evaluator.HasPermission(context.TODO(), resource, rbac.ActionPull))
}
}
@ -83,9 +84,9 @@ func TestProjectRoleAccess(t *testing.T) {
UserID: 1,
Username: "username",
}
evaluator := NewProjectEvaluator(ctl, NewBuilderForUser(user, ctl))
resorce := NewProjectNamespace(public.ProjectID).Resource(ResourceRepository)
assert.True(evaluator.HasPermission(context.TODO(), resorce, ActionPush))
evaluator := NewEvaluator(ctl, NewBuilderForUser(user, ctl))
resorce := NewNamespace(public.ProjectID).Resource(rbac.ResourceRepository)
assert.True(evaluator.HasPermission(context.TODO(), resorce, rbac.ActionPush))
}
{
@ -97,9 +98,9 @@ func TestProjectRoleAccess(t *testing.T) {
UserID: 1,
Username: "username",
}
evaluator := NewProjectEvaluator(ctl, NewBuilderForUser(user, ctl))
resorce := NewProjectNamespace(public.ProjectID).Resource(ResourceRepository)
assert.False(evaluator.HasPermission(context.TODO(), resorce, ActionPush))
evaluator := NewEvaluator(ctl, NewBuilderForUser(user, ctl))
resorce := NewNamespace(public.ProjectID).Resource(rbac.ResourceRepository)
assert.False(evaluator.HasPermission(context.TODO(), resorce, rbac.ActionPush))
}
}
@ -112,12 +113,12 @@ func BenchmarkProjectEvaluator(b *testing.B) {
UserID: 1,
Username: "username",
}
evaluator := NewProjectEvaluator(ctl, NewBuilderForUser(user, ctl))
resource := NewProjectNamespace(public.ProjectID).Resource(ResourceRepository)
evaluator := NewEvaluator(ctl, NewBuilderForUser(user, ctl))
resource := NewNamespace(public.ProjectID).Resource(rbac.ResourceRepository)
b.ResetTimer()
for i := 0; i < b.N; i++ {
evaluator.HasPermission(context.TODO(), resource, ActionPull)
evaluator.HasPermission(context.TODO(), resource, rbac.ActionPull)
}
}
@ -130,12 +131,12 @@ func BenchmarkProjectEvaluatorParallel(b *testing.B) {
UserID: 1,
Username: "username",
}
evaluator := NewProjectEvaluator(ctl, NewBuilderForUser(user, ctl))
resource := NewProjectNamespace(public.ProjectID).Resource(ResourceRepository)
evaluator := NewEvaluator(ctl, NewBuilderForUser(user, ctl))
resource := NewNamespace(public.ProjectID).Resource(rbac.ResourceRepository)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
evaluator.HasPermission(context.TODO(), resource, ActionPull)
evaluator.HasPermission(context.TODO(), resource, rbac.ActionPull)
}
})
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package rbac
package project
import (
"fmt"
@ -23,8 +23,8 @@ import (
)
const (
// ProjectNamespaceKind kind for project namespace
ProjectNamespaceKind = "project"
// NamespaceKind kind for project projectNamespace
NamespaceKind = "project"
)
var (
@ -36,7 +36,7 @@ type projectNamespace struct {
}
func (ns *projectNamespace) Kind() string {
return ProjectNamespaceKind
return NamespaceKind
}
func (ns *projectNamespace) Resource(subresources ...types.Resource) types.Resource {
@ -51,13 +51,13 @@ func (ns *projectNamespace) GetPolicies() []*types.Policy {
return GetPoliciesOfProject(ns.projectID)
}
// NewProjectNamespace returns namespace for project
func NewProjectNamespace(projectID int64) types.Namespace {
// NewNamespace returns projectNamespace for project
func NewNamespace(projectID int64) types.Namespace {
return &projectNamespace{projectID: projectID}
}
// ProjectNamespaceParse ...
func ProjectNamespaceParse(resource types.Resource) (types.Namespace, bool) {
// NamespaceParse ...
func NamespaceParse(resource types.Resource) (types.Namespace, bool) {
matches := projectNamespaceRe.FindStringSubmatch(resource.String())
if len(matches) <= 1 {
@ -69,9 +69,9 @@ func ProjectNamespaceParse(resource types.Resource) (types.Namespace, bool) {
return nil, false
}
return NewProjectNamespace(projectID), true
return NewNamespace(projectID), true
}
func init() {
types.RegistryNamespaceParse(ProjectNamespaceKind, ProjectNamespaceParse)
types.RegistryNamespaceParse(NamespaceKind, NamespaceParse)
}

View File

@ -0,0 +1,368 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package project
import (
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/pkg/permission/types"
)
var (
rolePoliciesMap = map[string][]*types.Policy{
"projectAdmin": {
{Resource: rbac.ResourceSelf, Action: rbac.ActionRead},
{Resource: rbac.ResourceSelf, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceSelf, Action: rbac.ActionDelete},
{Resource: rbac.ResourceMember, Action: rbac.ActionCreate},
{Resource: rbac.ResourceMember, Action: rbac.ActionRead},
{Resource: rbac.ResourceMember, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceMember, Action: rbac.ActionDelete},
{Resource: rbac.ResourceMember, Action: rbac.ActionList},
{Resource: rbac.ResourceMetadata, Action: rbac.ActionCreate},
{Resource: rbac.ResourceMetadata, Action: rbac.ActionRead},
{Resource: rbac.ResourceMetadata, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceMetadata, Action: rbac.ActionDelete},
{Resource: rbac.ResourceLog, Action: rbac.ActionList},
{Resource: rbac.ResourceLabel, Action: rbac.ActionCreate},
{Resource: rbac.ResourceLabel, Action: rbac.ActionRead},
{Resource: rbac.ResourceLabel, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceLabel, Action: rbac.ActionDelete},
{Resource: rbac.ResourceLabel, Action: rbac.ActionList},
{Resource: rbac.ResourceQuota, Action: rbac.ActionRead},
{Resource: rbac.ResourceRepository, Action: rbac.ActionCreate},
{Resource: rbac.ResourceRepository, Action: rbac.ActionRead},
{Resource: rbac.ResourceRepository, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceRepository, Action: rbac.ActionDelete},
{Resource: rbac.ResourceRepository, Action: rbac.ActionList},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPull},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPush},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionCreate},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionRead},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionDelete},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionList},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionOperate},
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionCreate},
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionDelete},
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionCreate}, // upload helm chart
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionRead}, // download helm chart
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionDelete},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionCreate}, // upload helm chart version
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionRead}, // read and download helm chart version
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionDelete},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChartVersionLabel, Action: rbac.ActionCreate},
{Resource: rbac.ResourceHelmChartVersionLabel, Action: rbac.ActionDelete},
{Resource: rbac.ResourceConfiguration, Action: rbac.ActionRead},
{Resource: rbac.ResourceConfiguration, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceRobot, Action: rbac.ActionCreate},
{Resource: rbac.ResourceRobot, Action: rbac.ActionRead},
{Resource: rbac.ResourceRobot, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceRobot, Action: rbac.ActionDelete},
{Resource: rbac.ResourceRobot, Action: rbac.ActionList},
{Resource: rbac.ResourceNotificationPolicy, Action: rbac.ActionCreate},
{Resource: rbac.ResourceNotificationPolicy, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceNotificationPolicy, Action: rbac.ActionDelete},
{Resource: rbac.ResourceNotificationPolicy, Action: rbac.ActionList},
{Resource: rbac.ResourceNotificationPolicy, Action: rbac.ActionRead},
{Resource: rbac.ResourceScan, Action: rbac.ActionCreate},
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
{Resource: rbac.ResourceScanner, Action: rbac.ActionCreate},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionCreate},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionDelete},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionList},
{Resource: rbac.ResourceArtifactAddition, Action: rbac.ActionRead},
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
{Resource: rbac.ResourceTag, Action: rbac.ActionCreate},
{Resource: rbac.ResourceTag, Action: rbac.ActionDelete},
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionCreate},
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionDelete},
{Resource: rbac.ResourcePreatPolicy, Action: rbac.ActionCreate},
{Resource: rbac.ResourcePreatPolicy, Action: rbac.ActionRead},
{Resource: rbac.ResourcePreatPolicy, Action: rbac.ActionUpdate},
{Resource: rbac.ResourcePreatPolicy, Action: rbac.ActionDelete},
{Resource: rbac.ResourcePreatPolicy, Action: rbac.ActionList},
},
"maintainer": {
{Resource: rbac.ResourceSelf, Action: rbac.ActionRead},
{Resource: rbac.ResourceMember, Action: rbac.ActionRead},
{Resource: rbac.ResourceMember, Action: rbac.ActionList},
{Resource: rbac.ResourceMetadata, Action: rbac.ActionCreate},
{Resource: rbac.ResourceMetadata, Action: rbac.ActionRead},
{Resource: rbac.ResourceMetadata, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceMetadata, Action: rbac.ActionDelete},
{Resource: rbac.ResourceLog, Action: rbac.ActionList},
{Resource: rbac.ResourceQuota, Action: rbac.ActionRead},
{Resource: rbac.ResourceLabel, Action: rbac.ActionCreate},
{Resource: rbac.ResourceLabel, Action: rbac.ActionRead},
{Resource: rbac.ResourceLabel, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceLabel, Action: rbac.ActionDelete},
{Resource: rbac.ResourceLabel, Action: rbac.ActionList},
{Resource: rbac.ResourceRepository, Action: rbac.ActionCreate},
{Resource: rbac.ResourceRepository, Action: rbac.ActionRead},
{Resource: rbac.ResourceRepository, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceRepository, Action: rbac.ActionDelete},
{Resource: rbac.ResourceRepository, Action: rbac.ActionList},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPush},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPull},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionCreate},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionRead},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionDelete},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionList},
{Resource: rbac.ResourceTagRetention, Action: rbac.ActionOperate},
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionCreate},
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionDelete},
{Resource: rbac.ResourceImmutableTag, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionCreate},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionDelete},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionCreate},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionDelete},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChartVersionLabel, Action: rbac.ActionCreate},
{Resource: rbac.ResourceHelmChartVersionLabel, Action: rbac.ActionDelete},
{Resource: rbac.ResourceConfiguration, Action: rbac.ActionRead},
{Resource: rbac.ResourceRobot, Action: rbac.ActionRead},
{Resource: rbac.ResourceRobot, Action: rbac.ActionList},
{Resource: rbac.ResourceNotificationPolicy, Action: rbac.ActionList},
{Resource: rbac.ResourceScan, Action: rbac.ActionCreate},
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionCreate},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionDelete},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionList},
{Resource: rbac.ResourceArtifactAddition, Action: rbac.ActionRead},
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
{Resource: rbac.ResourceTag, Action: rbac.ActionCreate},
{Resource: rbac.ResourceTag, Action: rbac.ActionDelete},
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionCreate},
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionDelete},
},
"developer": {
{Resource: rbac.ResourceSelf, Action: rbac.ActionRead},
{Resource: rbac.ResourceMember, Action: rbac.ActionRead},
{Resource: rbac.ResourceMember, Action: rbac.ActionList},
{Resource: rbac.ResourceLog, Action: rbac.ActionList},
{Resource: rbac.ResourceLabel, Action: rbac.ActionRead},
{Resource: rbac.ResourceLabel, Action: rbac.ActionList},
{Resource: rbac.ResourceQuota, Action: rbac.ActionRead},
{Resource: rbac.ResourceRepository, Action: rbac.ActionCreate},
{Resource: rbac.ResourceRepository, Action: rbac.ActionRead},
{Resource: rbac.ResourceRepository, Action: rbac.ActionUpdate},
{Resource: rbac.ResourceRepository, Action: rbac.ActionList},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPush},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPull},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionCreate},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionCreate},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChartVersionLabel, Action: rbac.ActionCreate},
{Resource: rbac.ResourceHelmChartVersionLabel, Action: rbac.ActionDelete},
{Resource: rbac.ResourceConfiguration, Action: rbac.ActionRead},
{Resource: rbac.ResourceRobot, Action: rbac.ActionRead},
{Resource: rbac.ResourceRobot, Action: rbac.ActionList},
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionCreate},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionList},
{Resource: rbac.ResourceArtifactAddition, Action: rbac.ActionRead},
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
{Resource: rbac.ResourceTag, Action: rbac.ActionCreate},
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionCreate},
{Resource: rbac.ResourceArtifactLabel, Action: rbac.ActionDelete},
},
"guest": {
{Resource: rbac.ResourceSelf, Action: rbac.ActionRead},
{Resource: rbac.ResourceMember, Action: rbac.ActionRead},
{Resource: rbac.ResourceMember, Action: rbac.ActionList},
{Resource: rbac.ResourceLog, Action: rbac.ActionList},
{Resource: rbac.ResourceLabel, Action: rbac.ActionRead},
{Resource: rbac.ResourceLabel, Action: rbac.ActionList},
{Resource: rbac.ResourceQuota, Action: rbac.ActionRead},
{Resource: rbac.ResourceRepository, Action: rbac.ActionRead},
{Resource: rbac.ResourceRepository, Action: rbac.ActionList},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPull},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionList},
{Resource: rbac.ResourceConfiguration, Action: rbac.ActionRead},
{Resource: rbac.ResourceRobot, Action: rbac.ActionRead},
{Resource: rbac.ResourceRobot, Action: rbac.ActionList},
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionList},
{Resource: rbac.ResourceArtifactAddition, Action: rbac.ActionRead},
},
"limitedGuest": {
{Resource: rbac.ResourceSelf, Action: rbac.ActionRead},
{Resource: rbac.ResourceQuota, Action: rbac.ActionRead},
{Resource: rbac.ResourceRepository, Action: rbac.ActionList},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPull},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionList},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionList},
{Resource: rbac.ResourceConfiguration, Action: rbac.ActionRead},
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionList},
{Resource: rbac.ResourceArtifactAddition, Action: rbac.ActionRead},
},
}
)
// projectRBACRole implement the RBACRole interface
type projectRBACRole struct {
projectID int64
roleID int
}
// GetRoleName returns role name for the visitor role
func (role *projectRBACRole) GetRoleName() string {
switch role.roleID {
case common.RoleProjectAdmin:
return "projectAdmin"
case common.RoleMaintainer:
return "maintainer"
case common.RoleDeveloper:
return "developer"
case common.RoleGuest:
return "guest"
case common.RoleLimitedGuest:
return "limitedGuest"
default:
return ""
}
}
// GetPolicies returns policies for the visitor role
func (role *projectRBACRole) GetPolicies() []*types.Policy {
policies := []*types.Policy{}
roleName := role.GetRoleName()
if roleName == "" {
return policies
}
namespace := NewNamespace(role.projectID)
for _, policy := range rolePoliciesMap[roleName] {
policies = append(policies, &types.Policy{
Resource: namespace.Resource(policy.Resource),
Action: policy.Action,
Effect: policy.Effect,
})
}
return policies
}

View File

@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package rbac
package project
import (
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/pkg/permission/types"
)
type projectRBACUser struct {
type rbacUser struct {
project *models.Project
username string
projectRoles []int
@ -27,12 +27,12 @@ type projectRBACUser struct {
}
// GetUserName returns username of the visitor
func (pru *projectRBACUser) GetUserName() string {
func (pru *rbacUser) GetUserName() string {
return pru.username
}
// GetPolicies returns policies of the visitor
func (pru *projectRBACUser) GetPolicies() []*types.Policy {
func (pru *rbacUser) GetPolicies() []*types.Policy {
policies := pru.policies
if pru.project.IsPublic() {
@ -43,7 +43,7 @@ func (pru *projectRBACUser) GetPolicies() []*types.Policy {
}
// GetRoles returns roles of the visitor
func (pru *projectRBACUser) GetRoles() []types.RBACRole {
func (pru *rbacUser) GetRoles() []types.RBACRole {
roles := []types.RBACRole{}
for _, roleID := range pru.projectRoles {
roles = append(roles, &projectRBACRole{projectID: pru.project.ProjectID, roleID: roleID})

View File

@ -12,37 +12,38 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package rbac
package project
import (
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/pkg/permission/types"
)
var (
// subresource policies for public project
publicProjectPolicies = []*types.Policy{
{Resource: ResourceSelf, Action: ActionRead},
{Resource: rbac.ResourceSelf, Action: rbac.ActionRead},
{Resource: ResourceLabel, Action: ActionRead},
{Resource: ResourceLabel, Action: ActionList},
{Resource: rbac.ResourceLabel, Action: rbac.ActionRead},
{Resource: rbac.ResourceLabel, Action: rbac.ActionList},
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: rbac.ResourceRepository, Action: rbac.ActionList},
{Resource: rbac.ResourceRepository, Action: rbac.ActionPull},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionList},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChart, Action: rbac.ActionList},
{Resource: ResourceHelmChartVersion, Action: ActionRead},
{Resource: ResourceHelmChartVersion, Action: ActionList},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionRead},
{Resource: rbac.ResourceHelmChartVersion, Action: rbac.ActionList},
{Resource: ResourceScan, Action: ActionRead},
{Resource: ResourceScanner, Action: ActionRead},
{Resource: rbac.ResourceScan, Action: rbac.ActionRead},
{Resource: rbac.ResourceScanner, Action: rbac.ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: rbac.ResourceTag, Action: rbac.ActionList},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionRead},
{Resource: rbac.ResourceArtifact, Action: rbac.ActionList},
{Resource: rbac.ResourceArtifactAddition, Action: rbac.ActionRead},
}
// sub policies for the projects
@ -52,7 +53,7 @@ var (
func getPoliciesForPublicProject(projectID int64) []*types.Policy {
policies := []*types.Policy{}
namespace := NewProjectNamespace(projectID)
namespace := NewNamespace(projectID)
for _, policy := range publicProjectPolicies {
policies = append(policies, &types.Policy{
Resource: namespace.Resource(policy.Resource),
@ -64,11 +65,11 @@ func getPoliciesForPublicProject(projectID int64) []*types.Policy {
return policies
}
// GetPoliciesOfProject returns all policies for namespace of the project
// GetPoliciesOfProject returns all policies for projectNamespace of the project
func GetPoliciesOfProject(projectID int64) []*types.Policy {
policies := []*types.Policy{}
namespace := NewProjectNamespace(projectID)
namespace := NewNamespace(projectID)
for _, policy := range subPoliciesForProject {
policies = append(policies, &types.Policy{
Resource: namespace.Resource(policy.Resource),

View File

@ -1,367 +0,0 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rbac
import (
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/pkg/permission/types"
)
var (
rolePoliciesMap = map[string][]*types.Policy{
"projectAdmin": {
{Resource: ResourceSelf, Action: ActionRead},
{Resource: ResourceSelf, Action: ActionUpdate},
{Resource: ResourceSelf, Action: ActionDelete},
{Resource: ResourceMember, Action: ActionCreate},
{Resource: ResourceMember, Action: ActionRead},
{Resource: ResourceMember, Action: ActionUpdate},
{Resource: ResourceMember, Action: ActionDelete},
{Resource: ResourceMember, Action: ActionList},
{Resource: ResourceMetadata, Action: ActionCreate},
{Resource: ResourceMetadata, Action: ActionRead},
{Resource: ResourceMetadata, Action: ActionUpdate},
{Resource: ResourceMetadata, Action: ActionDelete},
{Resource: ResourceLog, Action: ActionList},
{Resource: ResourceLabel, Action: ActionCreate},
{Resource: ResourceLabel, Action: ActionRead},
{Resource: ResourceLabel, Action: ActionUpdate},
{Resource: ResourceLabel, Action: ActionDelete},
{Resource: ResourceLabel, Action: ActionList},
{Resource: ResourceQuota, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionCreate},
{Resource: ResourceRepository, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionUpdate},
{Resource: ResourceRepository, Action: ActionDelete},
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceRepository, Action: ActionPush},
{Resource: ResourceTagRetention, Action: ActionCreate},
{Resource: ResourceTagRetention, Action: ActionRead},
{Resource: ResourceTagRetention, Action: ActionUpdate},
{Resource: ResourceTagRetention, Action: ActionDelete},
{Resource: ResourceTagRetention, Action: ActionList},
{Resource: ResourceTagRetention, Action: ActionOperate},
{Resource: ResourceImmutableTag, Action: ActionCreate},
{Resource: ResourceImmutableTag, Action: ActionUpdate},
{Resource: ResourceImmutableTag, Action: ActionDelete},
{Resource: ResourceImmutableTag, Action: ActionList},
{Resource: ResourceHelmChart, Action: ActionCreate}, // upload helm chart
{Resource: ResourceHelmChart, Action: ActionRead}, // download helm chart
{Resource: ResourceHelmChart, Action: ActionDelete},
{Resource: ResourceHelmChart, Action: ActionList},
{Resource: ResourceHelmChartVersion, Action: ActionCreate}, // upload helm chart version
{Resource: ResourceHelmChartVersion, Action: ActionRead}, // read and download helm chart version
{Resource: ResourceHelmChartVersion, Action: ActionDelete},
{Resource: ResourceHelmChartVersion, Action: ActionList},
{Resource: ResourceHelmChartVersionLabel, Action: ActionCreate},
{Resource: ResourceHelmChartVersionLabel, Action: ActionDelete},
{Resource: ResourceConfiguration, Action: ActionRead},
{Resource: ResourceConfiguration, Action: ActionUpdate},
{Resource: ResourceRobot, Action: ActionCreate},
{Resource: ResourceRobot, Action: ActionRead},
{Resource: ResourceRobot, Action: ActionUpdate},
{Resource: ResourceRobot, Action: ActionDelete},
{Resource: ResourceRobot, Action: ActionList},
{Resource: ResourceNotificationPolicy, Action: ActionCreate},
{Resource: ResourceNotificationPolicy, Action: ActionUpdate},
{Resource: ResourceNotificationPolicy, Action: ActionDelete},
{Resource: ResourceNotificationPolicy, Action: ActionList},
{Resource: ResourceNotificationPolicy, Action: ActionRead},
{Resource: ResourceScan, Action: ActionCreate},
{Resource: ResourceScan, Action: ActionRead},
{Resource: ResourceScanner, Action: ActionRead},
{Resource: ResourceScanner, Action: ActionCreate},
{Resource: ResourceArtifact, Action: ActionCreate},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionDelete},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceTag, Action: ActionCreate},
{Resource: ResourceTag, Action: ActionDelete},
{Resource: ResourceArtifactLabel, Action: ActionCreate},
{Resource: ResourceArtifactLabel, Action: ActionDelete},
{Resource: ResourcePreatPolicy, Action: ActionCreate},
{Resource: ResourcePreatPolicy, Action: ActionRead},
{Resource: ResourcePreatPolicy, Action: ActionUpdate},
{Resource: ResourcePreatPolicy, Action: ActionDelete},
{Resource: ResourcePreatPolicy, Action: ActionList},
},
"maintainer": {
{Resource: ResourceSelf, Action: ActionRead},
{Resource: ResourceMember, Action: ActionRead},
{Resource: ResourceMember, Action: ActionList},
{Resource: ResourceMetadata, Action: ActionCreate},
{Resource: ResourceMetadata, Action: ActionRead},
{Resource: ResourceMetadata, Action: ActionUpdate},
{Resource: ResourceMetadata, Action: ActionDelete},
{Resource: ResourceLog, Action: ActionList},
{Resource: ResourceQuota, Action: ActionRead},
{Resource: ResourceLabel, Action: ActionCreate},
{Resource: ResourceLabel, Action: ActionRead},
{Resource: ResourceLabel, Action: ActionUpdate},
{Resource: ResourceLabel, Action: ActionDelete},
{Resource: ResourceLabel, Action: ActionList},
{Resource: ResourceRepository, Action: ActionCreate},
{Resource: ResourceRepository, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionUpdate},
{Resource: ResourceRepository, Action: ActionDelete},
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPush},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceTagRetention, Action: ActionCreate},
{Resource: ResourceTagRetention, Action: ActionRead},
{Resource: ResourceTagRetention, Action: ActionUpdate},
{Resource: ResourceTagRetention, Action: ActionDelete},
{Resource: ResourceTagRetention, Action: ActionList},
{Resource: ResourceTagRetention, Action: ActionOperate},
{Resource: ResourceImmutableTag, Action: ActionCreate},
{Resource: ResourceImmutableTag, Action: ActionUpdate},
{Resource: ResourceImmutableTag, Action: ActionDelete},
{Resource: ResourceImmutableTag, Action: ActionList},
{Resource: ResourceHelmChart, Action: ActionCreate},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionDelete},
{Resource: ResourceHelmChart, Action: ActionList},
{Resource: ResourceHelmChartVersion, Action: ActionCreate},
{Resource: ResourceHelmChartVersion, Action: ActionRead},
{Resource: ResourceHelmChartVersion, Action: ActionDelete},
{Resource: ResourceHelmChartVersion, Action: ActionList},
{Resource: ResourceHelmChartVersionLabel, Action: ActionCreate},
{Resource: ResourceHelmChartVersionLabel, Action: ActionDelete},
{Resource: ResourceConfiguration, Action: ActionRead},
{Resource: ResourceRobot, Action: ActionRead},
{Resource: ResourceRobot, Action: ActionList},
{Resource: ResourceNotificationPolicy, Action: ActionList},
{Resource: ResourceScan, Action: ActionCreate},
{Resource: ResourceScan, Action: ActionRead},
{Resource: ResourceScanner, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionCreate},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionDelete},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceTag, Action: ActionCreate},
{Resource: ResourceTag, Action: ActionDelete},
{Resource: ResourceArtifactLabel, Action: ActionCreate},
{Resource: ResourceArtifactLabel, Action: ActionDelete},
},
"developer": {
{Resource: ResourceSelf, Action: ActionRead},
{Resource: ResourceMember, Action: ActionRead},
{Resource: ResourceMember, Action: ActionList},
{Resource: ResourceLog, Action: ActionList},
{Resource: ResourceLabel, Action: ActionRead},
{Resource: ResourceLabel, Action: ActionList},
{Resource: ResourceQuota, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionCreate},
{Resource: ResourceRepository, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionUpdate},
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPush},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceHelmChart, Action: ActionCreate},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionList},
{Resource: ResourceHelmChartVersion, Action: ActionCreate},
{Resource: ResourceHelmChartVersion, Action: ActionRead},
{Resource: ResourceHelmChartVersion, Action: ActionList},
{Resource: ResourceHelmChartVersionLabel, Action: ActionCreate},
{Resource: ResourceHelmChartVersionLabel, Action: ActionDelete},
{Resource: ResourceConfiguration, Action: ActionRead},
{Resource: ResourceRobot, Action: ActionRead},
{Resource: ResourceRobot, Action: ActionList},
{Resource: ResourceScan, Action: ActionRead},
{Resource: ResourceScanner, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionCreate},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceTag, Action: ActionCreate},
{Resource: ResourceArtifactLabel, Action: ActionCreate},
{Resource: ResourceArtifactLabel, Action: ActionDelete},
},
"guest": {
{Resource: ResourceSelf, Action: ActionRead},
{Resource: ResourceMember, Action: ActionRead},
{Resource: ResourceMember, Action: ActionList},
{Resource: ResourceLog, Action: ActionList},
{Resource: ResourceLabel, Action: ActionRead},
{Resource: ResourceLabel, Action: ActionList},
{Resource: ResourceQuota, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionList},
{Resource: ResourceHelmChartVersion, Action: ActionRead},
{Resource: ResourceHelmChartVersion, Action: ActionList},
{Resource: ResourceConfiguration, Action: ActionRead},
{Resource: ResourceRobot, Action: ActionRead},
{Resource: ResourceRobot, Action: ActionList},
{Resource: ResourceScan, Action: ActionRead},
{Resource: ResourceScanner, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
},
"limitedGuest": {
{Resource: ResourceSelf, Action: ActionRead},
{Resource: ResourceQuota, Action: ActionRead},
{Resource: ResourceRepository, Action: ActionList},
{Resource: ResourceRepository, Action: ActionPull},
{Resource: ResourceHelmChart, Action: ActionRead},
{Resource: ResourceHelmChart, Action: ActionList},
{Resource: ResourceHelmChartVersion, Action: ActionRead},
{Resource: ResourceHelmChartVersion, Action: ActionList},
{Resource: ResourceConfiguration, Action: ActionRead},
{Resource: ResourceScan, Action: ActionRead},
{Resource: ResourceScanner, Action: ActionRead},
{Resource: ResourceTag, Action: ActionList},
{Resource: ResourceArtifact, Action: ActionRead},
{Resource: ResourceArtifact, Action: ActionList},
{Resource: ResourceArtifactAddition, Action: ActionRead},
},
}
)
// projectRBACRole implement the RBACRole interface
type projectRBACRole struct {
projectID int64
roleID int
}
// GetRoleName returns role name for the visitor role
func (role *projectRBACRole) GetRoleName() string {
switch role.roleID {
case common.RoleProjectAdmin:
return "projectAdmin"
case common.RoleMaintainer:
return "maintainer"
case common.RoleDeveloper:
return "developer"
case common.RoleGuest:
return "guest"
case common.RoleLimitedGuest:
return "limitedGuest"
default:
return ""
}
}
// GetPolicies returns policies for the visitor role
func (role *projectRBACRole) GetPolicies() []*types.Policy {
policies := []*types.Policy{}
roleName := role.GetRoleName()
if roleName == "" {
return policies
}
namespace := NewProjectNamespace(role.projectID)
for _, policy := range rolePoliciesMap[roleName] {
policies = append(policies, &types.Policy{
Resource: namespace.Resource(policy.Resource),
Action: policy.Action,
Effect: policy.Effect,
})
}
return policies
}

View File

@ -16,10 +16,10 @@ package local
import (
"context"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"sync"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/controller/project"
"github.com/goharbor/harbor/src/pkg/permission/evaluator"
"github.com/goharbor/harbor/src/pkg/permission/evaluator/admin"
@ -88,7 +88,7 @@ func (s *SecurityContext) Can(ctx context.Context, action types.Action, resource
evaluators = evaluators.Add(admin.New(s.GetUsername()))
}
evaluators = evaluators.Add(rbac.NewProjectEvaluator(s.ctl, rbac.NewBuilderForUser(s.user, s.ctl)))
evaluators = evaluators.Add(rbac_project.NewEvaluator(s.ctl, rbac_project.NewBuilderForUser(s.user, s.ctl)))
s.evaluator = evaluators
})

View File

@ -16,6 +16,7 @@ package local
import (
"context"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"testing"
"github.com/goharbor/harbor/src/common"
@ -116,7 +117,7 @@ func TestHasPullPerm(t *testing.T) {
ctx := NewSecurityContext(nil)
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(1).Resource(rbac.ResourceRepository)
assert.True(t, ctx.Can(context.TODO(), rbac.ActionPull, resource))
}
@ -127,7 +128,7 @@ func TestHasPullPerm(t *testing.T) {
ctx := NewSecurityContext(nil)
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
assert.False(t, ctx.Can(context.TODO(), rbac.ActionPull, resource))
}
@ -139,7 +140,7 @@ func TestHasPullPerm(t *testing.T) {
ctx := NewSecurityContext(&models.User{Username: "test"})
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
assert.False(t, ctx.Can(context.TODO(), rbac.ActionPull, resource))
}
@ -151,7 +152,7 @@ func TestHasPullPerm(t *testing.T) {
ctx := NewSecurityContext(guestUser)
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
assert.True(t, ctx.Can(context.TODO(), rbac.ActionPull, resource))
}
@ -165,13 +166,13 @@ func TestHasPullPerm(t *testing.T) {
SysAdminFlag: true,
})
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
assert.True(t, ctx.Can(context.TODO(), rbac.ActionPull, resource))
}
}
func TestHasPushPerm(t *testing.T) {
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
{
// unauthenticated
@ -218,7 +219,7 @@ func TestHasPushPerm(t *testing.T) {
}
func TestHasPushPullPerm(t *testing.T) {
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
{
// unauthenticated
@ -266,7 +267,7 @@ func TestSysadminPerms(t *testing.T) {
SysAdminFlag: true,
})
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
assert.True(t, ctx.Can(context.TODO(), rbac.ActionPush, resource) && ctx.Can(context.TODO(), rbac.ActionPull, resource))
assert.False(t, ctx.Can(context.TODO(), rbac.ActionScannerPull, resource))

View File

@ -16,6 +16,7 @@ package proxycachesecret
import (
"context"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"github.com/goharbor/harbor/src/common/rbac"
"github.com/goharbor/harbor/src/common/utils"
@ -75,7 +76,7 @@ func (s *SecurityContext) Can(ctx context.Context, action types.Action, resource
log.Debugf("unauthorized for action %s", action)
return false
}
namespace, ok := rbac.ProjectNamespaceParse(resource)
namespace, ok := rbac_project.NamespaceParse(resource)
if !ok {
log.Debugf("got no namespace from the resource %s", resource)
return false

View File

@ -17,6 +17,7 @@ package proxycachesecret
import (
"context"
"errors"
"github.com/goharbor/harbor/src/common/rbac/project"
"testing"
"github.com/goharbor/harbor/src/common/models"
@ -63,7 +64,7 @@ func (p *proxyCacheSecretTestSuite) TestIsSolutionUser() {
func (p *proxyCacheSecretTestSuite) TestCan() {
// the action isn't pull/push
action := rbac.ActionDelete
resource := rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository)
resource := project.NewNamespace(1).Resource(rbac.ResourceRepository)
p.False(p.sc.Can(context.TODO(), action, resource))
// the resource isn't repository
@ -73,7 +74,7 @@ func (p *proxyCacheSecretTestSuite) TestCan() {
// the requested project not found
action = rbac.ActionPull
resource = rbac.NewProjectNamespace(2).Resource(rbac.ResourceRepository)
resource = project.NewNamespace(2).Resource(rbac.ResourceRepository)
p.ctl.On("Get", mock.Anything, mock.Anything).Return(nil, errors.New("not found"))
p.False(p.sc.Can(context.TODO(), action, resource))
p.ctl.AssertExpectations(p.T())
@ -83,7 +84,7 @@ func (p *proxyCacheSecretTestSuite) TestCan() {
// pass for action pull
action = rbac.ActionPull
resource = rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository)
resource = project.NewNamespace(1).Resource(rbac.ResourceRepository)
p.ctl.On("Get", mock.Anything, mock.Anything).Return(&models.Project{
ProjectID: 1,
Name: "library",
@ -96,7 +97,7 @@ func (p *proxyCacheSecretTestSuite) TestCan() {
// pass for action push
action = rbac.ActionPush
resource = rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository)
resource = project.NewNamespace(1).Resource(rbac.ResourceRepository)
p.ctl.On("Get", mock.Anything, mock.Anything).Return(&models.Project{
ProjectID: 1,
Name: "library",

View File

@ -16,6 +16,7 @@ package robot
import (
"context"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"github.com/goharbor/harbor/src/common/rbac/system"
"github.com/goharbor/harbor/src/controller/robot"
"strings"
@ -95,12 +96,12 @@ 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 {
evaluators = evaluators.Add(rbac.NewProjectEvaluator(s.ctl, rbac.NewBuilderForPolicies(s.GetUsername(), proPolicies)))
evaluators = evaluators.Add(rbac_project.NewEvaluator(s.ctl, rbac_project.NewBuilderForPolicies(s.GetUsername(), proPolicies)))
}
s.evaluator = evaluators
} else {
s.evaluator = rbac.NewProjectEvaluator(s.ctl, rbac.NewBuilderForPolicies(s.GetUsername(), s.policies, filterRobotPolicies))
s.evaluator = rbac_project.NewEvaluator(s.ctl, rbac_project.NewBuilderForPolicies(s.GetUsername(), s.policies, filterRobotPolicies))
}
})
@ -108,7 +109,7 @@ func (s *SecurityContext) Can(ctx context.Context, action types.Action, resource
}
func filterRobotPolicies(p *models.Project, policies []*types.Policy) []*types.Policy {
namespace := rbac.NewProjectNamespace(p.ProjectID)
namespace := rbac_project.NewNamespace(p.ProjectID)
var results []*types.Policy
for _, policy := range policies {

View File

@ -17,6 +17,7 @@ package robot
import (
"context"
"fmt"
"github.com/goharbor/harbor/src/common/rbac/project"
"reflect"
"testing"
@ -97,7 +98,7 @@ func TestHasPullPerm(t *testing.T) {
ctx := NewSecurityContext(robot, false, policies)
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
assert.True(t, ctx.Can(context.TODO(), rbac.ActionPull, resource))
}
@ -118,7 +119,7 @@ func TestHasPushPerm(t *testing.T) {
ctx := NewSecurityContext(robot, false, policies)
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
resource := project.NewNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
assert.True(t, ctx.Can(context.TODO(), rbac.ActionPush, resource))
}
@ -143,7 +144,7 @@ func TestHasPushPullPerm(t *testing.T) {
ctx := NewSecurityContext(robot, false, policies)
ctx.ctl = ctl
resource := rbac.NewProjectNamespace(private.ProjectID).Resource(rbac.ResourceRepository)
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))
}

View File

@ -2,6 +2,7 @@ package v2token
import (
"context"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"strings"
registry_token "github.com/docker/distribution/registry/auth/token"
@ -55,7 +56,7 @@ func (t *tokenSecurityCtx) Can(ctx context.Context, action types.Action, resourc
if !strings.HasSuffix(resource.String(), rbac.ResourceRepository.String()) {
return false
}
ns, ok := rbac.ProjectNamespaceParse(resource)
ns, ok := rbac_project.NamespaceParse(resource)
if !ok {
t.logger.Warningf("Failed to get namespace from resource: %s", resource)
return false

View File

@ -16,6 +16,7 @@ package v2token
import (
"context"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"testing"
"github.com/docker/distribution/registry/auth/token"
@ -71,42 +72,42 @@ func TestAll(t *testing.T) {
expect bool
}{
{
resource: rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository),
resource: rbac_project.NewNamespace(1).Resource(rbac.ResourceRepository),
action: rbac.ActionPush,
expect: true,
},
{
resource: rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository),
resource: rbac_project.NewNamespace(1).Resource(rbac.ResourceRepository),
action: rbac.ActionScannerPull,
expect: true,
},
{
resource: rbac.NewProjectNamespace(2).Resource(rbac.ResourceRepository),
resource: rbac_project.NewNamespace(2).Resource(rbac.ResourceRepository),
action: rbac.ActionPush,
expect: true,
},
{
resource: rbac.NewProjectNamespace(2).Resource(rbac.ResourceRepository),
resource: rbac_project.NewNamespace(2).Resource(rbac.ResourceRepository),
action: rbac.ActionDelete,
expect: true,
},
{
resource: rbac.NewProjectNamespace(2).Resource(rbac.ResourceRepository),
resource: rbac_project.NewNamespace(2).Resource(rbac.ResourceRepository),
action: rbac.ActionScannerPull,
expect: false,
},
{
resource: rbac.NewProjectNamespace(3).Resource(rbac.ResourceRepository),
resource: rbac_project.NewNamespace(3).Resource(rbac.ResourceRepository),
action: rbac.ActionPush,
expect: false,
},
{
resource: rbac.NewProjectNamespace(2).Resource(rbac.ResourceArtifact),
resource: rbac_project.NewNamespace(2).Resource(rbac.ResourceArtifact),
action: rbac.ActionPush,
expect: false,
},
{
resource: rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository),
resource: rbac_project.NewNamespace(1).Resource(rbac.ResourceRepository),
action: rbac.ActionCreate,
expect: false,
},

View File

@ -3,7 +3,7 @@ package robot
import (
"context"
"fmt"
rbac_common "github.com/goharbor/harbor/src/common/rbac"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/core/config"
"github.com/goharbor/harbor/src/lib/errors"
@ -312,7 +312,7 @@ func (d *controller) convertScope(ctx context.Context, scope string) (kind, name
namespace = "*"
} else {
kind = LEVELPROJECT
ns, ok := rbac_common.ProjectNamespaceParse(types.Resource(scope))
ns, ok := rbac_project.NamespaceParse(types.Resource(scope))
if !ok {
log.Debugf("got no namespace from the resource %s", scope)
return "", "", errors.Errorf("got no namespace from the resource %s", scope)

View File

@ -24,6 +24,7 @@ import (
"github.com/goharbor/harbor/src/common/api"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/rbac"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"github.com/goharbor/harbor/src/common/security"
"github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/controller/p2p/preheat"
@ -84,7 +85,7 @@ func (b *BaseController) HasProjectPermission(projectIDOrName interface{}, actio
return false, err
}
resource := rbac.NewProjectNamespace(project.ProjectID).Resource(subresource...)
resource := rbac_project.NewNamespace(project.ProjectID).Resource(subresource...)
if !b.SecurityCtx.Can(b.Context(), action, resource) {
return false, nil
}

View File

@ -17,6 +17,7 @@ package token
import (
"context"
"fmt"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"net/http"
"net/url"
"strings"
@ -182,7 +183,7 @@ func (rep repositoryFilter) filter(ctx context.Context, ctl project.Controller,
return err
}
resource := rbac.NewProjectNamespace(project.ProjectID).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(project.ProjectID).Resource(rbac.ResourceRepository)
scopeList := make([]string, 0)
for s := range resourceScopes(ctx, resource) {
scopeList = append(scopeList, s)

View File

@ -19,6 +19,7 @@ import (
"crypto/x509"
"encoding/pem"
"fmt"
"github.com/goharbor/harbor/src/common/rbac/project"
"io/ioutil"
"net/url"
"os"
@ -302,10 +303,10 @@ func TestResourceScopes(t *testing.T) {
sctx := &fakeSecurityContext{
isAdmin: false,
rcActions: map[rbac.Resource][]rbac.Action{
rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository): {rbac.ActionPull, rbac.ActionScannerPull},
rbac.NewProjectNamespace(2).Resource(rbac.ResourceRepository): {rbac.ActionPull, rbac.ActionScannerPull, rbac.ActionPush},
rbac.NewProjectNamespace(3).Resource(rbac.ResourceRepository): {rbac.ActionPull, rbac.ActionScannerPull, rbac.ActionPush, rbac.ActionDelete},
rbac.NewProjectNamespace(4).Resource(rbac.ResourceRepository): {},
project.NewNamespace(1).Resource(rbac.ResourceRepository): {rbac.ActionPull, rbac.ActionScannerPull},
project.NewNamespace(2).Resource(rbac.ResourceRepository): {rbac.ActionPull, rbac.ActionScannerPull, rbac.ActionPush},
project.NewNamespace(3).Resource(rbac.ResourceRepository): {rbac.ActionPull, rbac.ActionScannerPull, rbac.ActionPush, rbac.ActionDelete},
project.NewNamespace(4).Resource(rbac.ResourceRepository): {},
},
}
ctx := security.NewContext(context.TODO(), sctx)
@ -314,14 +315,14 @@ func TestResourceScopes(t *testing.T) {
expect map[string]struct{}
}{
{
rc: rbac.NewProjectNamespace(1).Resource(rbac.ResourceRepository),
rc: project.NewNamespace(1).Resource(rbac.ResourceRepository),
expect: map[string]struct{}{
"pull": {},
"scanner-pull": {},
},
},
{
rc: rbac.NewProjectNamespace(2).Resource(rbac.ResourceRepository),
rc: project.NewNamespace(2).Resource(rbac.ResourceRepository),
expect: map[string]struct{}{
"pull": {},
"scanner-pull": {},
@ -329,7 +330,7 @@ func TestResourceScopes(t *testing.T) {
},
},
{
rc: rbac.NewProjectNamespace(3).Resource(rbac.ResourceRepository),
rc: project.NewNamespace(3).Resource(rbac.ResourceRepository),
expect: map[string]struct{}{
"pull": {},
"scanner-pull": {},
@ -338,11 +339,11 @@ func TestResourceScopes(t *testing.T) {
},
},
{
rc: rbac.NewProjectNamespace(4).Resource(rbac.ResourceRepository),
rc: project.NewNamespace(4).Resource(rbac.ResourceRepository),
expect: map[string]struct{}{},
},
{
rc: rbac.NewProjectNamespace(5).Resource(rbac.ResourceRepository),
rc: project.NewNamespace(5).Resource(rbac.ResourceRepository),
expect: map[string]struct{}{},
},
}

View File

@ -17,6 +17,7 @@ package util
import (
"context"
"fmt"
"github.com/goharbor/harbor/src/common/rbac/project"
"net/http"
"path"
"strings"
@ -61,7 +62,7 @@ func SkipPolicyChecking(ctx context.Context, projectID int64) bool {
// only scanner pull access can bypass.
if ok && secCtx.Name() == "v2token" &&
secCtx.Can(ctx, rbac.ActionScannerPull, rbac.NewProjectNamespace(projectID).Resource(rbac.ResourceRepository)) {
secCtx.Can(ctx, rbac.ActionScannerPull, project.NewNamespace(projectID).Resource(rbac.ResourceRepository)) {
return true
}

View File

@ -17,6 +17,7 @@ package v2auth
import (
"context"
"fmt"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"github.com/goharbor/harbor/src/common/rbac/system"
"net/http"
"net/url"
@ -67,7 +68,7 @@ func (rc *reqChecker) check(req *http.Request) (string, error) {
if err != nil {
return "", err
}
resource := rbac.NewProjectNamespace(pid).Resource(rbac.ResourceRepository)
resource := rbac_project.NewNamespace(pid).Resource(rbac.ResourceRepository)
if !securityCtx.Can(req.Context(), a.action, resource) {
return getChallenge(req, al), fmt.Errorf("unauthorized to access repository: %s, action: %s", a.name, a.action)
}

View File

@ -18,6 +18,7 @@ package handler
import (
"context"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"github.com/goharbor/harbor/src/common/rbac/system"
"net/http"
"net/url"
@ -86,7 +87,7 @@ func (b *BaseAPI) HasProjectPermission(ctx context.Context, projectIDOrName inte
projectID = p.ProjectID
}
resource := rbac.NewProjectNamespace(projectID).Resource(subresource...)
resource := rbac_project.NewNamespace(projectID).Resource(subresource...)
return b.HasPermission(ctx, action, resource)
}

View File

@ -3,6 +3,7 @@ package handler
import (
"context"
"fmt"
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
"regexp"
"strings"
@ -256,7 +257,7 @@ func (rAPI *robotV1API) validate(ctx context.Context, params operation.CreateRob
return err
}
policies := rbac.GetPoliciesOfProject(pro.ProjectID)
policies := rbac_project.GetPoliciesOfProject(pro.ProjectID)
mp := map[string]bool{}
for _, policy := range policies {