From ae061482aef64f6f2c05c5ac616191d17f20dbb6 Mon Sep 17 00:00:00 2001 From: He Weiwei Date: Wed, 23 Jan 2019 14:32:37 +0800 Subject: [PATCH] Add Can method to securty.Context interface (#6779) * Add Can method to securty.Context interface Signed-off-by: He Weiwei * Improve mockSecurityContext Can method Signed-off-by: He Weiwei --- src/common/security/context.go | 3 ++ src/core/api/chart_repository_test.go | 48 +++++++++++++++------------ src/core/service/token/token_test.go | 4 +++ 3 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/common/security/context.go b/src/common/security/context.go index 7a6ea56f0..d1b9af92b 100644 --- a/src/common/security/context.go +++ b/src/common/security/context.go @@ -16,6 +16,7 @@ package security import ( "github.com/goharbor/harbor/src/common/models" + "github.com/goharbor/harbor/src/common/rbac" ) // Context abstracts the operations related with authN and authZ @@ -38,4 +39,6 @@ type Context interface { GetMyProjects() ([]*models.Project, error) // Get user's role in provided project GetProjectRoles(projectIDOrName interface{}) []int + // Can returns whether the user can do action on resource + Can(action rbac.Action, resource rbac.Resource) bool } diff --git a/src/core/api/chart_repository_test.go b/src/core/api/chart_repository_test.go index 030fa85a8..6d9be17b1 100644 --- a/src/core/api/chart_repository_test.go +++ b/src/core/api/chart_repository_test.go @@ -8,6 +8,8 @@ import ( "github.com/goharbor/harbor/src/chartserver" "github.com/goharbor/harbor/src/common/models" + "github.com/goharbor/harbor/src/common/rbac" + "github.com/goharbor/harbor/src/common/rbac/project" "github.com/goharbor/harbor/src/core/promgr/metamgr" ) @@ -311,32 +313,12 @@ func (msc *mockSecurityContext) IsSolutionUser() bool { // HasReadPerm returns whether the user has read permission to the project func (msc *mockSecurityContext) HasReadPerm(projectIDOrName interface{}) bool { - if projectIDOrName == nil { - return false - } - - if ns, ok := projectIDOrName.(string); ok { - if ns == "library" { - return true - } - } - - return false + return msc.Can(project.ActionPull, rbac.NewProjectNamespace(projectIDOrName, false).Resource(project.ResourceImage)) } // HasWritePerm returns whether the user has write permission to the project func (msc *mockSecurityContext) HasWritePerm(projectIDOrName interface{}) bool { - if projectIDOrName == nil { - return false - } - - if ns, ok := projectIDOrName.(string); ok { - if ns == "library" { - return true - } - } - - return false + return msc.Can(project.ActionPush, rbac.NewProjectNamespace(projectIDOrName, false).Resource(project.ResourceImage)) } // HasAllPerm returns whether the user has all permissions to the project @@ -344,6 +326,28 @@ func (msc *mockSecurityContext) HasAllPerm(projectIDOrName interface{}) bool { return msc.HasReadPerm(projectIDOrName) && msc.HasWritePerm(projectIDOrName) } +// Can returns whether the user can do action on resource +func (msc *mockSecurityContext) Can(action rbac.Action, resource rbac.Resource) bool { + namespace, err := resource.GetNamespace() + if err != nil || namespace.Kind() != "project" { + return false + } + + projectIDOrName := namespace.Identity() + + if projectIDOrName == nil { + return false + } + + if ns, ok := projectIDOrName.(string); ok { + if ns == "library" { + return true + } + } + + return false +} + // Get current user's all project func (msc *mockSecurityContext) GetMyProjects() ([]*models.Project, error) { return []*models.Project{{ProjectID: 0, Name: "library"}}, nil diff --git a/src/core/service/token/token_test.go b/src/core/service/token/token_test.go index 5c0ca8f18..3869eb105 100644 --- a/src/core/service/token/token_test.go +++ b/src/core/service/token/token_test.go @@ -30,6 +30,7 @@ import ( "testing" "github.com/goharbor/harbor/src/common/models" + "github.com/goharbor/harbor/src/common/rbac" "github.com/goharbor/harbor/src/common/utils/test" "github.com/goharbor/harbor/src/core/config" ) @@ -260,6 +261,9 @@ func (f *fakeSecurityContext) HasWritePerm(projectIDOrName interface{}) bool { func (f *fakeSecurityContext) HasAllPerm(projectIDOrName interface{}) bool { return false } +func (f *fakeSecurityContext) Can(action rbac.Action, resource rbac.Resource) bool { + return false +} func (f *fakeSecurityContext) GetMyProjects() ([]*models.Project, error) { return nil, nil }