mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-24 17:47:46 +01:00
Merge pull request #2713 from ywk253100/170704_pm
Move some method of project manager to security context
This commit is contained in:
commit
cbaf24fe81
@ -16,6 +16,7 @@ package admiral
|
||||
|
||||
import (
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/security/authcontext"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
"github.com/vmware/harbor/src/ui/projectmanager"
|
||||
@ -41,7 +42,7 @@ func (s *SecurityContext) IsAuthenticated() bool {
|
||||
if s.ctx == nil {
|
||||
return false
|
||||
}
|
||||
return len(s.ctx.GetUsername()) > 0
|
||||
return len(s.ctx.PrincipalID) > 0
|
||||
}
|
||||
|
||||
// GetUsername returns the username of the authenticated user
|
||||
@ -50,7 +51,7 @@ func (s *SecurityContext) GetUsername() string {
|
||||
if !s.IsAuthenticated() {
|
||||
return ""
|
||||
}
|
||||
return s.ctx.GetUsername()
|
||||
return s.ctx.PrincipalID
|
||||
}
|
||||
|
||||
// IsSysAdmin returns whether the authenticated user is system admin
|
||||
@ -59,12 +60,12 @@ func (s *SecurityContext) IsSysAdmin() bool {
|
||||
if !s.IsAuthenticated() {
|
||||
return false
|
||||
}
|
||||
|
||||
return s.ctx.IsSysAdmin()
|
||||
}
|
||||
|
||||
// HasReadPerm returns whether the user has read permission to the project
|
||||
func (s *SecurityContext) HasReadPerm(projectIDOrName interface{}) bool {
|
||||
// public project
|
||||
public, err := s.pm.IsPublic(projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to check the public of project %v: %v",
|
||||
@ -85,27 +86,9 @@ func (s *SecurityContext) HasReadPerm(projectIDOrName interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if name, ok := projectIDOrName.(string); ok {
|
||||
return s.ctx.HasReadPerm(name)
|
||||
}
|
||||
roles := s.GetProjectRoles(projectIDOrName)
|
||||
|
||||
roles, err := s.pm.GetRoles(s.GetUsername(), projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get roles of user %s to project %v: %v",
|
||||
s.GetUsername(), projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, role := range roles {
|
||||
switch role {
|
||||
case common.RoleProjectAdmin,
|
||||
common.RoleDeveloper,
|
||||
common.RoleGuest:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return len(roles) > 0
|
||||
}
|
||||
|
||||
// HasWritePerm returns whether the user has write permission to the project
|
||||
@ -119,17 +102,7 @@ func (s *SecurityContext) HasWritePerm(projectIDOrName interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if name, ok := projectIDOrName.(string); ok {
|
||||
return s.ctx.HasWritePerm(name)
|
||||
}
|
||||
|
||||
roles, err := s.pm.GetRoles(s.GetUsername(), projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get roles of user %s to project %v: %v",
|
||||
s.GetUsername(), projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
roles := s.GetProjectRoles(projectIDOrName)
|
||||
for _, role := range roles {
|
||||
switch role {
|
||||
case common.RoleProjectAdmin,
|
||||
@ -152,17 +125,7 @@ func (s *SecurityContext) HasAllPerm(projectIDOrName interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
if name, ok := projectIDOrName.(string); ok {
|
||||
return s.ctx.HasAllPerm(name)
|
||||
}
|
||||
|
||||
roles, err := s.pm.GetRoles(s.GetUsername(), projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get roles of user %s to project %v: %v",
|
||||
s.GetUsername(), projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
roles := s.GetProjectRoles(projectIDOrName)
|
||||
for _, role := range roles {
|
||||
switch role {
|
||||
case common.RoleProjectAdmin:
|
||||
@ -172,3 +135,17 @@ func (s *SecurityContext) HasAllPerm(projectIDOrName interface{}) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// GetMyProjects ...
|
||||
func (s *SecurityContext) GetMyProjects() ([]*models.Project, error) {
|
||||
return s.ctx.GetMyProjects(), nil
|
||||
}
|
||||
|
||||
// GetProjectRoles ...
|
||||
func (s *SecurityContext) GetProjectRoles(projectIDOrName interface{}) []int {
|
||||
if !s.IsAuthenticated() || projectIDOrName == nil {
|
||||
return []int{}
|
||||
}
|
||||
|
||||
return s.ctx.GetProjectRoles(projectIDOrName)
|
||||
}
|
||||
|
@ -21,9 +21,12 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
)
|
||||
|
||||
// TODO update the value of role when admiral API is ready
|
||||
const (
|
||||
// AuthTokenHeader is the key of auth token header
|
||||
AuthTokenHeader = "x-xenon-auth-token"
|
||||
@ -48,70 +51,83 @@ type AuthContext struct {
|
||||
Projects []*project `json:"projects"`
|
||||
}
|
||||
|
||||
// GetUsername ...
|
||||
func (a *AuthContext) GetUsername() string {
|
||||
return a.PrincipalID
|
||||
}
|
||||
|
||||
// IsSysAdmin ...
|
||||
func (a *AuthContext) IsSysAdmin() bool {
|
||||
isSysAdmin := false
|
||||
for _, role := range a.Roles {
|
||||
if role == sysAdminRole {
|
||||
isSysAdmin = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return isSysAdmin
|
||||
}
|
||||
|
||||
// HasReadPerm ...
|
||||
func (a *AuthContext) HasReadPerm(projectName string) bool {
|
||||
roles := a.getRoles(projectName)
|
||||
return len(roles) > 0
|
||||
}
|
||||
|
||||
// HasWritePerm ...
|
||||
func (a *AuthContext) HasWritePerm(projectName string) bool {
|
||||
roles := a.getRoles(projectName)
|
||||
for _, role := range roles {
|
||||
if role == projectAdminRole || role == developerRole {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HasAllPerm ...
|
||||
func (a *AuthContext) HasAllPerm(projectName string) bool {
|
||||
roles := a.getRoles(projectName)
|
||||
for _, role := range roles {
|
||||
if role == projectAdminRole {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
// GetProjectRoles ...
|
||||
func (a *AuthContext) GetProjectRoles(projectIDOrName interface{}) []int {
|
||||
var isID bool
|
||||
var id int64
|
||||
var name string
|
||||
|
||||
func (a *AuthContext) getRoles(projectName string) []string {
|
||||
id, isID = projectIDOrName.(int64)
|
||||
if !isID {
|
||||
name, _ = projectIDOrName.(string)
|
||||
}
|
||||
|
||||
roles := []string{}
|
||||
for _, project := range a.Projects {
|
||||
if project.Name == projectName {
|
||||
return project.Roles
|
||||
p := convertProject(project)
|
||||
if isID {
|
||||
if p.ProjectID == id {
|
||||
roles = append(roles, project.Roles...)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
if p.Name == name {
|
||||
roles = append(roles, project.Roles...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return []string{}
|
||||
return convertRoles(roles)
|
||||
}
|
||||
|
||||
// GetMyProjects returns all projects which the user is a member of
|
||||
func (a *AuthContext) GetMyProjects() []string {
|
||||
projects := []string{}
|
||||
func (a *AuthContext) GetMyProjects() []*models.Project {
|
||||
projects := []*models.Project{}
|
||||
for _, project := range a.Projects {
|
||||
projects = append(projects, project.Name)
|
||||
projects = append(projects, convertProject(project))
|
||||
}
|
||||
return projects
|
||||
}
|
||||
|
||||
// TODO populate harbor ID to the project
|
||||
// convert project returned by Admiral to project used in Harbor
|
||||
func convertProject(p *project) *models.Project {
|
||||
project := &models.Project{
|
||||
Name: p.Name,
|
||||
}
|
||||
return project
|
||||
}
|
||||
|
||||
// convert roles defined by Admiral to roles used in Harbor
|
||||
func convertRoles(roles []string) []int {
|
||||
list := []int{}
|
||||
for _, role := range roles {
|
||||
switch role {
|
||||
case projectAdminRole:
|
||||
list = append(list, common.RoleProjectAdmin)
|
||||
case developerRole:
|
||||
list = append(list, common.RoleDeveloper)
|
||||
case guestRole:
|
||||
list = append(list, common.RoleGuest)
|
||||
default:
|
||||
log.Warningf("unknow role: %s", role)
|
||||
}
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
// GetAuthCtx returns the auth context of the current user
|
||||
func GetAuthCtx(client *http.Client, url, token string) (*AuthContext, error) {
|
||||
return get(client, url, token)
|
||||
|
@ -14,4 +14,61 @@
|
||||
|
||||
package authcontext
|
||||
|
||||
// TODO add test cases
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsSysAdmin(t *testing.T) {
|
||||
// nil roles
|
||||
ctx := &AuthContext{}
|
||||
assert.False(t, ctx.IsSysAdmin())
|
||||
|
||||
// has no admin role
|
||||
ctx = &AuthContext{
|
||||
Roles: []string{projectAdminRole, developerRole, guestRole},
|
||||
}
|
||||
assert.False(t, ctx.IsSysAdmin())
|
||||
|
||||
// has admin role
|
||||
ctx = &AuthContext{
|
||||
Roles: []string{sysAdminRole},
|
||||
}
|
||||
assert.True(t, ctx.IsSysAdmin())
|
||||
}
|
||||
|
||||
func TestGetProjectRoles(t *testing.T) {
|
||||
ctx := &AuthContext{
|
||||
Projects: []*project{
|
||||
&project{
|
||||
Name: "project",
|
||||
Roles: []string{projectAdminRole, developerRole, guestRole},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// test with name
|
||||
roles := ctx.GetProjectRoles("project")
|
||||
assert.Equal(t, 3, len(roles))
|
||||
|
||||
// TODO add test case with ID
|
||||
}
|
||||
|
||||
func TestGetMyProjects(t *testing.T) {
|
||||
ctx := &AuthContext{
|
||||
Projects: []*project{
|
||||
&project{
|
||||
Name: "project1",
|
||||
Roles: []string{projectAdminRole},
|
||||
},
|
||||
&project{
|
||||
Name: "project2",
|
||||
Roles: []string{developerRole},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
projects := ctx.GetMyProjects()
|
||||
assert.Equal(t, 2, len(projects))
|
||||
}
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
package security
|
||||
|
||||
import (
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
)
|
||||
|
||||
// Context abstracts the operations related with authN and authZ
|
||||
type Context interface {
|
||||
// IsAuthenticated returns whether the context has been authenticated or not
|
||||
@ -28,4 +32,6 @@ type Context interface {
|
||||
HasWritePerm(projectIDOrName interface{}) bool
|
||||
// HasAllPerm returns whether the user has all permissions to the project
|
||||
HasAllPerm(projectIDOrName interface{}) bool
|
||||
GetMyProjects() ([]*models.Project, error)
|
||||
GetProjectRoles(projectIDOrName interface{}) []int
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ package local
|
||||
|
||||
import (
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
"github.com/vmware/harbor/src/ui/projectmanager"
|
||||
@ -60,18 +61,6 @@ func (s *SecurityContext) IsSysAdmin() bool {
|
||||
|
||||
// HasReadPerm returns whether the user has read permission to the project
|
||||
func (s *SecurityContext) HasReadPerm(projectIDOrName interface{}) bool {
|
||||
// not exist
|
||||
exist, err := s.pm.Exist(projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to check the existence of project %v: %v",
|
||||
projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if !exist {
|
||||
return false
|
||||
}
|
||||
|
||||
// public project
|
||||
public, err := s.pm.IsPublic(projectIDOrName)
|
||||
if err != nil {
|
||||
@ -93,23 +82,9 @@ func (s *SecurityContext) HasReadPerm(projectIDOrName interface{}) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
roles, err := s.pm.GetRoles(s.GetUsername(), projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get roles of user %s to project %v: %v",
|
||||
s.GetUsername(), projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
roles := s.GetProjectRoles(projectIDOrName)
|
||||
|
||||
for _, role := range roles {
|
||||
switch role {
|
||||
case common.RoleProjectAdmin,
|
||||
common.RoleDeveloper,
|
||||
common.RoleGuest:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return len(roles) > 0
|
||||
}
|
||||
|
||||
// HasWritePerm returns whether the user has write permission to the project
|
||||
@ -118,30 +93,12 @@ func (s *SecurityContext) HasWritePerm(projectIDOrName interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// project does not exist
|
||||
exist, err := s.pm.Exist(projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to check the existence of project %v: %v",
|
||||
projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if !exist {
|
||||
return false
|
||||
}
|
||||
|
||||
// system admin
|
||||
if s.IsSysAdmin() {
|
||||
return true
|
||||
}
|
||||
|
||||
roles, err := s.pm.GetRoles(s.GetUsername(), projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get roles of user %s to project %v: %v",
|
||||
s.GetUsername(), projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
roles := s.GetProjectRoles(projectIDOrName)
|
||||
for _, role := range roles {
|
||||
switch role {
|
||||
case common.RoleProjectAdmin,
|
||||
@ -159,30 +116,12 @@ func (s *SecurityContext) HasAllPerm(projectIDOrName interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// project does not exist
|
||||
exist, err := s.pm.Exist(projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to check the existence of project %v: %v",
|
||||
projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if !exist {
|
||||
return false
|
||||
}
|
||||
|
||||
// system admin
|
||||
if s.IsSysAdmin() {
|
||||
return true
|
||||
}
|
||||
|
||||
roles, err := s.pm.GetRoles(s.GetUsername(), projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get roles of user %s to project %v: %v",
|
||||
s.GetUsername(), projectIDOrName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
roles := s.GetProjectRoles(projectIDOrName)
|
||||
for _, role := range roles {
|
||||
switch role {
|
||||
case common.RoleProjectAdmin:
|
||||
@ -192,3 +131,61 @@ func (s *SecurityContext) HasAllPerm(projectIDOrName interface{}) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// GetMyProjects ...
|
||||
func (s *SecurityContext) GetMyProjects() ([]*models.Project, error) {
|
||||
return dao.GetProjects(&models.ProjectQueryParam{
|
||||
Member: &models.MemberQuery{
|
||||
Name: s.GetUsername(),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// GetProjectRoles ...
|
||||
func (s *SecurityContext) GetProjectRoles(projectIDOrName interface{}) []int {
|
||||
if !s.IsAuthenticated() || projectIDOrName == nil {
|
||||
return []int{}
|
||||
}
|
||||
|
||||
roles := []int{}
|
||||
user, err := dao.GetUser(models.User{
|
||||
Username: s.GetUsername(),
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to get user %s: %v", s.GetUsername(), err)
|
||||
return roles
|
||||
}
|
||||
if user == nil {
|
||||
log.Debugf("user %s not found", s.GetUsername())
|
||||
return roles
|
||||
}
|
||||
|
||||
project, err := s.pm.Get(projectIDOrName)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get project %v: %v", projectIDOrName, err)
|
||||
return roles
|
||||
}
|
||||
if project == nil {
|
||||
log.Errorf("project %v not found", projectIDOrName)
|
||||
return roles
|
||||
}
|
||||
|
||||
roleList, err := dao.GetUserProjectRoles(user.UserID, project.ProjectID)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get roles of user %d to project %d: %v", user.UserID, project.ProjectID, err)
|
||||
return roles
|
||||
}
|
||||
|
||||
for _, role := range roleList {
|
||||
switch role.RoleCode {
|
||||
case "MDRWS":
|
||||
roles = append(roles, common.RoleProjectAdmin)
|
||||
case "RWS":
|
||||
roles = append(roles, common.RoleDeveloper)
|
||||
case "RS":
|
||||
roles = append(roles, common.RoleGuest)
|
||||
}
|
||||
}
|
||||
|
||||
return roles
|
||||
}
|
||||
|
@ -15,109 +15,132 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
"github.com/vmware/harbor/src/ui/projectmanager/db"
|
||||
)
|
||||
|
||||
var (
|
||||
public = &models.Project{
|
||||
Name: "public_project",
|
||||
Public: 1,
|
||||
}
|
||||
|
||||
private = &models.Project{
|
||||
Name: "private_project",
|
||||
Public: 0,
|
||||
Name: "private_project",
|
||||
OwnerID: 1,
|
||||
}
|
||||
|
||||
read = &models.Project{
|
||||
Name: "has_read_perm_project",
|
||||
projectAdminUser = &models.User{
|
||||
Username: "projectAdminUser",
|
||||
Email: "projectAdminUser@vmware.com",
|
||||
}
|
||||
developerUser = &models.User{
|
||||
Username: "developerUser",
|
||||
Email: "developerUser@vmware.com",
|
||||
}
|
||||
guestUser = &models.User{
|
||||
Username: "guestUser",
|
||||
Email: "guestUser@vmware.com",
|
||||
}
|
||||
|
||||
write = &models.Project{
|
||||
Name: "has_write_perm_project",
|
||||
}
|
||||
|
||||
all = &models.Project{
|
||||
Name: "has_all_perm_project",
|
||||
}
|
||||
pm = &db.ProjectManager{}
|
||||
)
|
||||
|
||||
type fakePM struct {
|
||||
projects []*models.Project
|
||||
roles map[string][]int
|
||||
}
|
||||
|
||||
func (f *fakePM) IsPublic(projectIDOrName interface{}) (bool, error) {
|
||||
for _, project := range f.projects {
|
||||
if project.Name == projectIDOrName.(string) {
|
||||
return project.Public == 1, nil
|
||||
}
|
||||
func TestMain(m *testing.M) {
|
||||
dbHost := os.Getenv("MYSQL_HOST")
|
||||
if len(dbHost) == 0 {
|
||||
log.Fatalf("environment variable MYSQL_HOST is not set")
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
func (f *fakePM) GetRoles(username string, projectIDOrName interface{}) ([]int, error) {
|
||||
return f.roles[projectIDOrName.(string)], nil
|
||||
}
|
||||
func (f *fakePM) Get(projectIDOrName interface{}) (*models.Project, error) {
|
||||
for _, project := range f.projects {
|
||||
if project.Name == projectIDOrName.(string) {
|
||||
return project, nil
|
||||
}
|
||||
dbPortStr := os.Getenv("MYSQL_PORT")
|
||||
if len(dbPortStr) == 0 {
|
||||
log.Fatalf("environment variable MYSQL_PORT is not set")
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fakePM) Exist(projectIDOrName interface{}) (bool, error) {
|
||||
for _, project := range f.projects {
|
||||
if project.Name == projectIDOrName.(string) {
|
||||
return true, nil
|
||||
}
|
||||
dbPort, err := strconv.Atoi(dbPortStr)
|
||||
if err != nil {
|
||||
log.Fatalf("invalid MYSQL_PORT: %v", err)
|
||||
}
|
||||
dbUser := os.Getenv("MYSQL_USR")
|
||||
if len(dbUser) == 0 {
|
||||
log.Fatalf("environment variable MYSQL_USR is not set")
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// nil implement
|
||||
func (f *fakePM) GetPublic() ([]*models.Project, error) {
|
||||
return []*models.Project{}, nil
|
||||
}
|
||||
dbPassword := os.Getenv("MYSQL_PWD")
|
||||
dbDatabase := os.Getenv("MYSQL_DATABASE")
|
||||
if len(dbDatabase) == 0 {
|
||||
log.Fatalf("environment variable MYSQL_DATABASE is not set")
|
||||
}
|
||||
|
||||
// nil implement
|
||||
func (f *fakePM) GetByMember(username string) ([]*models.Project, error) {
|
||||
return []*models.Project{}, nil
|
||||
}
|
||||
database := &models.Database{
|
||||
Type: "mysql",
|
||||
MySQL: &models.MySQL{
|
||||
Host: dbHost,
|
||||
Port: dbPort,
|
||||
Username: dbUser,
|
||||
Password: dbPassword,
|
||||
Database: dbDatabase,
|
||||
},
|
||||
}
|
||||
|
||||
// nil implement
|
||||
func (f *fakePM) Create(*models.Project) (int64, error) {
|
||||
return 0, fmt.Errorf("not support")
|
||||
}
|
||||
log.Infof("MYSQL_HOST: %s, MYSQL_USR: %s, MYSQL_PORT: %d, MYSQL_PWD: %s\n", dbHost, dbUser, dbPort, dbPassword)
|
||||
|
||||
// nil implement
|
||||
func (f *fakePM) Delete(projectIDOrName interface{}) error {
|
||||
return fmt.Errorf("not support")
|
||||
}
|
||||
if err := dao.InitDatabase(database); err != nil {
|
||||
log.Fatalf("failed to initialize database: %v", err)
|
||||
}
|
||||
|
||||
// nil implement
|
||||
func (f *fakePM) Update(projectIDOrName interface{}, project *models.Project) error {
|
||||
return fmt.Errorf("not support")
|
||||
}
|
||||
// regiser users
|
||||
id, err := dao.Register(*projectAdminUser)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to register user: %v", err)
|
||||
}
|
||||
projectAdminUser.UserID = int(id)
|
||||
defer dao.DeleteUser(int(id))
|
||||
|
||||
// nil implement
|
||||
func (f *fakePM) GetAll(*models.ProjectQueryParam, ...*models.BaseProjectCollection) ([]*models.Project, error) {
|
||||
return []*models.Project{}, nil
|
||||
}
|
||||
id, err = dao.Register(*developerUser)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to register user: %v", err)
|
||||
}
|
||||
developerUser.UserID = int(id)
|
||||
defer dao.DeleteUser(int(id))
|
||||
|
||||
// nil implement
|
||||
func (f *fakePM) GetHasReadPerm(username ...string) ([]*models.Project, error) {
|
||||
return []*models.Project{}, nil
|
||||
}
|
||||
id, err = dao.Register(*guestUser)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to register user: %v", err)
|
||||
}
|
||||
guestUser.UserID = int(id)
|
||||
defer dao.DeleteUser(int(id))
|
||||
|
||||
// nil implement
|
||||
func (f *fakePM) GetTotal(*models.ProjectQueryParam, ...*models.BaseProjectCollection) (int64, error) {
|
||||
return 0, nil
|
||||
// add project
|
||||
id, err = dao.AddProject(*private)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to add project: %v", err)
|
||||
}
|
||||
private.ProjectID = id
|
||||
defer dao.DeleteProject(id)
|
||||
|
||||
// add project members
|
||||
err = dao.AddProjectMember(private.ProjectID, projectAdminUser.UserID, common.RoleProjectAdmin)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to add member: %v", err)
|
||||
}
|
||||
defer dao.DeleteProjectMember(private.ProjectID, projectAdminUser.UserID)
|
||||
|
||||
err = dao.AddProjectMember(private.ProjectID, developerUser.UserID, common.RoleDeveloper)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to add member: %v", err)
|
||||
}
|
||||
defer dao.DeleteProjectMember(private.ProjectID, developerUser.UserID)
|
||||
|
||||
err = dao.AddProjectMember(private.ProjectID, guestUser.UserID, common.RoleGuest)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to add member: %v", err)
|
||||
}
|
||||
defer dao.DeleteProjectMember(private.ProjectID, guestUser.UserID)
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
func TestIsAuthenticated(t *testing.T) {
|
||||
@ -164,147 +187,104 @@ func TestIsSysAdmin(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestHasReadPerm(t *testing.T) {
|
||||
pm := &fakePM{
|
||||
projects: []*models.Project{public, private, read},
|
||||
roles: map[string][]int{
|
||||
"has_read_perm_project": []int{common.RoleGuest},
|
||||
},
|
||||
}
|
||||
|
||||
// non-exist project
|
||||
ctx := NewSecurityContext(nil, pm)
|
||||
assert.False(t, ctx.HasReadPerm("non_exist_project"))
|
||||
|
||||
// public project
|
||||
ctx = NewSecurityContext(nil, pm)
|
||||
assert.True(t, ctx.HasReadPerm("public_project"))
|
||||
ctx := NewSecurityContext(nil, pm)
|
||||
assert.True(t, ctx.HasReadPerm("library"))
|
||||
|
||||
// private project, unauthenticated
|
||||
ctx = NewSecurityContext(nil, pm)
|
||||
assert.False(t, ctx.HasReadPerm("private_project"))
|
||||
assert.False(t, ctx.HasReadPerm(private.Name))
|
||||
|
||||
// private project, authenticated, has no perm
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasReadPerm("private_project"))
|
||||
assert.False(t, ctx.HasReadPerm(private.Name))
|
||||
|
||||
// private project, authenticated, has read perm
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.True(t, ctx.HasReadPerm("has_read_perm_project"))
|
||||
ctx = NewSecurityContext(guestUser, pm)
|
||||
assert.True(t, ctx.HasReadPerm(private.Name))
|
||||
|
||||
// private project, authenticated, system admin
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
Username: "admin",
|
||||
HasAdminRole: 1,
|
||||
}, pm)
|
||||
assert.True(t, ctx.HasReadPerm("private_project"))
|
||||
|
||||
// non-exist project, authenticated, system admin
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
HasAdminRole: 1,
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasReadPerm("non_exist_project"))
|
||||
assert.True(t, ctx.HasReadPerm(private.Name))
|
||||
}
|
||||
|
||||
func TestHasWritePerm(t *testing.T) {
|
||||
pm := &fakePM{
|
||||
projects: []*models.Project{read, write, private},
|
||||
roles: map[string][]int{
|
||||
"has_read_perm_project": []int{common.RoleGuest},
|
||||
"has_write_perm_project": []int{common.RoleGuest, common.RoleDeveloper},
|
||||
},
|
||||
}
|
||||
|
||||
// unauthenticated
|
||||
ctx := NewSecurityContext(nil, pm)
|
||||
assert.False(t, ctx.HasWritePerm("has_write_perm_project"))
|
||||
|
||||
// authenticated, non-exist project
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasWritePerm("non_exist_project"))
|
||||
assert.False(t, ctx.HasWritePerm(private.Name))
|
||||
|
||||
// authenticated, has read perm
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasWritePerm("has_read_perm_project")) // authenticated, has read perm
|
||||
ctx = NewSecurityContext(guestUser, pm)
|
||||
assert.False(t, ctx.HasWritePerm(private.Name))
|
||||
|
||||
// authenticated, has write perm
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.True(t, ctx.HasWritePerm("has_write_perm_project"))
|
||||
ctx = NewSecurityContext(developerUser, pm)
|
||||
assert.True(t, ctx.HasWritePerm(private.Name))
|
||||
|
||||
// authenticated, system admin
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
Username: "admin",
|
||||
HasAdminRole: 1,
|
||||
}, pm)
|
||||
assert.True(t, ctx.HasReadPerm("private_project"))
|
||||
|
||||
// authenticated, system admin, non-exist project
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
HasAdminRole: 1,
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasReadPerm("non_exist_project"))
|
||||
assert.True(t, ctx.HasReadPerm(private.Name))
|
||||
}
|
||||
|
||||
func TestHasAllPerm(t *testing.T) {
|
||||
pm := &fakePM{
|
||||
projects: []*models.Project{read, write, all, private},
|
||||
roles: map[string][]int{
|
||||
"has_read_perm_project": []int{common.RoleGuest},
|
||||
"has_write_perm_project": []int{common.RoleGuest, common.RoleDeveloper},
|
||||
"has_all_perm_project": []int{common.RoleGuest, common.RoleDeveloper, common.RoleProjectAdmin},
|
||||
},
|
||||
}
|
||||
|
||||
// unauthenticated
|
||||
ctx := NewSecurityContext(nil, pm)
|
||||
assert.False(t, ctx.HasAllPerm("has_all_perm_project"))
|
||||
|
||||
// authenticated, non-exist project
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasAllPerm("non_exist_project"))
|
||||
|
||||
// authenticated, has read perm
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasAllPerm("has_read_perm_project"))
|
||||
|
||||
// authenticated, has write perm
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasAllPerm("has_write_perm_project"))
|
||||
assert.False(t, ctx.HasAllPerm(private.Name))
|
||||
|
||||
// authenticated, has all perms
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
}, pm)
|
||||
assert.True(t, ctx.HasAllPerm("has_all_perm_project"))
|
||||
ctx = NewSecurityContext(projectAdminUser, pm)
|
||||
assert.True(t, ctx.HasAllPerm(private.Name))
|
||||
|
||||
// authenticated, system admin
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
Username: "admin",
|
||||
HasAdminRole: 1,
|
||||
}, pm)
|
||||
assert.True(t, ctx.HasAllPerm("private_project"))
|
||||
|
||||
// authenticated, system admin, non-exist project
|
||||
ctx = NewSecurityContext(&models.User{
|
||||
Username: "test",
|
||||
HasAdminRole: 1,
|
||||
}, pm)
|
||||
assert.False(t, ctx.HasAllPerm("non_exist_project"))
|
||||
assert.True(t, ctx.HasAllPerm(private.Name))
|
||||
}
|
||||
|
||||
func TestGetMyProjects(t *testing.T) {
|
||||
ctx := NewSecurityContext(guestUser, pm)
|
||||
projects, err := ctx.GetMyProjects()
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, 1, len(projects))
|
||||
assert.Equal(t, private.ProjectID, projects[0].ProjectID)
|
||||
}
|
||||
|
||||
func TestGetProjectRoles(t *testing.T) {
|
||||
// unauthenticated
|
||||
ctx := NewSecurityContext(nil, pm)
|
||||
roles := ctx.GetProjectRoles(private.Name)
|
||||
assert.Equal(t, 0, len(roles))
|
||||
|
||||
// authenticated, project name of ID is nil
|
||||
ctx = NewSecurityContext(guestUser, pm)
|
||||
roles = ctx.GetProjectRoles(nil)
|
||||
assert.Equal(t, 0, len(roles))
|
||||
|
||||
// authenticated, has read perm
|
||||
ctx = NewSecurityContext(guestUser, pm)
|
||||
roles = ctx.GetProjectRoles(private.Name)
|
||||
assert.Equal(t, 1, len(roles))
|
||||
assert.Equal(t, common.RoleGuest, roles[0])
|
||||
|
||||
// authenticated, has write perm
|
||||
ctx = NewSecurityContext(developerUser, pm)
|
||||
roles = ctx.GetProjectRoles(private.Name)
|
||||
assert.Equal(t, 1, len(roles))
|
||||
assert.Equal(t, common.RoleDeveloper, roles[0])
|
||||
|
||||
// authenticated, has all perms
|
||||
ctx = NewSecurityContext(projectAdminUser, pm)
|
||||
roles = ctx.GetProjectRoles(private.Name)
|
||||
assert.Equal(t, 1, len(roles))
|
||||
assert.Equal(t, common.RoleProjectAdmin, roles[0])
|
||||
}
|
||||
|
@ -15,6 +15,10 @@
|
||||
package secret
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/secret"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
)
|
||||
@ -79,3 +83,17 @@ func (s *SecurityContext) HasWritePerm(projectIDOrName interface{}) bool {
|
||||
func (s *SecurityContext) HasAllPerm(projectIDOrName interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// GetMyProjects ...
|
||||
func (s *SecurityContext) GetMyProjects() ([]*models.Project, error) {
|
||||
return nil, fmt.Errorf("GetMyProjects is unsupported")
|
||||
}
|
||||
|
||||
// GetProjectRoles return guest role if has read permission, otherwise return nil
|
||||
func (s *SecurityContext) GetProjectRoles(projectIDOrName interface{}) []int {
|
||||
roles := []int{}
|
||||
if s.HasReadPerm(projectIDOrName) {
|
||||
roles = append(roles, common.RoleGuest)
|
||||
}
|
||||
return roles
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/secret"
|
||||
)
|
||||
|
||||
@ -132,3 +133,34 @@ func TestHasAllPerm(t *testing.T) {
|
||||
hasAllPerm = context.HasAllPerm(1)
|
||||
assert.False(t, hasAllPerm)
|
||||
}
|
||||
|
||||
func TestGetMyProjects(t *testing.T) {
|
||||
context := NewSecurityContext("secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"secret": "username",
|
||||
}))
|
||||
|
||||
_, err := context.GetMyProjects()
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestGetProjectRoles(t *testing.T) {
|
||||
//invalid secret
|
||||
context := NewSecurityContext("invalid_secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"jobservice_secret": secret.JobserviceUser,
|
||||
}))
|
||||
|
||||
roles := context.GetProjectRoles("any_project")
|
||||
assert.Equal(t, 0, len(roles))
|
||||
|
||||
// valid secret
|
||||
context = NewSecurityContext("jobservice_secret",
|
||||
secret.NewStore(map[string]string{
|
||||
"jobservice_secret": secret.JobserviceUser,
|
||||
}))
|
||||
|
||||
roles = context.GetProjectRoles("any_project")
|
||||
assert.Equal(t, 1, len(roles))
|
||||
assert.Equal(t, common.RoleGuest, roles[0])
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ func (l *LogAPI) Get() {
|
||||
}
|
||||
|
||||
if !l.isSysAdmin {
|
||||
projects, err := l.ProjectMgr.GetByMember(l.username)
|
||||
projects, err := l.SecurityCtx.GetMyProjects()
|
||||
if err != nil {
|
||||
l.HandleInternalServerError(fmt.Sprintf(
|
||||
"failed to get projects of user %s: %v", l.username, err))
|
||||
|
@ -311,13 +311,7 @@ func (p *ProjectAPI) List() {
|
||||
|
||||
for _, project := range projects {
|
||||
if p.SecurityCtx.IsAuthenticated() {
|
||||
roles, err := p.ProjectMgr.GetRoles(p.SecurityCtx.GetUsername(), project.ProjectID)
|
||||
if err != nil {
|
||||
p.HandleInternalServerError(fmt.Sprintf("failed to get roles of user %s to project %d: %v",
|
||||
p.SecurityCtx.GetUsername(), project.ProjectID, err))
|
||||
return
|
||||
}
|
||||
|
||||
roles := p.SecurityCtx.GetProjectRoles(project.ProjectID)
|
||||
if len(roles) != 0 {
|
||||
project.Role = roles[0]
|
||||
}
|
||||
|
@ -608,7 +608,7 @@ func (ra *RepositoryAPI) GetTopRepos() {
|
||||
return
|
||||
}
|
||||
if ra.SecurityCtx.IsAuthenticated() {
|
||||
list, err := ra.ProjectMgr.GetByMember(ra.SecurityCtx.GetUsername())
|
||||
list, err := ra.SecurityCtx.GetMyProjects()
|
||||
if err != nil {
|
||||
ra.HandleInternalServerError(fmt.Sprintf("failed to get projects which the user %s is a member of: %v",
|
||||
ra.SecurityCtx.GetUsername(), err))
|
||||
|
@ -43,23 +43,43 @@ type searchResult struct {
|
||||
func (s *SearchAPI) Get() {
|
||||
keyword := s.GetString("q")
|
||||
isAuthenticated := s.SecurityCtx.IsAuthenticated()
|
||||
username := s.SecurityCtx.GetUsername()
|
||||
isSysAdmin := s.SecurityCtx.IsSysAdmin()
|
||||
|
||||
var projects []*models.Project
|
||||
var err error
|
||||
|
||||
if !isAuthenticated {
|
||||
projects, err = s.ProjectMgr.GetPublic()
|
||||
} else if isSysAdmin {
|
||||
if isSysAdmin {
|
||||
projects, err = s.ProjectMgr.GetAll(nil)
|
||||
if err != nil {
|
||||
s.HandleInternalServerError(fmt.Sprintf(
|
||||
"failed to get projects: %v", err))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
projects, err = s.ProjectMgr.GetHasReadPerm(username)
|
||||
}
|
||||
if err != nil {
|
||||
s.HandleInternalServerError(fmt.Sprintf(
|
||||
"failed to get projects: %v", err))
|
||||
return
|
||||
projects, err = s.ProjectMgr.GetPublic()
|
||||
if err != nil {
|
||||
s.HandleInternalServerError(fmt.Sprintf(
|
||||
"failed to get projects: %v", err))
|
||||
return
|
||||
}
|
||||
if isAuthenticated {
|
||||
mys, err := s.SecurityCtx.GetMyProjects()
|
||||
if err != nil {
|
||||
s.HandleInternalServerError(fmt.Sprintf(
|
||||
"failed to get projects: %v", err))
|
||||
return
|
||||
}
|
||||
exist := map[int64]bool{}
|
||||
for _, p := range projects {
|
||||
exist[p.ProjectID] = true
|
||||
}
|
||||
|
||||
for _, p := range mys {
|
||||
if !exist[p.ProjectID] {
|
||||
projects = append(projects, p)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
projectSorter := &models.ProjectSorter{Projects: projects}
|
||||
@ -71,13 +91,7 @@ func (s *SearchAPI) Get() {
|
||||
}
|
||||
|
||||
if isAuthenticated {
|
||||
roles, err := s.ProjectMgr.GetRoles(username, p.ProjectID)
|
||||
if err != nil {
|
||||
s.HandleInternalServerError(fmt.Sprintf("failed to get roles of user %s to project %d: %v",
|
||||
username, p.ProjectID, err))
|
||||
return
|
||||
}
|
||||
|
||||
roles := s.SecurityCtx.GetProjectRoles(p.ProjectID)
|
||||
if len(roles) != 0 {
|
||||
p.Role = roles[0]
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
)
|
||||
@ -62,48 +61,6 @@ func (p *ProjectManager) IsPublic(projectIDOrName interface{}) (bool, error) {
|
||||
return project.Public == 1, nil
|
||||
}
|
||||
|
||||
// GetRoles return a role list which contains the user's roles to the project
|
||||
func (p *ProjectManager) GetRoles(username string, projectIDOrName interface{}) ([]int, error) {
|
||||
roles := []int{}
|
||||
|
||||
user, err := dao.GetUser(models.User{
|
||||
Username: username,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get user %s: %v",
|
||||
username, err)
|
||||
}
|
||||
if user == nil {
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
project, err := p.Get(projectIDOrName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if project == nil {
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
roleList, err := dao.GetUserProjectRoles(user.UserID, project.ProjectID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, role := range roleList {
|
||||
switch role.RoleCode {
|
||||
case "MDRWS":
|
||||
roles = append(roles, common.RoleProjectAdmin)
|
||||
case "RWS":
|
||||
roles = append(roles, common.RoleDeveloper)
|
||||
case "RS":
|
||||
roles = append(roles, common.RoleGuest)
|
||||
}
|
||||
}
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
// GetPublic returns all public projects
|
||||
func (p *ProjectManager) GetPublic() ([]*models.Project, error) {
|
||||
t := true
|
||||
@ -112,20 +69,6 @@ func (p *ProjectManager) GetPublic() ([]*models.Project, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// GetByMember returns all projects which the user is a member of
|
||||
func (p *ProjectManager) GetByMember(username string) (
|
||||
[]*models.Project, error) {
|
||||
if len(username) == 0 {
|
||||
return []*models.Project{}, nil
|
||||
}
|
||||
|
||||
return p.GetAll(&models.ProjectQueryParam{
|
||||
Member: &models.MemberQuery{
|
||||
Name: username,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Create ...
|
||||
func (p *ProjectManager) Create(project *models.Project) (int64, error) {
|
||||
if project == nil {
|
||||
@ -204,13 +147,3 @@ func (p *ProjectManager) GetTotal(query *models.ProjectQueryParam, base ...*mode
|
||||
int64, error) {
|
||||
return dao.GetTotalOfProjects(query, base...)
|
||||
}
|
||||
|
||||
// GetHasReadPerm returns projects which are public or the user is a member of
|
||||
func (p *ProjectManager) GetHasReadPerm(username ...string) (
|
||||
[]*models.Project, error) {
|
||||
if len(username) == 0 || len(username[0]) == 0 {
|
||||
return p.GetPublic()
|
||||
}
|
||||
|
||||
return dao.GetHasReadPermProjects(username[0])
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/dao"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
@ -121,25 +120,6 @@ func TestIsPublic(t *testing.T) {
|
||||
assert.False(t, public)
|
||||
}
|
||||
|
||||
func TestGetRoles(t *testing.T) {
|
||||
pm := &ProjectManager{}
|
||||
|
||||
// non exist user
|
||||
roles, err := pm.GetRoles("non_exist_user", int64(1))
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []int{}, roles)
|
||||
|
||||
// exist project
|
||||
roles, err = pm.GetRoles("admin", "library")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []int{common.RoleProjectAdmin}, roles)
|
||||
|
||||
// non-exist project
|
||||
roles, err = pm.GetRoles("admin", "non_exist_project")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, []int{}, roles)
|
||||
}
|
||||
|
||||
func TestGetPublic(t *testing.T) {
|
||||
pm := &ProjectManager{}
|
||||
projects, err := pm.GetPublic()
|
||||
@ -151,19 +131,6 @@ func TestGetPublic(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetByMember(t *testing.T) {
|
||||
pm := &ProjectManager{}
|
||||
// empty username
|
||||
projects, err := pm.GetByMember("")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 0, len(projects))
|
||||
|
||||
//non-empty username
|
||||
projects, err = pm.GetByMember("admin")
|
||||
assert.Nil(t, err)
|
||||
assert.NotEqual(t, 0, len(projects))
|
||||
}
|
||||
|
||||
func TestCreateAndDelete(t *testing.T) {
|
||||
pm := &ProjectManager{}
|
||||
|
||||
@ -304,58 +271,3 @@ func TestGetAll(t *testing.T) {
|
||||
}
|
||||
assert.True(t, exist)
|
||||
}
|
||||
|
||||
func TestGetHasReadPerm(t *testing.T) {
|
||||
pm := &ProjectManager{}
|
||||
|
||||
// do not pass username
|
||||
projects, err := pm.GetHasReadPerm()
|
||||
assert.Nil(t, err)
|
||||
assert.NotEqual(t, 0, len(projects))
|
||||
exist := false
|
||||
for _, project := range projects {
|
||||
if project.ProjectID == 1 {
|
||||
exist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.True(t, exist)
|
||||
|
||||
// username is nil
|
||||
projects, err = pm.GetHasReadPerm("")
|
||||
assert.Nil(t, err)
|
||||
assert.NotEqual(t, 0, len(projects))
|
||||
exist = false
|
||||
for _, project := range projects {
|
||||
if project.ProjectID == 1 {
|
||||
exist = true
|
||||
break
|
||||
}
|
||||
}
|
||||
assert.True(t, exist)
|
||||
|
||||
// valid username
|
||||
id, err := pm.Create(&models.Project{
|
||||
Name: "get_has_read_perm_test",
|
||||
OwnerID: 1,
|
||||
Public: 0,
|
||||
})
|
||||
assert.Nil(t, err)
|
||||
defer pm.Delete(id)
|
||||
|
||||
projects, err = pm.GetHasReadPerm("admin")
|
||||
assert.Nil(t, err)
|
||||
assert.NotEqual(t, 0, len(projects))
|
||||
exist1 := false
|
||||
exist2 := false
|
||||
for _, project := range projects {
|
||||
if project.ProjectID == 1 {
|
||||
exist1 = true
|
||||
}
|
||||
if project.ProjectID == id {
|
||||
exist2 = true
|
||||
}
|
||||
}
|
||||
assert.True(t, exist1)
|
||||
assert.True(t, exist2)
|
||||
}
|
||||
|
@ -24,11 +24,8 @@ type ProjectManager interface {
|
||||
Get(projectIDOrName interface{}) (*models.Project, error)
|
||||
IsPublic(projectIDOrName interface{}) (bool, error)
|
||||
Exist(projectIDOrName interface{}) (bool, error)
|
||||
GetRoles(username string, projectIDOrName interface{}) ([]int, error)
|
||||
// get all public project
|
||||
GetPublic() ([]*models.Project, error)
|
||||
// get projects which the user is a member of
|
||||
GetByMember(username string) ([]*models.Project, error)
|
||||
Create(*models.Project) (int64, error)
|
||||
Delete(projectIDOrName interface{}) error
|
||||
Update(projectIDOrName interface{}, project *models.Project) error
|
||||
@ -36,8 +33,4 @@ type ProjectManager interface {
|
||||
GetAll(query *models.ProjectQueryParam, base ...*models.BaseProjectCollection) ([]*models.Project, error)
|
||||
// GetTotal returns the total count according to the query parameters
|
||||
GetTotal(query *models.ProjectQueryParam, base ...*models.BaseProjectCollection) (int64, error)
|
||||
// GetHasReadPerm returns a project list which the user has read
|
||||
// permission of. The list should contains all public projects and
|
||||
// projects which the user is a member of if the username is not nil
|
||||
GetHasReadPerm(username ...string) ([]*models.Project, error)
|
||||
}
|
||||
|
@ -25,9 +25,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/vmware/harbor/src/common"
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/security/authcontext"
|
||||
er "github.com/vmware/harbor/src/common/utils/error"
|
||||
"github.com/vmware/harbor/src/common/utils/log"
|
||||
)
|
||||
@ -227,6 +225,7 @@ func (p *ProjectManager) Exist(projectIDOrName interface{}) (bool, error) {
|
||||
return project != nil, nil
|
||||
}
|
||||
|
||||
/*
|
||||
// GetRoles gets roles that the user has to the project
|
||||
// This method is used in GET /projects API.
|
||||
// Jobservice calls GET /projects API to get information of source
|
||||
@ -279,6 +278,7 @@ func (p *ProjectManager) GetRoles(username string, projectIDOrName interface{})
|
||||
|
||||
return roles, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (p *ProjectManager) getIDbyHarborIDOrName(projectIDOrName interface{}) (string, error) {
|
||||
pro, err := p.get(projectIDOrName)
|
||||
@ -301,26 +301,6 @@ func (p *ProjectManager) GetPublic() ([]*models.Project, error) {
|
||||
})
|
||||
}
|
||||
|
||||
// GetByMember ...
|
||||
func (p *ProjectManager) GetByMember(username string) ([]*models.Project, error) {
|
||||
projects := []*models.Project{}
|
||||
ctx, err := authcontext.GetAuthCtxOfUser(p.client, p.endpoint, p.getToken(), username)
|
||||
if err != nil {
|
||||
return projects, err
|
||||
}
|
||||
|
||||
names := ctx.GetMyProjects()
|
||||
for _, name := range names {
|
||||
project, err := p.Get(name)
|
||||
if err != nil {
|
||||
return projects, err
|
||||
}
|
||||
projects = append(projects, project)
|
||||
}
|
||||
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
// Create ...
|
||||
func (p *ProjectManager) Create(pro *models.Project) (int64, error) {
|
||||
proj := &project{
|
||||
@ -407,11 +387,6 @@ func (p *ProjectManager) GetTotal(query *models.ProjectQueryParam, base ...*mode
|
||||
return int64(len(projects)), err
|
||||
}
|
||||
|
||||
// GetHasReadPerm ...
|
||||
func (p *ProjectManager) GetHasReadPerm(username ...string) ([]*models.Project, error) {
|
||||
return nil, errors.New("GetHasReadPerm is unsupported")
|
||||
}
|
||||
|
||||
func (p *ProjectManager) send(method, path string, body io.Reader) ([]byte, error) {
|
||||
req, err := http.NewRequest(method, p.endpoint+path, body)
|
||||
if err != nil {
|
||||
|
@ -292,33 +292,6 @@ func TestExist(t *testing.T) {
|
||||
assert.True(t, exist)
|
||||
}
|
||||
|
||||
func TestGetRoles(t *testing.T) {
|
||||
pm := NewProjectManager(client, endpoint, tokenReader)
|
||||
|
||||
// nil username, nil project
|
||||
roles, err := pm.GetRoles("", nil)
|
||||
assert.Nil(t, err)
|
||||
assert.Zero(t, len(roles))
|
||||
|
||||
// non-exist project
|
||||
_, err = pm.GetRoles("user01", "non_exist_project")
|
||||
assert.NotNil(t, err)
|
||||
|
||||
// exist project
|
||||
name := "project_for_test_get_roles"
|
||||
id, err := pm.Create(&models.Project{
|
||||
Name: name,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
defer delete(t, id)
|
||||
|
||||
roles, err = pm.GetRoles("user01", id)
|
||||
assert.Nil(t, err)
|
||||
assert.Zero(t, len(roles))
|
||||
|
||||
// TODO add test cases for real role of user
|
||||
}
|
||||
|
||||
func TestGetPublic(t *testing.T) {
|
||||
pm := NewProjectManager(client, endpoint, tokenReader)
|
||||
|
||||
@ -348,11 +321,6 @@ func TestGetPublic(t *testing.T) {
|
||||
assert.True(t, found)
|
||||
}
|
||||
|
||||
// TODO add test case
|
||||
func TestGetByMember(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
pm := NewProjectManager(client, endpoint, tokenReader)
|
||||
|
||||
@ -492,12 +460,6 @@ func TestGetTotal(t *testing.T) {
|
||||
assert.Equal(t, total1+1, total2)
|
||||
}
|
||||
|
||||
func TestGetHasReadPerm(t *testing.T) {
|
||||
pm := NewProjectManager(client, endpoint, tokenReader)
|
||||
_, err := pm.GetHasReadPerm()
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func delete(t *testing.T, id int64) {
|
||||
pm := NewProjectManager(client, endpoint, tokenReader)
|
||||
if err := pm.Delete(id); err != nil {
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/vmware/harbor/src/common/models"
|
||||
"github.com/vmware/harbor/src/common/utils/test"
|
||||
"github.com/vmware/harbor/src/ui/config"
|
||||
)
|
||||
@ -225,6 +226,12 @@ func (f *fakeSecurityContext) HasWritePerm(projectIDOrName interface{}) bool {
|
||||
func (f *fakeSecurityContext) HasAllPerm(projectIDOrName interface{}) bool {
|
||||
return false
|
||||
}
|
||||
func (f *fakeSecurityContext) GetMyProjects() ([]*models.Project, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *fakeSecurityContext) GetProjectRoles(interface{}) []int {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestFilterAccess(t *testing.T) {
|
||||
//TODO put initial data in DB to verify repository filter.
|
||||
|
Loading…
Reference in New Issue
Block a user