implement security context interface for database

This commit is contained in:
Wenkai Yin 2017-05-02 17:36:38 +08:00
parent 5699b258eb
commit ac7256efbd
3 changed files with 212 additions and 1 deletions

View File

@ -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)
}

View 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"))
}

View File

@ -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
}