mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-26 12:15:20 +01:00
Refactor project member
This commit is contained in:
parent
a813edbe2c
commit
f138067242
@ -82,19 +82,19 @@ insert into project (owner_id, name, creation_time, update_time) values
|
|||||||
(1, 'library', NOW(), NOW());
|
(1, 'library', NOW(), NOW());
|
||||||
|
|
||||||
create table project_member (
|
create table project_member (
|
||||||
|
id int not null AUTO_INCREMENT,
|
||||||
project_id int NOT NULL,
|
project_id int NOT NULL,
|
||||||
user_id int NOT NULL,
|
entity_id int NOT NULL,
|
||||||
|
entity_type char NOT NULL, ## u for user, g for user group
|
||||||
role int NOT NULL,
|
role int NOT NULL,
|
||||||
creation_time timestamp,
|
creation_time timestamp default CURRENT_TIMESTAMP,
|
||||||
update_time timestamp,
|
update_time timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (project_id, user_id),
|
PRIMARY KEY (id),
|
||||||
FOREIGN KEY (role) REFERENCES role(role_id),
|
CONSTRAINT unique_project_entity_type UNIQUE (project_id, entity_id, entity_type)
|
||||||
FOREIGN KEY (project_id) REFERENCES project(project_id),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES user(user_id)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
insert into project_member (project_id, user_id, role, creation_time, update_time) values
|
insert into project_member (project_id, entity_id, role, entity_type) values
|
||||||
(1, 1, 1, NOW(), NOW());
|
(1, 1, 1, 'u');
|
||||||
|
|
||||||
create table project_metadata (
|
create table project_metadata (
|
||||||
id int NOT NULL AUTO_INCREMENT,
|
id int NOT NULL AUTO_INCREMENT,
|
||||||
@ -112,6 +112,19 @@ create table project_metadata (
|
|||||||
insert into project_metadata (id, project_id, name, value, creation_time, update_time, deleted) values
|
insert into project_metadata (id, project_id, name, value, creation_time, update_time, deleted) values
|
||||||
(1, 1, 'public', 'true', NOW(), NOW(), 0);
|
(1, 1, 'public', 'true', NOW(), NOW(), 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
create table user_group
|
||||||
|
(
|
||||||
|
id int NOT NULL AUTO_INCREMENT,
|
||||||
|
group_name varchar(255) NOT NULL,
|
||||||
|
group_type int default 0,
|
||||||
|
group_property varchar(512) NOT NULL,
|
||||||
|
creation_time timestamp default CURRENT_TIMESTAMP,
|
||||||
|
update_time timestamp default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
create table access_log (
|
create table access_log (
|
||||||
log_id int NOT NULL AUTO_INCREMENT,
|
log_id int NOT NULL AUTO_INCREMENT,
|
||||||
username varchar (255) NOT NULL,
|
username varchar (255) NOT NULL,
|
||||||
|
@ -60,6 +60,15 @@ insert into user (username, email, password, realname, comment, deleted, sysadmi
|
|||||||
('admin', 'admin@example.com', '', 'system admin', 'admin user',0, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
('admin', 'admin@example.com', '', 'system admin', 'admin user',0, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
||||||
('anonymous', 'anonymous@example.com', '', 'anonymous user', 'anonymous user', 1, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
('anonymous', 'anonymous@example.com', '', 'anonymous user', 'anonymous user', 1, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||||
|
|
||||||
|
create table user_group (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
group_name varchar(255) NOT NULL,
|
||||||
|
group_type int default 0,
|
||||||
|
group_property varchar(512) NOT NULL,
|
||||||
|
creation_time timestamp default CURRENT_TIMESTAMP,
|
||||||
|
update_time timestamp default CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
create table project (
|
create table project (
|
||||||
project_id INTEGER PRIMARY KEY,
|
project_id INTEGER PRIMARY KEY,
|
||||||
owner_id int NOT NULL,
|
owner_id int NOT NULL,
|
||||||
@ -78,20 +87,21 @@ create table project (
|
|||||||
insert into project (owner_id, name, creation_time, update_time) values
|
insert into project (owner_id, name, creation_time, update_time) values
|
||||||
(1, 'library', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
(1, 'library', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
create table project_member (
|
create table project_member (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
project_id int NOT NULL,
|
project_id int NOT NULL,
|
||||||
user_id int NOT NULL,
|
entity_id int NOT NULL,
|
||||||
|
entity_type char NOT NULL,
|
||||||
role int NOT NULL,
|
role int NOT NULL,
|
||||||
creation_time timestamp,
|
creation_time timestamp default CURRENT_TIMESTAMP,
|
||||||
update_time timestamp,
|
update_time timestamp default CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (project_id, user_id),
|
UNIQUE (project_id, entity_id, entity_type)
|
||||||
FOREIGN KEY (role) REFERENCES role(role_id),
|
|
||||||
FOREIGN KEY (project_id) REFERENCES project(project_id),
|
|
||||||
FOREIGN KEY (user_id) REFERENCES user(user_id)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
insert into project_member (project_id, user_id, role, creation_time, update_time) values
|
insert into project_member (project_id, entity_id, role, entity_type) values
|
||||||
(1, 1, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
|
(1, 1, 1, 'u');
|
||||||
|
|
||||||
create table project_metadata (
|
create table project_metadata (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
@ -235,3 +245,4 @@ create table alembic_version (
|
|||||||
);
|
);
|
||||||
|
|
||||||
insert into alembic_version values ('1.4.0');
|
insert into alembic_version values ('1.4.0');
|
||||||
|
|
||||||
|
@ -84,4 +84,6 @@ const (
|
|||||||
CfgDriverJSON = "json"
|
CfgDriverJSON = "json"
|
||||||
NewHarborAdminName = "admin@harbor.local"
|
NewHarborAdminName = "admin@harbor.local"
|
||||||
RegistryStorageProviderName = "registry_storage_provider_name"
|
RegistryStorageProviderName = "registry_storage_provider_name"
|
||||||
|
UserMember = "u"
|
||||||
|
GroupMember = "g"
|
||||||
)
|
)
|
||||||
|
@ -133,7 +133,8 @@ func paginateForRawSQL(sql string, limit, offset int64) string {
|
|||||||
return fmt.Sprintf("%s limit %d offset %d", sql, limit, offset)
|
return fmt.Sprintf("%s limit %d offset %d", sql, limit, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
func escape(str string) string {
|
//Escape ..
|
||||||
|
func Escape(str string) string {
|
||||||
str = strings.Replace(str, `%`, `\%`, -1)
|
str = strings.Replace(str, `%`, `\%`, -1)
|
||||||
str = strings.Replace(str, `_`, `\_`, -1)
|
str = strings.Replace(str, `_`, `\_`, -1)
|
||||||
return str
|
return str
|
||||||
|
@ -49,7 +49,7 @@ func cleanByUser(username string) {
|
|||||||
|
|
||||||
err = execUpdate(o, `delete
|
err = execUpdate(o, `delete
|
||||||
from project_member
|
from project_member
|
||||||
where user_id = (
|
where entity_id = (
|
||||||
select user_id
|
select user_id
|
||||||
from user
|
from user
|
||||||
where username = ?
|
where username = ?
|
||||||
@ -661,7 +661,7 @@ func TestGetUserByProject(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetUserProjectRoles(t *testing.T) {
|
func TestGetUserProjectRoles(t *testing.T) {
|
||||||
r, err := GetUserProjectRoles(currentUser.UserID, currentProject.ProjectID)
|
r, err := GetUserProjectRoles(currentUser.UserID, currentProject.ProjectID, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error happened in GetUserProjectRole: %v, userID: %+v, project Id: %d", err, currentUser.UserID, currentProject.ProjectID)
|
t.Errorf("Error happened in GetUserProjectRole: %v, userID: %+v, project Id: %d", err, currentUser.UserID, currentProject.ProjectID)
|
||||||
}
|
}
|
||||||
@ -701,12 +701,19 @@ func TestGetProjects(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAddProjectMember(t *testing.T) {
|
func TestAddProjectMember(t *testing.T) {
|
||||||
err := AddProjectMember(currentProject.ProjectID, 1, models.DEVELOPER)
|
pmid, err := AddProjectMember(currentProject.ProjectID, 1, models.DEVELOPER, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error occurred in AddProjectMember: %v", err)
|
t.Errorf("Error occurred in AddProjectMember: %v", err)
|
||||||
}
|
}
|
||||||
|
if pmid == 0 {
|
||||||
|
t.Errorf("Error add project member, pmid=0")
|
||||||
|
}
|
||||||
|
pmid, err = AddProjectMember(currentProject.ProjectID, 1, models.DEVELOPER, "randomstring")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Should failed on adding project member when adding duplicated items")
|
||||||
|
}
|
||||||
|
|
||||||
roles, err := GetUserProjectRoles(1, currentProject.ProjectID)
|
roles, err := GetUserProjectRoles(1, currentProject.ProjectID, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
|
t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
|
||||||
}
|
}
|
||||||
@ -725,11 +732,11 @@ func TestAddProjectMember(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateProjectMember(t *testing.T) {
|
func TestUpdateProjectMember(t *testing.T) {
|
||||||
err := UpdateProjectMember(currentProject.ProjectID, 1, models.GUEST)
|
err := UpdateProjectMember(currentProject.ProjectID, 1, models.GUEST, "randomstring")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error occurred in UpdateProjectMember: %v", err)
|
t.Errorf("Error occurred in UpdateProjectMember: %v", err)
|
||||||
}
|
}
|
||||||
roles, err := GetUserProjectRoles(1, currentProject.ProjectID)
|
roles, err := GetUserProjectRoles(1, currentProject.ProjectID, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
|
t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
|
||||||
}
|
}
|
||||||
@ -740,12 +747,12 @@ func TestUpdateProjectMember(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteProjectMember(t *testing.T) {
|
func TestDeleteProjectMember(t *testing.T) {
|
||||||
err := DeleteProjectMember(currentProject.ProjectID, 1)
|
err := DeleteProjectMember(currentProject.ProjectID, 1, "randomstring")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error occurred in DeleteProjectMember: %v", err)
|
t.Errorf("Error occurred in DeleteProjectMember: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
roles, err := GetUserProjectRoles(1, currentProject.ProjectID)
|
roles, err := GetUserProjectRoles(1, currentProject.ProjectID, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
|
t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
//"github.com/vmware/harbor/src/common/utils/log"
|
//"github.com/vmware/harbor/src/common/utils/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,7 +45,10 @@ func AddProject(project models.Project) (int64, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = AddProjectMember(projectID, project.OwnerID, models.PROJECTADMIN)
|
pmID, err := AddProjectMember(projectID, project.OwnerID, models.PROJECTADMIN, common.UserMember)
|
||||||
|
if pmID == 0 {
|
||||||
|
return projectID, fmt.Errorf("Failed to add project member, pmid=0")
|
||||||
|
}
|
||||||
return projectID, err
|
return projectID, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +148,7 @@ func projectQueryConditions(query *models.ProjectQueryParam) (string, []interfac
|
|||||||
sql += ` join project_member pm
|
sql += ` join project_member pm
|
||||||
on p.project_id = pm.project_id
|
on p.project_id = pm.project_id
|
||||||
join user u2
|
join user u2
|
||||||
on pm.user_id=u2.user_id`
|
on pm.entity_id=u2.user_id`
|
||||||
}
|
}
|
||||||
sql += ` where p.deleted=0`
|
sql += ` where p.deleted=0`
|
||||||
|
|
||||||
@ -157,7 +159,7 @@ func projectQueryConditions(query *models.ProjectQueryParam) (string, []interfac
|
|||||||
|
|
||||||
if len(query.Name) != 0 {
|
if len(query.Name) != 0 {
|
||||||
sql += ` and p.name like ?`
|
sql += ` and p.name like ?`
|
||||||
params = append(params, "%"+escape(query.Name)+"%")
|
params = append(params, "%"+Escape(query.Name)+"%")
|
||||||
}
|
}
|
||||||
|
|
||||||
if query.Member != nil && len(query.Member.Name) != 0 {
|
if query.Member != nil && len(query.Member.Name) != 0 {
|
||||||
|
@ -15,25 +15,39 @@
|
|||||||
package dao
|
package dao
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/vmware/harbor/src/common"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddProjectMember inserts a record to table project_member
|
// AddProjectMember inserts a record to table project_member
|
||||||
func AddProjectMember(projectID int64, userID int, role int) error {
|
func AddProjectMember(projectID int64, userID int, role int, entityType string) (int, error) {
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
|
if !(entityType == common.UserMember || entityType == common.GroupMember) {
|
||||||
|
entityType = common.UserMember
|
||||||
|
}
|
||||||
|
sql := `insert into project_member (project_id, entity_id , role, entity_type) values (?, ?, ?, ?)`
|
||||||
|
_, err := o.Raw(sql, projectID, userID, role, entityType).Exec()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var pmid int
|
||||||
|
querySQL := `select id from project_member where project_id = ? and entity_id = ? and entity_type = ? limit 1`
|
||||||
|
|
||||||
sql := "insert into project_member (project_id, user_id , role) values (?, ?, ?)"
|
err = o.Raw(querySQL, projectID, userID, entityType).QueryRow(&pmid)
|
||||||
|
if err != nil {
|
||||||
_, err := o.Raw(sql, projectID, userID, role).Exec()
|
return 0, err
|
||||||
|
}
|
||||||
return err
|
return pmid, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateProjectMember updates the record in table project_member
|
// UpdateProjectMember updates the record in table project_member
|
||||||
func UpdateProjectMember(projectID int64, userID int, role int) error {
|
func UpdateProjectMember(projectID int64, userID int, role int, entityType string) error {
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
|
if !(entityType == common.UserMember || entityType == common.GroupMember) {
|
||||||
|
entityType = common.UserMember
|
||||||
|
}
|
||||||
|
|
||||||
sql := "update project_member set role = ? where project_id = ? and user_id = ?"
|
sql := `update project_member set role = ? where project_id = ? and entity_id = ?`
|
||||||
|
|
||||||
_, err := o.Raw(sql, role, projectID, userID).Exec()
|
_, err := o.Raw(sql, role, projectID, userID).Exec()
|
||||||
|
|
||||||
@ -41,12 +55,16 @@ func UpdateProjectMember(projectID int64, userID int, role int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DeleteProjectMember delete the record from table project_member
|
// DeleteProjectMember delete the record from table project_member
|
||||||
func DeleteProjectMember(projectID int64, userID int) error {
|
func DeleteProjectMember(projectID int64, userID int, entityType string) error {
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
|
|
||||||
sql := "delete from project_member where project_id = ? and user_id = ?"
|
if !(entityType == common.UserMember || entityType == common.GroupMember) {
|
||||||
|
entityType = common.UserMember
|
||||||
|
}
|
||||||
|
|
||||||
if _, err := o.Raw(sql, projectID, userID).Exec(); err != nil {
|
sql := `delete from project_member where project_id = ? and entity_id = ? and entity_type = ?`
|
||||||
|
|
||||||
|
if _, err := o.Raw(sql, projectID, userID, entityType).Exec(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,27 +72,23 @@ func DeleteProjectMember(projectID int64, userID int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetUserByProject gets all members of the project.
|
// GetUserByProject gets all members of the project.
|
||||||
func GetUserByProject(projectID int64, queryUser models.User) ([]*models.Member, error) {
|
func GetUserByProject(projectID int64, queryUser models.User) ([]*models.UserMember, error) {
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
sql := `select u.user_id, u.username, u.creation_time, u.update_time, r.name as rolename,
|
sql := `select pm.id as id, u.user_id, u.username, u.creation_time, u.update_time, r.name as rolename,
|
||||||
r.role_id as role
|
r.role_id as role, pm.entity_type as entity_type from user u join project_member pm
|
||||||
from user u
|
on pm.project_id = ? and u.user_id = pm.entity_id
|
||||||
join project_member pm
|
join role r on pm.role = r.role_id where u.deleted = 0 and pm.entity_type = 'u' `
|
||||||
on pm.project_id = ? and u.user_id = pm.user_id
|
|
||||||
join role r
|
|
||||||
on pm.role = r.role_id
|
|
||||||
where u.deleted = 0`
|
|
||||||
|
|
||||||
queryParam := make([]interface{}, 1)
|
queryParam := make([]interface{}, 1)
|
||||||
queryParam = append(queryParam, projectID)
|
queryParam = append(queryParam, projectID)
|
||||||
|
|
||||||
if queryUser.Username != "" {
|
if len(queryUser.Username) != 0 {
|
||||||
sql += " and u.username like ? "
|
sql += ` and u.username like ? `
|
||||||
queryParam = append(queryParam, "%"+escape(queryUser.Username)+"%")
|
queryParam = append(queryParam, `%`+Escape(queryUser.Username)+`%`)
|
||||||
}
|
}
|
||||||
sql += ` order by u.username `
|
sql += ` order by u.username `
|
||||||
|
|
||||||
members := []*models.Member{}
|
members := []*models.UserMember{}
|
||||||
_, err := o.Raw(sql, queryParam).QueryRows(&members)
|
_, err := o.Raw(sql, queryParam).QueryRows(&members)
|
||||||
|
|
||||||
return members, err
|
return members, err
|
||||||
|
@ -90,7 +90,7 @@ func FilterRepTargets(name string) ([]*models.RepTarget, error) {
|
|||||||
sql := `select * from replication_target `
|
sql := `select * from replication_target `
|
||||||
if len(name) != 0 {
|
if len(name) != 0 {
|
||||||
sql += `where name like ? `
|
sql += `where name like ? `
|
||||||
args = append(args, "%"+escape(name)+"%")
|
args = append(args, `%`+Escape(name)+`%`)
|
||||||
}
|
}
|
||||||
sql += `order by creation_time`
|
sql += `order by creation_time`
|
||||||
|
|
||||||
@ -173,11 +173,11 @@ func FilterRepPolicies(name string, projectID, page, pageSize int64) ([]*models.
|
|||||||
|
|
||||||
if len(name) != 0 && projectID != 0 {
|
if len(name) != 0 && projectID != 0 {
|
||||||
sql += `and rp.name like ? and rp.project_id = ? `
|
sql += `and rp.name like ? and rp.project_id = ? `
|
||||||
args = append(args, "%"+escape(name)+"%")
|
args = append(args, `%`+Escape(name)+`%`)
|
||||||
args = append(args, projectID)
|
args = append(args, projectID)
|
||||||
} else if len(name) != 0 {
|
} else if len(name) != 0 {
|
||||||
sql += `and rp.name like ? `
|
sql += `and rp.name like ? `
|
||||||
args = append(args, "%"+escape(name)+"%")
|
args = append(args, `%`+Escape(name)+`%`)
|
||||||
} else if projectID != 0 {
|
} else if projectID != 0 {
|
||||||
sql += `and rp.project_id = ? `
|
sql += `and rp.project_id = ? `
|
||||||
args = append(args, projectID)
|
args = append(args, projectID)
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// GetUserProjectRoles returns roles that the user has according to the project.
|
// GetUserProjectRoles returns roles that the user has according to the project.
|
||||||
func GetUserProjectRoles(userID int, projectID int64) ([]models.Role, error) {
|
func GetUserProjectRoles(userID int, projectID int64, entityType string) ([]models.Role, error) {
|
||||||
|
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ func GetUserProjectRoles(userID int, projectID int64) ([]models.Role, error) {
|
|||||||
(
|
(
|
||||||
select role
|
select role
|
||||||
from project_member
|
from project_member
|
||||||
where project_id = ? and user_id = ?
|
where project_id = ? and entity_id = ? and entity_type = 'u'
|
||||||
)`
|
)`
|
||||||
|
|
||||||
var roleList []models.Role
|
var roleList []models.Role
|
||||||
|
@ -16,6 +16,17 @@ package models
|
|||||||
|
|
||||||
// Member holds the details of a member.
|
// Member holds the details of a member.
|
||||||
type Member struct {
|
type Member struct {
|
||||||
|
ID int `orm:"pk;column(id)" json:"id"`
|
||||||
|
ProjectID int64 `orm:"column(project_id)" json:"project_id"`
|
||||||
|
Entityname string `orm:"column(entity_name)" json:"entity_name"`
|
||||||
|
Rolename string `json:"role_name"`
|
||||||
|
Role int `json:"role_id"`
|
||||||
|
EntityID int `orm:"column(entity_id)" json:"entity_id"`
|
||||||
|
EntityType string `orm:"column(entity_type)" json:"entity_type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserMember ...
|
||||||
|
type UserMember struct {
|
||||||
ID int `orm:"pk;column(user_id)" json:"user_id"`
|
ID int `orm:"pk;column(user_id)" json:"user_id"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Rolename string `json:"role_name"`
|
Rolename string `json:"role_name"`
|
||||||
|
@ -175,7 +175,7 @@ func (s *SecurityContext) GetProjectRoles(projectIDOrName interface{}) []int {
|
|||||||
return roles
|
return roles
|
||||||
}
|
}
|
||||||
|
|
||||||
roleList, err := dao.GetUserProjectRoles(user.UserID, project.ProjectID)
|
roleList, err := dao.GetUserProjectRoles(user.UserID, project.ProjectID, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to get roles of user %d to project %d: %v", user.UserID, project.ProjectID, err)
|
log.Errorf("failed to get roles of user %d to project %d: %v", user.UserID, project.ProjectID, err)
|
||||||
return roles
|
return roles
|
||||||
@ -192,5 +192,7 @@ func (s *SecurityContext) GetProjectRoles(projectIDOrName interface{}) []int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//If len(roles)==0, Get Group Roles
|
||||||
|
|
||||||
return roles
|
return roles
|
||||||
}
|
}
|
||||||
|
@ -123,23 +123,23 @@ func TestMain(m *testing.M) {
|
|||||||
defer dao.DeleteProject(id)
|
defer dao.DeleteProject(id)
|
||||||
|
|
||||||
// add project members
|
// add project members
|
||||||
err = dao.AddProjectMember(private.ProjectID, projectAdminUser.UserID, common.RoleProjectAdmin)
|
_, err = dao.AddProjectMember(private.ProjectID, projectAdminUser.UserID, common.RoleProjectAdmin, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to add member: %v", err)
|
log.Fatalf("failed to add member: %v", err)
|
||||||
}
|
}
|
||||||
defer dao.DeleteProjectMember(private.ProjectID, projectAdminUser.UserID)
|
defer dao.DeleteProjectMember(private.ProjectID, projectAdminUser.UserID, common.UserMember)
|
||||||
|
|
||||||
err = dao.AddProjectMember(private.ProjectID, developerUser.UserID, common.RoleDeveloper)
|
_, err = dao.AddProjectMember(private.ProjectID, developerUser.UserID, common.RoleDeveloper, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to add member: %v", err)
|
log.Fatalf("failed to add member: %v", err)
|
||||||
}
|
}
|
||||||
defer dao.DeleteProjectMember(private.ProjectID, developerUser.UserID)
|
defer dao.DeleteProjectMember(private.ProjectID, developerUser.UserID, common.UserMember)
|
||||||
|
|
||||||
err = dao.AddProjectMember(private.ProjectID, guestUser.UserID, common.RoleGuest)
|
_, err = dao.AddProjectMember(private.ProjectID, guestUser.UserID, common.RoleGuest, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to add member: %v", err)
|
log.Fatalf("failed to add member: %v", err)
|
||||||
}
|
}
|
||||||
defer dao.DeleteProjectMember(private.ProjectID, guestUser.UserID)
|
defer dao.DeleteProjectMember(private.ProjectID, guestUser.UserID, common.UserMember)
|
||||||
|
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/src/common"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
"github.com/dghubble/sling"
|
"github.com/dghubble/sling"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -224,7 +226,7 @@ func prepare() error {
|
|||||||
}
|
}
|
||||||
projAdminID = int(id)
|
projAdminID = int(id)
|
||||||
|
|
||||||
if err = dao.AddProjectMember(1, projAdminID, models.PROJECTADMIN); err != nil {
|
if _, err = dao.AddProjectMember(1, projAdminID, models.PROJECTADMIN, common.UserMember); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,7 +241,7 @@ func prepare() error {
|
|||||||
}
|
}
|
||||||
projDeveloperID = int(id)
|
projDeveloperID = int(id)
|
||||||
|
|
||||||
if err = dao.AddProjectMember(1, projDeveloperID, models.DEVELOPER); err != nil {
|
if _, err = dao.AddProjectMember(1, projDeveloperID, models.DEVELOPER, common.UserMember); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,13 +256,14 @@ func prepare() error {
|
|||||||
}
|
}
|
||||||
projGuestID = int(id)
|
projGuestID = int(id)
|
||||||
|
|
||||||
return dao.AddProjectMember(1, projGuestID, models.GUEST)
|
_, err = dao.AddProjectMember(1, projGuestID, models.GUEST, common.UserMember)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func clean() {
|
func clean() {
|
||||||
ids := []int{projAdminID, projDeveloperID, projGuestID}
|
ids := []int{projAdminID, projDeveloperID, projGuestID}
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
if err := dao.DeleteProjectMember(1, id); err != nil {
|
if err := dao.DeleteProjectMember(1, id, common.UserMember); err != nil {
|
||||||
fmt.Printf("failed to clean up member %d from project library: %v", id, err)
|
fmt.Printf("failed to clean up member %d from project library: %v", id, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ func init() {
|
|||||||
beego.Router("/api/users/:id/sysadmin", &UserAPI{}, "put:ToggleUserAdminRole")
|
beego.Router("/api/users/:id/sysadmin", &UserAPI{}, "put:ToggleUserAdminRole")
|
||||||
beego.Router("/api/projects/:id([0-9]+)/logs", &ProjectAPI{}, "get:Logs")
|
beego.Router("/api/projects/:id([0-9]+)/logs", &ProjectAPI{}, "get:Logs")
|
||||||
beego.Router("/api/projects/:id([0-9]+)/_deletable", &ProjectAPI{}, "get:Deletable")
|
beego.Router("/api/projects/:id([0-9]+)/_deletable", &ProjectAPI{}, "get:Deletable")
|
||||||
beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &ProjectMemberAPI{}, "get:Get;post:Post;delete:Delete;put:Put")
|
beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &ProjectUserMemberAPI{}, "get:Get;post:Post;delete:Delete;put:Put")
|
||||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/?:name", &MetadataAPI{}, "get:Get")
|
beego.Router("/api/projects/:id([0-9]+)/metadatas/?:name", &MetadataAPI{}, "get:Get")
|
||||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/", &MetadataAPI{}, "post:Post")
|
beego.Router("/api/projects/:id([0-9]+)/metadatas/", &MetadataAPI{}, "post:Post")
|
||||||
beego.Router("/api/projects/:id([0-9]+)/metadatas/:name", &MetadataAPI{}, "put:Put;delete:Delete")
|
beego.Router("/api/projects/:id([0-9]+)/metadatas/:name", &MetadataAPI{}, "put:Put;delete:Delete")
|
||||||
|
@ -19,14 +19,16 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/src/common"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
"github.com/vmware/harbor/src/ui/auth"
|
"github.com/vmware/harbor/src/ui/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProjectMemberAPI handles request to /api/projects/{}/members/{}
|
// ProjectUserMemberAPI handles request to /api/projects/{}/members/{}
|
||||||
type ProjectMemberAPI struct {
|
type ProjectUserMemberAPI struct {
|
||||||
BaseController
|
BaseController
|
||||||
memberID int
|
memberID int
|
||||||
currentUserID int
|
currentUserID int
|
||||||
@ -40,7 +42,7 @@ type memberReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare validates the URL and parms
|
// Prepare validates the URL and parms
|
||||||
func (pma *ProjectMemberAPI) Prepare() {
|
func (pma *ProjectUserMemberAPI) Prepare() {
|
||||||
pma.BaseController.Prepare()
|
pma.BaseController.Prepare()
|
||||||
|
|
||||||
if !pma.SecurityCtx.IsAuthenticated() {
|
if !pma.SecurityCtx.IsAuthenticated() {
|
||||||
@ -116,7 +118,7 @@ func (pma *ProjectMemberAPI) Prepare() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get ...
|
// Get ...
|
||||||
func (pma *ProjectMemberAPI) Get() {
|
func (pma *ProjectUserMemberAPI) Get() {
|
||||||
pid := pma.project.ProjectID
|
pid := pma.project.ProjectID
|
||||||
if pma.memberID == 0 { //member id not set return list of the members
|
if pma.memberID == 0 { //member id not set return list of the members
|
||||||
username := pma.GetString("username")
|
username := pma.GetString("username")
|
||||||
@ -129,7 +131,7 @@ func (pma *ProjectMemberAPI) Get() {
|
|||||||
}
|
}
|
||||||
pma.Data["json"] = userList
|
pma.Data["json"] = userList
|
||||||
} else { //return detail of a member
|
} else { //return detail of a member
|
||||||
roleList, err := listRoles(pma.memberID, pid)
|
roleList, err := listRoles(pma.memberID, pid, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
|
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
|
||||||
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||||
@ -155,7 +157,7 @@ func (pma *ProjectMemberAPI) Get() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Post ...
|
// Post ...
|
||||||
func (pma *ProjectMemberAPI) Post() {
|
func (pma *ProjectUserMemberAPI) Post() {
|
||||||
projectID := pma.project.ProjectID
|
projectID := pma.project.ProjectID
|
||||||
|
|
||||||
var req memberReq
|
var req memberReq
|
||||||
@ -193,7 +195,7 @@ func (pma *ProjectMemberAPI) Post() {
|
|||||||
userID = user.UserID
|
userID = user.UserID
|
||||||
|
|
||||||
}
|
}
|
||||||
rolelist, err := dao.GetUserProjectRoles(userID, projectID)
|
rolelist, err := dao.GetUserProjectRoles(userID, projectID, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
|
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
|
||||||
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||||
@ -215,7 +217,7 @@ func (pma *ProjectMemberAPI) Post() {
|
|||||||
pma.CustomAbort(http.StatusBadRequest, "invalid role")
|
pma.CustomAbort(http.StatusBadRequest, "invalid role")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dao.AddProjectMember(projectID, userID, rid)
|
_, err = dao.AddProjectMember(projectID, userID, rid, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", projectID, userID, rid)
|
log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", projectID, userID, rid)
|
||||||
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
|
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
|
||||||
@ -224,13 +226,13 @@ func (pma *ProjectMemberAPI) Post() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Put ...
|
// Put ...
|
||||||
func (pma *ProjectMemberAPI) Put() {
|
func (pma *ProjectUserMemberAPI) Put() {
|
||||||
pid := pma.project.ProjectID
|
pid := pma.project.ProjectID
|
||||||
mid := pma.memberID
|
mid := pma.memberID
|
||||||
|
|
||||||
var req memberReq
|
var req memberReq
|
||||||
pma.DecodeJSONReq(&req)
|
pma.DecodeJSONReq(&req)
|
||||||
roleList, err := dao.GetUserProjectRoles(mid, pid)
|
roleList, err := dao.GetUserProjectRoles(mid, pid, common.UserMember)
|
||||||
if len(roleList) == 0 {
|
if len(roleList) == 0 {
|
||||||
log.Warningf("User is not in project, user id: %d, project id: %d", mid, pid)
|
log.Warningf("User is not in project, user id: %d, project id: %d", mid, pid)
|
||||||
pma.RenderError(http.StatusNotFound, "user not exist in project")
|
pma.RenderError(http.StatusNotFound, "user not exist in project")
|
||||||
@ -238,7 +240,7 @@ func (pma *ProjectMemberAPI) Put() {
|
|||||||
}
|
}
|
||||||
//TODO: delete and insert should in one transaction
|
//TODO: delete and insert should in one transaction
|
||||||
//delete user project role record for the given user
|
//delete user project role record for the given user
|
||||||
err = dao.DeleteProjectMember(pid, mid)
|
err = dao.DeleteProjectMember(pid, mid, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to delete project roles for user, user id: %d, project id: %d, error: %v", mid, pid, err)
|
log.Errorf("Failed to delete project roles for user, user id: %d, project id: %d, error: %v", mid, pid, err)
|
||||||
pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB")
|
pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB")
|
||||||
@ -246,7 +248,7 @@ func (pma *ProjectMemberAPI) Put() {
|
|||||||
}
|
}
|
||||||
//insert roles in request
|
//insert roles in request
|
||||||
for _, rid := range req.Roles {
|
for _, rid := range req.Roles {
|
||||||
err = dao.AddProjectMember(pid, mid, int(rid))
|
_, err = dao.AddProjectMember(pid, mid, int(rid), common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", pid, mid, rid)
|
log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", pid, mid, rid)
|
||||||
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
|
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
|
||||||
@ -256,11 +258,11 @@ func (pma *ProjectMemberAPI) Put() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Delete ...
|
// Delete ...
|
||||||
func (pma *ProjectMemberAPI) Delete() {
|
func (pma *ProjectUserMemberAPI) Delete() {
|
||||||
pid := pma.project.ProjectID
|
pid := pma.project.ProjectID
|
||||||
mid := pma.memberID
|
mid := pma.memberID
|
||||||
|
|
||||||
err := dao.DeleteProjectMember(pid, mid)
|
err := dao.DeleteProjectMember(pid, mid, common.UserMember)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to delete project roles for user, user id: %d, project id: %d, error: %v", mid, pid, err)
|
log.Errorf("Failed to delete project roles for user, user id: %d, project id: %d, error: %v", mid, pid, err)
|
||||||
pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB")
|
pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB")
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/vmware/harbor/src/common"
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/replication"
|
"github.com/vmware/harbor/src/replication"
|
||||||
@ -320,10 +321,10 @@ func TestRepPolicyAPIList(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer dao.DeleteUser(int(proAdminID))
|
defer dao.DeleteUser(int(proAdminID))
|
||||||
|
|
||||||
if err = dao.AddProjectMember(1, int(proAdminID), models.PROJECTADMIN); err != nil {
|
if _, err = dao.AddProjectMember(1, int(proAdminID), models.PROJECTADMIN, common.UserMember); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer dao.DeleteProjectMember(1, int(proAdminID))
|
defer dao.DeleteProjectMember(1, int(proAdminID), common.UserMember)
|
||||||
|
|
||||||
proDevID, err := dao.Register(projectDev)
|
proDevID, err := dao.Register(projectDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -331,10 +332,10 @@ func TestRepPolicyAPIList(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer dao.DeleteUser(int(proDevID))
|
defer dao.DeleteUser(int(proDevID))
|
||||||
|
|
||||||
if err = dao.AddProjectMember(1, int(proDevID), models.DEVELOPER); err != nil {
|
if _, err = dao.AddProjectMember(1, int(proDevID), models.DEVELOPER, common.UserMember); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
defer dao.DeleteProjectMember(1, int(proDevID))
|
defer dao.DeleteProjectMember(1, int(proDevID), common.UserMember)
|
||||||
|
|
||||||
// 400: invalid project ID
|
// 400: invalid project ID
|
||||||
runCodeCheckingCases(t, &codeCheckingCase{
|
runCodeCheckingCases(t, &codeCheckingCase{
|
||||||
|
@ -36,7 +36,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//sysadmin has all privileges to all projects
|
//sysadmin has all privileges to all projects
|
||||||
func listRoles(userID int, projectID int64) ([]models.Role, error) {
|
func listRoles(userID int, projectID int64, entityType string) ([]models.Role, error) {
|
||||||
roles := make([]models.Role, 0, 1)
|
roles := make([]models.Role, 0, 1)
|
||||||
isSysAdmin, err := dao.IsAdminRole(userID)
|
isSysAdmin, err := dao.IsAdminRole(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -53,7 +53,7 @@ func listRoles(userID int, projectID int64) ([]models.Role, error) {
|
|||||||
return roles, nil
|
return roles, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rs, err := dao.GetUserProjectRoles(userID, projectID)
|
rs, err := dao.GetUserProjectRoles(userID, projectID, entityType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to get user %d 's roles for project %d: %v", userID, projectID, err)
|
log.Errorf("failed to get user %d 's roles for project %d: %v", userID, projectID, err)
|
||||||
return roles, err
|
return roles, err
|
||||||
|
@ -45,7 +45,7 @@ func initRouters() {
|
|||||||
beego.Router("/sendEmail", &controllers.CommonController{}, "get:SendResetEmail")
|
beego.Router("/sendEmail", &controllers.CommonController{}, "get:SendResetEmail")
|
||||||
|
|
||||||
//API:
|
//API:
|
||||||
beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &api.ProjectMemberAPI{})
|
beego.Router("/api/projects/:pid([0-9]+)/members/?:mid", &api.ProjectUserMemberAPI{})
|
||||||
beego.Router("/api/projects/", &api.ProjectAPI{}, "head:Head")
|
beego.Router("/api/projects/", &api.ProjectAPI{}, "head:Head")
|
||||||
beego.Router("/api/projects/:id([0-9]+)", &api.ProjectAPI{})
|
beego.Router("/api/projects/:id([0-9]+)", &api.ProjectAPI{})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user