mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 10:15:35 +01:00
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:
parent
64e61c0d11
commit
2d4456c630
@ -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 {
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
@ -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)
|
||||
}
|
368
src/common/rbac/project/rbac_role.go
Normal file
368
src/common/rbac/project/rbac_role.go
Normal 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
|
||||
}
|
@ -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})
|
@ -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),
|
@ -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
|
||||
}
|
@ -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
|
||||
})
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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{}{},
|
||||
},
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user