mirror of
https://github.com/goharbor/harbor.git
synced 2024-09-27 13:02:59 +02:00
bacfe64979
Signed-off-by: He Weiwei <hweiwei@vmware.com>
393 lines
8.3 KiB
Go
393 lines
8.3 KiB
Go
// 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 (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
type role struct {
|
|
RoleName string
|
|
}
|
|
|
|
func (r *role) GetRoleName() string {
|
|
return r.RoleName
|
|
}
|
|
|
|
func (r *role) GetPolicies() []*Policy {
|
|
return []*Policy{
|
|
{Resource: "/project", Action: "create"},
|
|
{Resource: "/project", Action: "update"},
|
|
}
|
|
}
|
|
|
|
type userWithRoles struct {
|
|
Username string
|
|
RoleName string
|
|
BaseUser
|
|
}
|
|
|
|
func (u *userWithRoles) GetUserName() string {
|
|
return u.Username
|
|
}
|
|
|
|
func (u *userWithRoles) GetRoles() []Role {
|
|
return []Role{
|
|
&role{RoleName: u.RoleName},
|
|
}
|
|
}
|
|
|
|
type userWithoutRoles struct {
|
|
Username string
|
|
UserPolicies []*Policy
|
|
BaseUser
|
|
}
|
|
|
|
func (u *userWithoutRoles) GetUserName() string {
|
|
return u.Username
|
|
}
|
|
|
|
func (u *userWithoutRoles) GetPolicies() []*Policy {
|
|
return u.UserPolicies
|
|
}
|
|
|
|
func TestHasPermissionUserWithRoles(t *testing.T) {
|
|
type args struct {
|
|
user User
|
|
resource Resource
|
|
action Action
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want bool
|
|
}{
|
|
{
|
|
name: "project create for project admin",
|
|
args: args{
|
|
&userWithRoles{Username: "project admin", RoleName: "projectAdmin"},
|
|
"/project",
|
|
"create",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "project update for project admin",
|
|
args: args{
|
|
&userWithRoles{Username: "project admin", RoleName: "projectAdmin"},
|
|
"/project",
|
|
"update",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "project delete for project admin",
|
|
args: args{
|
|
&userWithRoles{Username: "project admin", RoleName: "projectAdmin"},
|
|
"/project",
|
|
"delete",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := HasPermission(tt.args.user, tt.args.resource, tt.args.action); got != tt.want {
|
|
t.Errorf("HasPermission() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasPermissionUserWithoutRoles(t *testing.T) {
|
|
|
|
type args struct {
|
|
user User
|
|
resource Resource
|
|
action Action
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want bool
|
|
}{
|
|
{
|
|
name: "project create for user without roles",
|
|
args: args{
|
|
&userWithoutRoles{Username: "user1", UserPolicies: []*Policy{{Resource: "project", Action: "create"}}},
|
|
"/project",
|
|
"create",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "project delete test for user without roles",
|
|
args: args{
|
|
&userWithoutRoles{Username: "user1", UserPolicies: []*Policy{{Resource: "project", Action: "create"}}},
|
|
"/project",
|
|
"delete",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := HasPermission(tt.args.user, tt.args.resource, tt.args.action); got != tt.want {
|
|
t.Errorf("HasPermission() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasPermissionUsernameEmpty(t *testing.T) {
|
|
|
|
type args struct {
|
|
user User
|
|
resource Resource
|
|
action Action
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want bool
|
|
}{
|
|
{
|
|
name: "project create for user without roles",
|
|
args: args{
|
|
&userWithoutRoles{Username: "", UserPolicies: []*Policy{{Resource: "project", Action: "create"}}},
|
|
"/project",
|
|
"create",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := HasPermission(tt.args.user, tt.args.resource, tt.args.action); got != tt.want {
|
|
t.Errorf("HasPermission() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasPermissionRoleNameEmpty(t *testing.T) {
|
|
type args struct {
|
|
user User
|
|
resource Resource
|
|
action Action
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want bool
|
|
}{
|
|
{
|
|
name: "project create for project admin",
|
|
args: args{
|
|
&userWithRoles{Username: "project admin", RoleName: ""},
|
|
"/project",
|
|
"create",
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "project update for project admin",
|
|
args: args{
|
|
&userWithRoles{Username: "project admin", RoleName: ""},
|
|
"/project",
|
|
"update",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := HasPermission(tt.args.user, tt.args.resource, tt.args.action); got != tt.want {
|
|
t.Errorf("HasPermission() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasPermissionResourceKeyMatch(t *testing.T) {
|
|
|
|
type args struct {
|
|
user User
|
|
resource Resource
|
|
action Action
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want bool
|
|
}{
|
|
{
|
|
name: "project member create for resource key match",
|
|
args: args{
|
|
&userWithoutRoles{Username: "user1", UserPolicies: []*Policy{{Resource: "/project/1/*", Action: "*"}}},
|
|
"/project/1/member",
|
|
"create",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "project member create for resource key match",
|
|
args: args{
|
|
&userWithoutRoles{Username: "user1", UserPolicies: []*Policy{{Resource: "/project/:id/*", Action: "*"}}},
|
|
"/project/1/member",
|
|
"create",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "project repository create test for resource key match",
|
|
args: args{
|
|
&userWithoutRoles{Username: "user1", UserPolicies: []*Policy{{Resource: "/project/1/*", Action: "create"}}},
|
|
"/project/1/repository",
|
|
"create",
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "project repository delete test for resource key match",
|
|
args: args{
|
|
&userWithoutRoles{Username: "user1", UserPolicies: []*Policy{{Resource: "/project/1/*", Action: "create"}}},
|
|
"/project/1/repository",
|
|
"delete",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := HasPermission(tt.args.user, tt.args.resource, tt.args.action); got != tt.want {
|
|
t.Errorf("HasPermission() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHasPermissionPolicyDeny(t *testing.T) {
|
|
|
|
type args struct {
|
|
user User
|
|
resource Resource
|
|
action Action
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want bool
|
|
}{
|
|
{
|
|
name: "project member create for resource deny",
|
|
args: args{
|
|
&userWithoutRoles{
|
|
Username: "user1",
|
|
UserPolicies: []*Policy{
|
|
{Resource: "/project/1/*", Action: "*"},
|
|
{Resource: "/project/1/member", Action: "create", Effect: EffectDeny},
|
|
},
|
|
},
|
|
"/project/1/member",
|
|
"create",
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := HasPermission(tt.args.user, tt.args.resource, tt.args.action); got != tt.want {
|
|
t.Errorf("HasPermission() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResource_Subresource(t *testing.T) {
|
|
type args struct {
|
|
resources []Resource
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
res Resource
|
|
args args
|
|
want Resource
|
|
}{
|
|
{
|
|
name: "subresource image",
|
|
res: Resource("/project/1"),
|
|
args: args{
|
|
resources: []Resource{"image"},
|
|
},
|
|
want: Resource("/project/1/image"),
|
|
},
|
|
{
|
|
name: "subresource image build-history",
|
|
res: Resource("/project/1"),
|
|
args: args{
|
|
resources: []Resource{"image", "12", "build-history"},
|
|
},
|
|
want: Resource("/project/1/image/12/build-history"),
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := tt.res.Subresource(tt.args.resources...); got != tt.want {
|
|
t.Errorf("Resource.Subresource() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestResource_GetNamespace(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
res Resource
|
|
want Namespace
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "project namespace",
|
|
res: Resource("/project/1"),
|
|
want: &projectNamespace{int64(1), false},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "unknow namespace",
|
|
res: Resource("/unknow/1"),
|
|
want: nil,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := tt.res.GetNamespace()
|
|
if (err != nil) != tt.wantErr {
|
|
t.Errorf("Resource.GetNamespace() error = %v, wantErr %v", err, tt.wantErr)
|
|
return
|
|
}
|
|
if !reflect.DeepEqual(got, tt.want) {
|
|
t.Errorf("Resource.GetNamespace() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|