mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 02:35:17 +01:00
implement security context interface for database
This commit is contained in:
parent
5699b258eb
commit
ac7256efbd
@ -13,3 +13,76 @@
|
||||
// limitations under the License.
|
||||
|
||||
package db
|
||||
|
||||
import (
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/ui/pms"
|
||||
)
|
||||
|
||||
// SecurityContext implements security.Context interface based on database
|
||||
type SecurityContext struct {
|
||||
user *models.User
|
||||
pms pms.PMS
|
||||
}
|
||||
|
||||
// NewSecurityContext ...
|
||||
func NewSecurityContext(user *models.User, pms pms.PMS) *SecurityContext {
|
||||
return &SecurityContext{
|
||||
user: user,
|
||||
pms: pms,
|
||||
}
|
||||
}
|
||||
|
||||
// IsAuthenticated returns true if the user has been authenticated
|
||||
func (s *SecurityContext) IsAuthenticated() bool {
|
||||
return s.user != nil
|
||||
}
|
||||
|
||||
// GetUsername returns the username of the authenticated user
|
||||
// It returns null if the user has not been authenticated
|
||||
func (s *SecurityContext) GetUsername() string {
|
||||
if !s.IsAuthenticated() {
|
||||
return ""
|
||||
}
|
||||
return s.user.Username
|
||||
}
|
||||
|
||||
// IsSysAdmin returns whether the authenticated user is system admin
|
||||
// It returns false if the user has not been authenticated
|
||||
func (s *SecurityContext) IsSysAdmin() bool {
|
||||
if !s.IsAuthenticated() {
|
||||
return false
|
||||
}
|
||||
return s.user.HasAdminRole == 1
|
||||
}
|
||||
|
||||
// HasReadPerm returns whether the user has read permission to the project
|
||||
func (s *SecurityContext) HasReadPerm(projectIDOrName interface{}) bool {
|
||||
// public project
|
||||
if s.pms.IsPublic(projectIDOrName) {
|
||||
return true
|
||||
}
|
||||
|
||||
// private project
|
||||
if !s.IsAuthenticated() {
|
||||
return false
|
||||
}
|
||||
|
||||
return s.pms.HasReadPerm(s.GetUsername(), projectIDOrName)
|
||||
}
|
||||
|
||||
// HasWritePerm returns whether the user has write permission to the project
|
||||
func (s *SecurityContext) HasWritePerm(projectIDOrName interface{}) bool {
|
||||
if !s.IsAuthenticated() {
|
||||
return false
|
||||
}
|
||||
return s.pms.HasWritePerm(s.GetUsername(), projectIDOrName)
|
||||
}
|
||||
|
||||
// HasAllPerm returns whether the user has all permissions to the project
|
||||
func (s *SecurityContext) HasAllPerm(projectIDOrName interface{}) bool {
|
||||
if !s.IsAuthenticated() {
|
||||
return false
|
||||
}
|
||||
return s.pms.HasAllPerm(s.GetUsername(), projectIDOrName)
|
||||
}
|
||||
|
134
src/common/security/db/context_test.go
Normal file
134
src/common/security/db/context_test.go
Normal file
@ -0,0 +1,134 @@
|
||||
// Copyright (c) 2017 VMware, Inc. All Rights Reserved.
|
||||
//
|
||||
// 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 db
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
//"github.com/stretchr/testify/require"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
)
|
||||
|
||||
type fakePMS struct {
|
||||
public string
|
||||
}
|
||||
|
||||
func (f *fakePMS) IsPublic(projectIDOrName interface{}) bool {
|
||||
return f.public == projectIDOrName.(string)
|
||||
}
|
||||
func (f *fakePMS) HasReadPerm(username string, projectIDOrName interface{},
|
||||
token ...string) bool {
|
||||
return true
|
||||
}
|
||||
func (f *fakePMS) HasWritePerm(username string, projectIDOrName interface{},
|
||||
token ...string) bool {
|
||||
return true
|
||||
}
|
||||
func (f *fakePMS) HasAllPerm(username string, projectIDOrName interface{},
|
||||
token ...string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func TestIsAuthenticated(t *testing.T) {
|
||||
// unauthenticated
|
||||
ctx := NewSecurityContext(nil, nil)
|
||||
assert.False(t, ctx.IsAuthenticated())
|
||||
|
||||
// authenticated
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, nil)
|
||||
assert.True(t, ctx.IsAuthenticated())
|
||||
}
|
||||
|
||||
func TestGetUsername(t *testing.T) {
|
||||
// unauthenticated
|
||||
ctx := NewSecurityContext(nil, nil)
|
||||
assert.Equal(t, "", ctx.GetUsername())
|
||||
|
||||
// authenticated
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, nil)
|
||||
assert.Equal(t, "test", ctx.GetUsername())
|
||||
}
|
||||
|
||||
func TestIsSysAdmin(t *testing.T) {
|
||||
// unauthenticated
|
||||
ctx := NewSecurityContext(nil, nil)
|
||||
assert.False(t, ctx.IsSysAdmin())
|
||||
|
||||
// authenticated, non admin
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, nil)
|
||||
assert.False(t, ctx.IsSysAdmin())
|
||||
|
||||
// authenticated, admin
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
HasAdminRole: 1,
|
||||
}, nil)
|
||||
assert.True(t, ctx.IsSysAdmin())
|
||||
}
|
||||
|
||||
func TestHasReadPerm(t *testing.T) {
|
||||
pms := &fakePMS{
|
||||
public: "public_project",
|
||||
}
|
||||
|
||||
// public project, unauthenticated
|
||||
ctx := NewSecurityContext(nil, pms)
|
||||
assert.True(t, ctx.HasReadPerm("public_project"))
|
||||
|
||||
// private project, unauthenticated
|
||||
ctx = NewSecurityContext(nil, pms)
|
||||
assert.False(t, ctx.HasReadPerm("private_project"))
|
||||
|
||||
// private project, authenticated
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pms)
|
||||
assert.True(t, ctx.HasReadPerm("private_project"))
|
||||
}
|
||||
|
||||
func TestHasWritePerm(t *testing.T) {
|
||||
pms := &fakePMS{}
|
||||
|
||||
// unauthenticated
|
||||
ctx := NewSecurityContext(nil, pms)
|
||||
assert.False(t, ctx.HasWritePerm("project"))
|
||||
|
||||
// authenticated
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pms)
|
||||
assert.True(t, ctx.HasWritePerm("project"))
|
||||
}
|
||||
|
||||
func TestHasAllPerm(t *testing.T) {
|
||||
pms := &fakePMS{}
|
||||
|
||||
// unauthenticated
|
||||
ctx := NewSecurityContext(nil, pms)
|
||||
assert.False(t, ctx.HasAllPerm("project"))
|
||||
|
||||
// authenticated
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pms)
|
||||
assert.True(t, ctx.HasAllPerm("project"))
|
||||
}
|
@ -12,9 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package project
|
||||
package pms
|
||||
|
||||
// PMS is the project mamagement service which abstracts
|
||||
// the operations related to projects
|
||||
type PMS interface {
|
||||
IsPublic(projectIDOrName interface{}) bool
|
||||
HasReadPerm(username string, projectIDOrName interface{}, token ...string) bool
|
||||
HasWritePerm(username string, projectIDOrName interface{}, token ...string) bool
|
||||
HasAllPerm(username string, projectIDOrName interface{}, token ...string) bool
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user