Merge pull request #65 from vmware/db-role-refactor

Db role refactor
This commit is contained in:
Daniel Jiang 2016-03-30 18:22:47 +08:00
commit 3ebb2dea0f
18 changed files with 368 additions and 448 deletions

View File

@ -10,27 +10,30 @@ create table access (
primary key (access_id) primary key (access_id)
); );
insert into access values insert into access (access_code, comment) values
( null, 'A', 'All access for the system'), ('M', 'Management access for project'),
( null, 'M', 'Management access for project'), ('R', 'Read access for project'),
( null, 'R', 'Read access for project'), ('W', 'Write access for project'),
( null, 'W', 'Write access for project'), ('D', 'Delete access for project'),
( null, 'D', 'Delete access for project'), ('S', 'Search access for project');
( null, 'S', 'Search access for project');
create table role ( create table role (
role_id int NOT NULL AUTO_INCREMENT, role_id int NOT NULL AUTO_INCREMENT,
role_mask int DEFAULT 0 NOT NULL,
role_code varchar(20), role_code varchar(20),
name varchar (20), name varchar (20),
primary key (role_id) primary key (role_id)
); );
/*
role mask is used for future enhancement when a project member can have multi-roles
currently set to 0
*/
insert into role values insert into role (role_code, name) values
( null, 'AMDRWS', 'sysAdmin'), ('MDRWS', 'projectAdmin'),
( null, 'MDRWS', 'projectAdmin'), ('RWS', 'developer'),
( null, 'RWS', 'developer'), ('RS', 'guest');
( null, 'RS', 'guest');
create table user ( create table user (
@ -43,20 +46,24 @@ create table user (
deleted tinyint (1) DEFAULT 0 NOT NULL, deleted tinyint (1) DEFAULT 0 NOT NULL,
reset_uuid varchar(40) DEFAULT NULL, reset_uuid varchar(40) DEFAULT NULL,
salt varchar(40) DEFAULT NULL, salt varchar(40) DEFAULT NULL,
sysadmin_flag tinyint (1),
creation_time timestamp,
update_time timestamp,
primary key (user_id), primary key (user_id),
UNIQUE (username), UNIQUE (username),
UNIQUE (email) UNIQUE (email)
); );
insert into user values insert into user (username, email, password, realname, comment, deleted, sysadmin_flag, creation_time, update_time) values
(1, 'admin', 'admin@example.com', '', 'system admin', 'admin user',0, null, ''), ('admin', 'admin@example.com', '', 'system admin', 'admin user',0, 1, NOW(), NOW()),
(2, 'anonymous', 'anonymous@example.com', '', 'anonymous user', 'anonymous user', 1, null, ''); ('anonymous', 'anonymous@example.com', '', 'anonymous user', 'anonymous user', 1, 0, NOW(), NOW());
create table project ( create table project (
project_id int NOT NULL AUTO_INCREMENT, project_id int NOT NULL AUTO_INCREMENT,
owner_id int NOT NULL, owner_id int NOT NULL,
name varchar (30) NOT NULL, name varchar (30) NOT NULL,
creation_time timestamp, creation_time timestamp,
update_time timestamp,
deleted tinyint (1) DEFAULT 0 NOT NULL, deleted tinyint (1) DEFAULT 0 NOT NULL,
public tinyint (1) DEFAULT 0 NOT NULL, public tinyint (1) DEFAULT 0 NOT NULL,
primary key (project_id), primary key (project_id),
@ -64,32 +71,23 @@ create table project (
UNIQUE (name) UNIQUE (name)
); );
insert into project values insert into project (owner_id, name, creation_time, update_time, public) values
(null, 1, 'library', NOW(), 0, 1); (1, 'library', NOW(), NOW(), 1);
create table project_role ( create table project_member (
pr_id int NOT NULL AUTO_INCREMENT,
project_id int NOT NULL, project_id int NOT NULL,
role_id int NOT NULL,
primary key (pr_id),
FOREIGN KEY (role_id) REFERENCES role(role_id),
FOREIGN KEY (project_id) REFERENCES project (project_id)
);
insert into project_role values
( 1,1,1 );
create table user_project_role (
upr_id int NOT NULL AUTO_INCREMENT,
user_id int NOT NULL, user_id int NOT NULL,
pr_id int NOT NULL, role int NOT NULL,
primary key (upr_id), creation_time timestamp,
FOREIGN KEY (user_id) REFERENCES user(user_id), update_time timestamp,
FOREIGN KEY (pr_id) REFERENCES project_role (pr_id) PRIMARY KEY (project_id, user_id),
); 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 user_project_role values insert into project_member (project_id, user_id, role, creation_time, update_time) values
( 1,1,1 ); (1, 1, 1, NOW(), NOW());
create table access_log ( create table access_log (
log_id int NOT NULL AUTO_INCREMENT, log_id int NOT NULL AUTO_INCREMENT,

View File

@ -92,7 +92,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 := dao.GetUserProjectRoles(models.User{UserID: pma.memberID}, pid) roleList, err := dao.GetUserProjectRoles(pma.memberID, pid)
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.")
@ -115,17 +115,26 @@ func (pma *ProjectMemberAPI) Get() {
// Post ... // Post ...
func (pma *ProjectMemberAPI) Post() { func (pma *ProjectMemberAPI) Post() {
pid := pma.project.ProjectID pid := pma.project.ProjectID
userQuery := models.User{UserID: pma.currentUserID, RoleID: models.PROJECTADMIN}
rolelist, err := dao.GetUserProjectRoles(userQuery, pid) //userQuery := models.User{UserID: pma.currentUserID, RoleID: models.PROJECTADMIN}
rolelist, err := dao.GetUserProjectRoles(pma.currentUserID, pid)
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.")
} }
if len(rolelist) == 0 { hasProjectAdminRole := false
log.Warningf("Current user, id: %d does not have project admin role for project, id: %d", pma.currentUserID, pid) for _, role := range rolelist {
if role.RoleID == models.PROJECTADMIN {
hasProjectAdminRole = true
break
}
}
if !hasProjectAdminRole {
log.Warningf("Current user, id: %d does not have project admin role for project, id:", pma.currentUserID, pid)
pma.RenderError(http.StatusForbidden, "") pma.RenderError(http.StatusForbidden, "")
return return
} }
var req memberReq var req memberReq
pma.DecodeJSONReq(&req) pma.DecodeJSONReq(&req)
username := req.Username username := req.Username
@ -135,7 +144,7 @@ func (pma *ProjectMemberAPI) Post() {
pma.RenderError(http.StatusNotFound, "User does not exist") pma.RenderError(http.StatusNotFound, "User does not exist")
return return
} }
rolelist, err = dao.GetUserProjectRoles(models.User{UserID: userID}, pid) rolelist, err = dao.GetUserProjectRoles(userID, pid)
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.")
@ -147,7 +156,7 @@ func (pma *ProjectMemberAPI) Post() {
} }
for _, rid := range req.Roles { for _, rid := range req.Roles {
err = dao.AddUserProjectRole(userID, pid, int(rid)) err = dao.AddProjectMember(pid, userID, int(rid))
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, userID, rid) log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", pid, userID, rid)
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database") pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
@ -160,20 +169,28 @@ func (pma *ProjectMemberAPI) Post() {
func (pma *ProjectMemberAPI) Put() { func (pma *ProjectMemberAPI) Put() {
pid := pma.project.ProjectID pid := pma.project.ProjectID
mid := pma.memberID mid := pma.memberID
userQuery := models.User{UserID: pma.currentUserID, RoleID: models.PROJECTADMIN}
rolelist, err := dao.GetUserProjectRoles(userQuery, pid) rolelist, err := dao.GetUserProjectRoles(pma.currentUserID, pid)
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.")
} }
if len(rolelist) == 0 { hasProjectAdminRole := false
for _, role := range rolelist {
if role.RoleID == models.PROJECTADMIN {
hasProjectAdminRole = true
break
}
}
if !hasProjectAdminRole {
log.Warningf("Current user, id: %d does not have project admin role for project, id: %d", pma.currentUserID, pid) log.Warningf("Current user, id: %d does not have project admin role for project, id: %d", pma.currentUserID, pid)
pma.RenderError(http.StatusForbidden, "") pma.RenderError(http.StatusForbidden, "")
return return
} }
var req memberReq var req memberReq
pma.DecodeJSONReq(&req) pma.DecodeJSONReq(&req)
roleList, err := dao.GetUserProjectRoles(models.User{UserID: mid}, pid) roleList, err := dao.GetUserProjectRoles(mid, pid)
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")
@ -181,7 +198,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.DeleteUserProjectRoles(mid, pid) err = dao.DeleteProjectMember(pid, mid)
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")
@ -189,7 +206,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.AddUserProjectRole(mid, pid, int(rid)) err = dao.AddProjectMember(pid, mid, int(rid))
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")
@ -202,14 +219,22 @@ func (pma *ProjectMemberAPI) Put() {
func (pma *ProjectMemberAPI) Delete() { func (pma *ProjectMemberAPI) Delete() {
pid := pma.project.ProjectID pid := pma.project.ProjectID
mid := pma.memberID mid := pma.memberID
userQuery := models.User{UserID: pma.currentUserID, RoleID: models.PROJECTADMIN}
rolelist, err := dao.GetUserProjectRoles(userQuery, pid) rolelist, err := dao.GetUserProjectRoles(pma.currentUserID, pid)
if len(rolelist) == 0 { hasProjectAdminRole := false
for _, role := range rolelist {
if role.RoleID == models.PROJECTADMIN {
hasProjectAdminRole = true
break
}
}
if !hasProjectAdminRole {
log.Warningf("Current user, id: %d does not have project admin role for project, id: %d", pma.currentUserID, pid) log.Warningf("Current user, id: %d does not have project admin role for project, id: %d", pma.currentUserID, pid)
pma.RenderError(http.StatusForbidden, "") pma.RenderError(http.StatusForbidden, "")
return return
} }
err = dao.DeleteUserProjectRoles(mid, pid) err = dao.DeleteProjectMember(pid, mid)
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")

View File

@ -187,13 +187,21 @@ func (p *ProjectAPI) FilterAccessLog() {
} }
func isProjectAdmin(userID int, pid int64) bool { func isProjectAdmin(userID int, pid int64) bool {
userQuery := models.User{UserID: userID, RoleID: models.PROJECTADMIN} rolelist, err := dao.GetUserProjectRoles(userID, pid)
rolelist, err := dao.GetUserProjectRoles(userQuery, pid)
if err != nil { if err != nil {
log.Errorf("Error occurred in GetUserProjectRoles, returning false, error: %v", err) log.Errorf("Error occurred in GetUserProjectRoles, returning false, error: %v", err)
return false return false
} }
return len(rolelist) > 0
hasProjectAdminRole := false
for _, role := range rolelist {
if role.RoleID == models.PROJECTADMIN {
hasProjectAdminRole = true
break
}
}
return hasProjectAdminRole
} }
func validateProjectReq(req projectReq) error { func validateProjectReq(req projectReq) error {

View File

@ -30,7 +30,7 @@ func checkProjectPermission(userID int, projectID int64) bool {
if exist { if exist {
return true return true
} }
roleList, err := dao.GetUserProjectRoles(models.User{UserID: userID}, projectID) roleList, err := dao.GetUserProjectRoles(userID, projectID)
if err != nil { if err != nil {
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err) log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
return false return false

View File

@ -21,7 +21,6 @@ import (
"os" "os"
"github.com/vmware/harbor/dao" "github.com/vmware/harbor/dao"
"github.com/vmware/harbor/models"
"github.com/astaxie/beego" "github.com/astaxie/beego"
) )
@ -69,7 +68,7 @@ func (idc *ItemDetailController) Get() {
idc.Data["Username"] = idc.GetSession("username") idc.Data["Username"] = idc.GetSession("username")
idc.Data["UserId"] = userID idc.Data["UserId"] = userID
roleList, err := dao.GetUserProjectRoles(models.User{UserID: userID}, projectID) roleList, err := dao.GetUserProjectRoles(userID, projectID)
if err != nil { if err != nil {
beego.Error("Error occurred in GetUserProjectRoles:", err) beego.Error("Error occurred in GetUserProjectRoles:", err)
idc.CustomAbort(http.StatusInternalServerError, "Internal error.") idc.CustomAbort(http.StatusInternalServerError, "Internal error.")
@ -86,9 +85,7 @@ func (idc *ItemDetailController) Get() {
return return
} }
if isAdmin { if len(roleList) > 0 {
idc.Data["RoleId"] = models.SYSADMIN
} else if len(roleList) > 0 {
idc.Data["RoleId"] = roleList[0].RoleID idc.Data["RoleId"] = roleList[0].RoleID
} }
} }

View File

@ -16,9 +16,10 @@
package dao package dao
import ( import (
"log"
"net" "net"
"github.com/vmware/harbor/utils/log"
"os" "os"
"strings" "strings"
"time" "time"
@ -88,7 +89,7 @@ func InitDB() {
c.Close() c.Close()
ch <- 1 ch <- 1
} else { } else {
log.Printf("failed to connect to db, retry after 2 seconds...") log.Info("failed to connect to db, retry after 2 seconds...")
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
} }
} }

View File

@ -16,12 +16,12 @@
package dao package dao
import ( import (
"fmt"
"log"
"os" "os"
"testing" "testing"
"time" "time"
"github.com/vmware/harbor/utils/log"
"github.com/vmware/harbor/models" "github.com/vmware/harbor/models"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
@ -41,44 +41,61 @@ func execUpdate(o orm.Ormer, sql string, params interface{}) error {
} }
func clearUp(username string) { func clearUp(username string) {
var err error
o := orm.NewOrm() o := orm.NewOrm()
o.Begin() o.Begin()
err := execUpdate(o, `delete upr from user_project_role upr
left join project_role pr on upr.pr_id = pr.pr_id err = execUpdate(o, `delete pm
left join project p on pr.project_id = p.project_id from project_member pm
left join user u on u.user_id = p.owner_id join user u
where u.username = ?`, username) on pm.user_id = u.user_id
where u.username = ?`, username)
if err != nil { if err != nil {
o.Rollback() o.Rollback()
log.Println(err) log.Error(err)
} }
err = execUpdate(o, `delete pr from project_role pr
left join project p on pr.project_id = p.project_id err = execUpdate(o, `delete pm
left join user u on u.user_id = p.owner_id from project_member pm
where u.username = ?`, username) join project p
on pm.project_id = p.project_id
where p.name = ?`, projectName)
if err != nil { if err != nil {
o.Rollback() o.Rollback()
log.Println(err) log.Error(err)
} }
err = execUpdate(o, `delete a from access_log a
left join user u on a.user_id = u.user_id err = execUpdate(o, `delete al
where u.username = ?`, username) from access_log al
join user u
on al.user_id = u.user_id
where u.username = ?`, username)
if err != nil { if err != nil {
o.Rollback() o.Rollback()
log.Println(err) log.Error(err)
} }
err = execUpdate(o, `delete p from project p
left join user u on p.owner_id = u.user_id err = execUpdate(o, `delete al
where u.username = ?`, username) from access_log al
join project p
on al.project_id = p.project_id
where p.name = ?`, projectName)
if err != nil { if err != nil {
o.Rollback() o.Rollback()
log.Println(err) log.Error(err)
} }
err = execUpdate(o, `delete u from user u
where u.username = ?`, username) err = execUpdate(o, `delete from project where name = ?`, projectName)
if err != nil { if err != nil {
o.Rollback() o.Rollback()
log.Println(err) log.Error(err)
}
err = execUpdate(o, `delete from user where username = ?`, username)
if err != nil {
o.Rollback()
log.Error(err)
} }
o.Commit() o.Commit()
} }
@ -109,7 +126,7 @@ func TestMain(m *testing.M) {
} }
dbPassword := os.Getenv("DB_PWD") dbPassword := os.Getenv("DB_PWD")
fmt.Printf("DB_HOST: %s, DB_USR: %s, DB_PORT: %s, DB_PWD: %s\n", dbHost, dbUser, dbPort, dbPassword) log.Infof("DB_HOST: %s, DB_USR: %s, DB_PORT: %s, DB_PWD: %s\n", dbHost, dbUser, dbPort, dbPassword)
os.Setenv("MYSQL_PORT_3306_TCP_ADDR", dbHost) os.Setenv("MYSQL_PORT_3306_TCP_ADDR", dbHost)
os.Setenv("MYSQL_PORT_3306_TCP_PORT", dbPort) os.Setenv("MYSQL_PORT_3306_TCP_PORT", dbPort)
@ -379,32 +396,6 @@ func TestGetProject(t *testing.T) {
} }
} }
func getProjectRole(projectID int64) []models.Role {
o := orm.NewOrm()
var r []models.Role
_, err := o.Raw(`select r.role_id, r.name
from project_role pr
left join role r on pr.role_id = r.role_id
where project_id = ?`, projectID).QueryRows(&r)
if err != nil {
log.Printf("Error occurred in querying project_role: %v", err)
}
return r
}
func TestCheckProjectRoles(t *testing.T) {
r := getProjectRole(currentProject.ProjectID)
if len(r) != 3 {
t.Errorf("The length of project roles is not 3")
}
if r[1].RoleID != 3 {
t.Errorf("The role id does not match, expected: 3, acutal: %d", r[1].RoleID)
}
if r[1].Name != "developer" {
t.Errorf("The name of role id: 3 should be developer, actual:%s", r[1].Name)
}
}
func TestGetAccessLog(t *testing.T) { func TestGetAccessLog(t *testing.T) {
queryAccessLog := models.AccessLog{ queryAccessLog := models.AccessLog{
UserID: currentUser.UserID, UserID: currentUser.UserID,
@ -546,25 +537,10 @@ func TestQueryProject(t *testing.T) {
} }
} }
func getUserProjectRole(projectID int64, userID int) []models.Role {
o := orm.NewOrm()
var r []models.Role
_, err := o.Raw(`select r.role_id, r.name
from user_project_role upr
left join project_role pr on upr.pr_id = pr.pr_id
left join role r on r.role_id = pr.role_id
where pr.project_id = ? and upr.user_id = ?`, projectID, userID).QueryRows(&r)
if err != nil {
log.Fatalf("Error occurred in querying user_project_role: %v", err)
}
return r
}
func TestGetUserProjectRoles(t *testing.T) { func TestGetUserProjectRoles(t *testing.T) {
user := *currentUser r, err := GetUserProjectRoles(currentUser.UserID, currentProject.ProjectID)
r, err := GetUserProjectRoles(user, currentProject.ProjectID)
if err != nil { if err != nil {
t.Errorf("Error happened in GetUserProjectRole: %v, user: %+v, project Id: %d", err, user, currentProject.ProjectID) t.Errorf("Error happened in GetUserProjectRole: %v, userID: %+v, project Id: %d", err, currentUser.UserID, currentProject.ProjectID)
} }
//Get the size of current user project role. //Get the size of current user project role.
@ -575,16 +551,6 @@ func TestGetUserProjectRoles(t *testing.T) {
if r[0].Name != "projectAdmin" { if r[0].Name != "projectAdmin" {
t.Errorf("the expected rolename is: projectAdmin, actual: %s", r[0].Name) t.Errorf("the expected rolename is: projectAdmin, actual: %s", r[0].Name)
} }
user.RoleID = 1
r, err = GetUserProjectRoles(user, currentProject.ProjectID)
if err != nil {
t.Errorf("Error happened in GetUserProjectRole: %v, user: %+v, project Id: %d", err, user, currentProject.ProjectID)
}
//Get the size of current user project role.
if len(r) != 0 {
t.Errorf("The user, id: %d, should not have role id: 1 in project id: %d, actual role list: %v", currentUser.UserID, currentProject.ProjectID, r)
}
} }
func TestProjectPermission(t *testing.T) { func TestProjectPermission(t *testing.T) {
@ -610,34 +576,43 @@ func TestQueryRelevantProjects(t *testing.T) {
} }
} }
func TestAssignUserProjectRole(t *testing.T) { func TestAddProjectMember(t *testing.T) {
err := AddUserProjectRole(currentUser.UserID, currentProject.ProjectID, developer) err := AddProjectMember(currentProject.ProjectID, 1, models.DEVELOPER)
if err != nil { if err != nil {
t.Errorf("Error occurred in AddUserProjectRole: %v", err) t.Errorf("Error occurred in AddProjectMember: %v", err)
} }
r := getUserProjectRole(currentProject.ProjectID, currentUser.UserID) roles, err := GetUserProjectRoles(1, currentProject.ProjectID)
if err != nil {
//Get the size of current user project role info. t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
if len(r) != 2 {
t.Errorf("Expected length of role list is 2, actual: %d", len(r))
} }
if r[1].RoleID != 3 { flag := false
t.Errorf("Expected role id of the second role in list is 3, actual: %d", r[1].RoleID) for _, role := range roles {
if role.Name == "developer" {
flag = true
break
}
}
if !flag {
t.Errorf("the user which ID is 1 does not have developer privileges")
} }
} }
func TestDeleteUserProjectRole(t *testing.T) { func TestDeleteProjectMember(t *testing.T) {
err := DeleteUserProjectRoles(currentUser.UserID, currentProject.ProjectID) err := DeleteProjectMember(currentProject.ProjectID, 1)
if err != nil { if err != nil {
t.Errorf("Error occurred in DeleteUserProjectRoles: %v", err) t.Errorf("Error occurred in DeleteProjectMember: %v", err)
} }
r := getUserProjectRole(currentProject.ProjectID, currentUser.UserID) roles, err := GetUserProjectRoles(1, currentProject.ProjectID)
//Get the size of current user project role. if err != nil {
if len(r) != 0 { t.Errorf("Error occurred in GetUserProjectRoles: %v", err)
t.Errorf("Expected role list length is 0, actual: %d, role list: %+v", len(r), r) }
if len(roles) != 0 {
t.Errorf("delete record failed from table project_member")
} }
} }

View File

@ -22,8 +22,8 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/vmware/harbor/utils/log"
) )
//TODO:transaction, return err //TODO:transaction, return err
@ -40,12 +40,13 @@ func AddProject(project models.Project) error {
o := orm.NewOrm() o := orm.NewOrm()
p, err := o.Raw("insert into project (owner_id, name, creation_time, deleted, public) values (?, ?, now(), ?, ?)").Prepare() p, err := o.Raw("insert into project (owner_id, name, creation_time, update_time, deleted, public) values (?, ?, ?, ?, ?, ?)").Prepare()
if err != nil { if err != nil {
return err return err
} }
r, err := p.Exec(project.OwnerID, project.Name, project.Deleted, project.Public) now := time.Now()
r, err := p.Exec(project.OwnerID, project.Name, now, now, project.Deleted, project.Public)
if err != nil { if err != nil {
return err return err
} }
@ -55,27 +56,7 @@ func AddProject(project models.Project) error {
return err return err
} }
projectAdminRole := models.ProjectRole{ProjectID: projectID, RoleID: models.PROJECTADMIN} if err = AddProjectMember(projectID, project.OwnerID, models.PROJECTADMIN); err != nil {
_, err = AddProjectRole(projectAdminRole)
if err != nil {
return err
}
projectDeveloperRole := models.ProjectRole{ProjectID: projectID, RoleID: models.DEVELOPER}
_, err = AddProjectRole(projectDeveloperRole)
if err != nil {
return err
}
projectGuestRole := models.ProjectRole{ProjectID: projectID, RoleID: models.GUEST}
_, err = AddProjectRole(projectGuestRole)
if err != nil {
return err
}
//Add all project roles, after that when assigning a user to a project just update the upr table
err = AddUserProjectRole(project.OwnerID, projectID, models.PROJECTADMIN)
if err != nil {
return err return err
} }
@ -89,7 +70,7 @@ func AddProject(project models.Project) error {
func IsProjectPublic(projectName string) bool { func IsProjectPublic(projectName string) bool {
project, err := GetProjectByName(projectName) project, err := GetProjectByName(projectName)
if err != nil { if err != nil {
beego.Error("Error occurred in GetProjectByName:", err) log.Errorf("Error occurred in GetProjectByName: %v", err)
return false return false
} }
if project == nil { if project == nil {
@ -103,11 +84,9 @@ func QueryProject(query models.Project) ([]models.Project, error) {
o := orm.NewOrm() o := orm.NewOrm()
sql := `select distinct sql := `select distinct
p.project_id, p.owner_id, p.name,p.creation_time, p.public p.project_id, p.owner_id, p.name,p.creation_time, p.update_time, p.public
from project p from project p
left join project_role pr on p.project_id = pr.project_id left join project_member pm on p.project_id = pm.project_id
left join user_project_role upr on upr.pr_id = pr.pr_id
left join user u on u.user_id = upr.user_id
where p.deleted = 0 ` where p.deleted = 0 `
queryParam := make([]interface{}, 1) queryParam := make([]interface{}, 1)
@ -116,8 +95,7 @@ func QueryProject(query models.Project) ([]models.Project, error) {
sql += ` and p.public = ?` sql += ` and p.public = ?`
queryParam = append(queryParam, query.Public) queryParam = append(queryParam, query.Public)
} else if isAdmin, _ := IsAdminRole(query.UserID); isAdmin == false { } else if isAdmin, _ := IsAdminRole(query.UserID); isAdmin == false {
sql += ` and (p.owner_id = ? or u.user_id = ?) ` sql += ` and (pm.user_id = ?) `
queryParam = append(queryParam, query.UserID)
queryParam = append(queryParam, query.UserID) queryParam = append(queryParam, query.UserID)
} }
@ -161,60 +139,65 @@ func ProjectExists(nameOrID interface{}) (bool, error) {
} }
// GetProjectByID ... // GetProjectByID ...
func GetProjectByID(projectID int64) (*models.Project, error) { func GetProjectByID(id int64) (*models.Project, error) {
o := orm.NewOrm() o := orm.NewOrm()
sql := `select p.project_id, p.name, u.username as owner_name, p.owner_id, p.creation_time, p.public sql := `select p.project_id, p.name, u.username as owner_name, p.owner_id, p.creation_time, p.update_time, p.public
from project p left join user u on p.owner_id = u.user_id where p.deleted = 0 and p.project_id = ?` from project p left join user u on p.owner_id = u.user_id where p.deleted = 0 and p.project_id = ?`
queryParam := make([]interface{}, 1) queryParam := make([]interface{}, 1)
queryParam = append(queryParam, projectID) queryParam = append(queryParam, id)
p := []models.Project{} p := []models.Project{}
count, err := o.Raw(sql, queryParam).QueryRows(&p) count, err := o.Raw(sql, queryParam).QueryRows(&p)
if err != nil { if err != nil {
return nil, err return nil, err
} else if count == 0 {
return nil, nil
} else {
return &p[0], nil
} }
if count == 0 {
return nil, nil
}
return &p[0], nil
} }
// GetProjectByName ... // GetProjectByName ...
func GetProjectByName(projectName string) (*models.Project, error) { func GetProjectByName(name string) (*models.Project, error) {
o := orm.NewOrm() o := orm.NewOrm()
var p []models.Project var p []models.Project
n, err := o.Raw(`select project_id, owner_id, name, deleted, public from project where name = ? and deleted = 0`, projectName).QueryRows(&p) n, err := o.Raw(`select * from project where name = ? and deleted = 0`, name).QueryRows(&p)
if err != nil { if err != nil {
return nil, err return nil, err
} else if n == 0 {
return nil, nil
} else {
return &p[0], nil
} }
if n == 0 {
return nil, nil
}
return &p[0], nil
} }
// GetPermission gets roles that the user has according to the project. // GetPermission gets roles that the user has according to the project.
func GetPermission(username, projectName string) (string, error) { func GetPermission(username, projectName string) (string, error) {
o := orm.NewOrm() o := orm.NewOrm()
sql := "select r.role_code from role as r " + sql := `select r.role_code from role as r
"inner join project_role as pr on r.role_id = pr.role_id " + inner join project_member as pm on r.role_id = pm.role
"inner join user_project_role as ur on pr.pr_id = ur.pr_id " + inner join user as u on u.user_id = pm.user_id
"inner join user as u on u.user_id = ur.user_id " + inner join project p on p.project_id = pm.project_id
"inner join project p on p.project_id = pr.project_id " + where u.username = ? and p.name = ? and u.deleted = 0 and p.deleted = 0`
"where u.username = ? and p.name = ? and u.deleted = 0 and p.deleted = 0"
var r []models.Role var r []models.Role
n, err := o.Raw(sql, username, projectName).QueryRows(&r) n, err := o.Raw(sql, username, projectName).QueryRows(&r)
if err != nil { if err != nil {
return "", err return "", err
} else if n == 0 {
return "", nil
} else {
return r[0].RoleCode, nil
} }
if n == 0 {
return "", nil
}
return r[0].RoleCode, nil
} }
// ToggleProjectPublicity toggles the publicity of the project. // ToggleProjectPublicity toggles the publicity of the project.
@ -228,10 +211,11 @@ func ToggleProjectPublicity(projectID int64, publicity int) error {
// QueryRelevantProjects returns all projects that the user is a member of. // QueryRelevantProjects returns all projects that the user is a member of.
func QueryRelevantProjects(userID int) ([]models.Project, error) { func QueryRelevantProjects(userID int) ([]models.Project, error) {
o := orm.NewOrm() o := orm.NewOrm()
sql := `SELECT distinct p.project_id, p.name, p.public FROM registry.project p sql := `select distinct p.project_id, p.name, p.public
left join project_role pr on p.project_id = pr.project_id from project p
left join user_project_role upr on upr.pr_id = pr.pr_id left join project_member pm on p.project_id = pm.project_id
where upr.user_id = ? or p.public = 1 and p.deleted = 0` left join user u on u.user_id = pm.user_id
where u.user_id = ? or p.public = 1 and p.deleted = 0`
var res []models.Project var res []models.Project
_, err := o.Raw(sql, userID).QueryRows(&res) _, err := o.Raw(sql, userID).QueryRows(&res)
if err != nil { if err != nil {

View File

@ -16,25 +16,56 @@
package dao package dao
import ( import (
"github.com/vmware/harbor/models"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/vmware/harbor/models"
) )
// AddProjectMember inserts a record to table project_member
func AddProjectMember(projectID int64, userID int, role int) error {
o := orm.NewOrm()
sql := "insert into project_member (project_id, user_id , role) values (?, ?, ?)"
_, err := o.Raw(sql, projectID, userID, role).Exec()
return err
}
// UpdateProjectMember updates the record in table project_member
func UpdateProjectMember(projectID int64, userID int, role int) error {
o := orm.NewOrm()
sql := "update project_member set role = ? where project_id = ? and user_id = ?"
_, err := o.Raw(sql, role, projectID, userID).Exec()
return err
}
// DeleteProjectMember delete the record from table project_member
func DeleteProjectMember(projectID int64, userID int) error {
o := orm.NewOrm()
sql := "delete from project_member where project_id = ? and user_id = ?"
if _, err := o.Raw(sql, projectID, userID).Exec(); err != nil {
return err
}
return nil
}
// GetUserByProject gets all members of the project. // GetUserByProject gets all members of the project.
func GetUserByProject(projectID int64, queryUser models.User) ([]models.User, error) { func GetUserByProject(projectID int64, queryUser models.User) ([]models.User, error) {
o := orm.NewOrm() o := orm.NewOrm()
u := []models.User{} u := []models.User{}
sql := `select sql := `select u.user_id, u.username, r.name rolename, r.role_id
u.user_id, u.username, r.name rolename, r.role_id from user u
from user u left join user_project_role upr join project_member pm
on u.user_id = upr.user_id on pm.project_id = ? and u.user_id = pm.user_id
left join project_role pr join role r
on pr.pr_id = upr.pr_id on pm.role = r.role_id
left join role r where u.deleted = 0`
on r.role_id = pr.role_id
where u.deleted = 0
and pr.project_id = ? `
queryParam := make([]interface{}, 1) queryParam := make([]interface{}, 1)
queryParam = append(queryParam, projectID) queryParam = append(queryParam, projectID)

View File

@ -1,93 +0,0 @@
/*
Copyright (c) 2016 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 dao
import (
"github.com/vmware/harbor/models"
"github.com/astaxie/beego/orm"
)
// AddProjectRole ...
func AddProjectRole(projectRole models.ProjectRole) (int64, error) {
o := orm.NewOrm()
p, err := o.Raw("insert into project_role (project_id, role_id) values (?, ?)").Prepare()
if err != nil {
return 0, err
}
defer p.Close()
r, err := p.Exec(projectRole.ProjectID, projectRole.RoleID)
if err != nil {
return 0, err
}
id, err := r.LastInsertId()
return id, err
}
// AddUserProjectRole inserts role information to table project_role and user_project_role.
func AddUserProjectRole(userID int, projectID int64, roleID int) error {
o := orm.NewOrm()
var pr []models.ProjectRole
var prID int
sql := `select pr.pr_id, pr.project_id, pr.role_id from project_role pr where pr.project_id = ? and pr.role_id = ?`
n, err := o.Raw(sql, projectID, roleID).QueryRows(&pr)
if err != nil {
return err
}
if n == 0 { //project role not found, insert a pr record
p, err := o.Raw("insert into project_role (project_id, role_id) values (?, ?)").Prepare()
if err != nil {
return err
}
defer p.Close()
r, err := p.Exec(projectID, roleID)
if err != nil {
return err
}
id, err := r.LastInsertId()
if err != nil {
return err
}
prID = int(id)
} else if n > 0 {
prID = pr[0].PrID
}
p, err := o.Raw("insert into user_project_role (user_id, pr_id) values (?, ?)").Prepare()
if err != nil {
return err
}
defer p.Close()
_, err = p.Exec(userID, prID)
return err
}
// DeleteUserProjectRoles ...
func DeleteUserProjectRoles(userID int, projectID int64) error {
o := orm.NewOrm()
sql := `delete from user_project_role where user_id = ? and pr_id in
(select pr_id from project_role where project_id = ?)`
p, err := o.Raw(sql).Prepare()
if err != nil {
return err
}
_, err = p.Exec(userID, projectID)
return err
}

View File

@ -18,6 +18,7 @@ package dao
import ( import (
"errors" "errors"
"regexp" "regexp"
"time"
"github.com/vmware/harbor/models" "github.com/vmware/harbor/models"
"github.com/vmware/harbor/utils" "github.com/vmware/harbor/utils"
@ -34,7 +35,8 @@ func Register(user models.User) (int64, error) {
} }
o := orm.NewOrm() o := orm.NewOrm()
p, err := o.Raw("insert into user (username, password, realname, email, comment, salt) values (?, ?, ?, ?, ?, ?)").Prepare()
p, err := o.Raw("insert into user (username, password, realname, email, comment, salt, sysadmin_flag, creation_time, update_time) values (?, ?, ?, ?, ?, ?, ?, ?, ?)").Prepare()
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -45,7 +47,8 @@ func Register(user models.User) (int64, error) {
return 0, err return 0, err
} }
r, err := p.Exec(user.Username, utils.Encrypt(user.Password, salt), user.Realname, user.Email, user.Comment, salt) now := time.Now()
r, err := p.Exec(user.Username, utils.Encrypt(user.Password, salt), user.Realname, user.Email, user.Comment, salt, user.HasAdminRole, now, now)
if err != nil { if err != nil {
return 0, err return 0, err

View File

@ -16,37 +16,28 @@
package dao package dao
import ( import (
"github.com/vmware/harbor/models" "fmt"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/vmware/harbor/models"
) )
// GetUserProjectRoles returns roles that the user has according to the project. // GetUserProjectRoles returns roles that the user has according to the project.
func GetUserProjectRoles(userQuery models.User, projectID int64) ([]models.Role, error) { func GetUserProjectRoles(userID int, projectID int64) ([]models.Role, error) {
o := orm.NewOrm() o := orm.NewOrm()
sql := `select distinct r.role_id, r.role_code, r.name sql := `select *
from role r from role
left join project_role pr on r.role_id = pr.role_id where role_id =
left join user_project_role upr on pr.pr_id = upr.pr_id (
left join user u on u.user_id = upr.user_id select role
where u.deleted = 0 from project_member
and u.user_id = ? ` where project_id = ? and user_id = ?
queryParam := make([]interface{}, 1) )`
queryParam = append(queryParam, userQuery.UserID)
if projectID > 0 {
sql += ` and pr.project_id = ? `
queryParam = append(queryParam, projectID)
}
if userQuery.RoleID > 0 {
sql += ` and r.role_id = ? `
queryParam = append(queryParam, userQuery.RoleID)
}
var roleList []models.Role var roleList []models.Role
_, err := o.Raw(sql, queryParam).QueryRows(&roleList) _, err := o.Raw(sql, projectID, userID).QueryRows(&roleList)
if err != nil { if err != nil {
return nil, err return nil, err
@ -54,13 +45,27 @@ func GetUserProjectRoles(userQuery models.User, projectID int64) ([]models.Role,
return roleList, nil return roleList, nil
} }
// IsAdminRole returns whether the user is admin. // IsAdminRole returns whether the user is admin.
func IsAdminRole(userID int) (bool, error) { func IsAdminRole(userIDOrUsername interface{}) (bool, error) {
//role_id == 1 means the user is system admin u := models.User{}
userQuery := models.User{UserID: userID, RoleID: models.SYSADMIN}
adminRoleList, err := GetUserProjectRoles(userQuery, 0) switch v := userIDOrUsername.(type) {
case int:
u.UserID = v
case string:
u.Username = v
default:
return false, fmt.Errorf("invalid parameter, only int and string are supported: %v", userIDOrUsername)
}
user, err := GetUser(u)
if err != nil { if err != nil {
return false, err return false, err
} }
return len(adminRoleList) > 0, nil
if user == nil {
return false, nil
}
return user.HasAdminRole == 1, nil
} }

View File

@ -22,8 +22,8 @@ import (
"github.com/vmware/harbor/models" "github.com/vmware/harbor/models"
"github.com/vmware/harbor/utils" "github.com/vmware/harbor/utils"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm" "github.com/astaxie/beego/orm"
"github.com/vmware/harbor/utils/log"
) )
// GetUser ... // GetUser ...
@ -31,12 +31,8 @@ func GetUser(query models.User) (*models.User, error) {
o := orm.NewOrm() o := orm.NewOrm()
sql := `select user_id, username, email, realname, reset_uuid, salt, sql := `select user_id, username, email, realname, comment, reset_uuid, salt,
ifnull((select pr.role_id sysadmin_flag, creation_time, update_time
from project_role pr
left join user_project_role upr on upr.pr_id = pr.pr_id
where pr.role_id = 1
and upr.user_id = u.user_id),0) as has_admin_role
from user u from user u
where deleted = 0 ` where deleted = 0 `
queryParam := make([]interface{}, 1) queryParam := make([]interface{}, 1)
@ -60,51 +56,54 @@ func GetUser(query models.User) (*models.User, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} else if n == 0 {
return nil, nil
} else {
return &u[0], nil
} }
if n == 0 {
return nil, nil
}
return &u[0], nil
} }
// LoginByDb is used for user to login with database auth mode. // LoginByDb is used for user to login with database auth mode.
func LoginByDb(auth models.AuthModel) (*models.User, error) { func LoginByDb(auth models.AuthModel) (*models.User, error) {
query := models.User{Username: auth.Principal, Email: auth.Principal}
o := orm.NewOrm() o := orm.NewOrm()
var u []models.User
n, err := o.Raw(`select username from user where (username = ? or email = ?)`, query.Username, query.Email).QueryRows(&u) var users []models.User
n, err := o.Raw(`select * from user where (username = ? or email = ?) and deleted = 0`,
auth.Principal, auth.Principal).QueryRows(&users)
if err != nil { if err != nil {
return nil, err return nil, err
} else if n == 0 { }
beego.Warning("User does not exist. Principal:", auth.Principal) if n == 0 {
return nil, nil return nil, nil
} else {
u[0].Password = auth.Password
return CheckUserPassword(u[0])
} }
user := users[0]
if user.Password != utils.Encrypt(auth.Password, user.Salt) {
return nil, nil
}
user.Password = "" //do not return the password
return &user, nil
} }
// ListUsers lists all users according to different conditions. // ListUsers lists all users according to different conditions.
func ListUsers(query models.User) ([]models.User, error) { func ListUsers(query models.User) ([]models.User, error) {
o := orm.NewOrm() o := orm.NewOrm()
u := []models.User{} u := []models.User{}
sql := `select u.user_id, u.username, u.email, ifnull((select pr.role_id sql := `select user_id, username, email, realname, comment, reset_uuid, salt,
from project_role pr sysadmin_flag, creation_time, update_time
left join user_project_role upr on upr.pr_id = pr.pr_id from user u
where pr.role_id = 1 where u.deleted = 0 and u.user_id != 1 `
and upr.user_id = u.user_id),0) as has_admin_role
from user u
where u.deleted = 0 and u.user_id != 1 `
queryParam := make([]interface{}, 1) queryParam := make([]interface{}, 1)
if query.Username != "" { if query.Username != "" {
sql += ` and u.username like ? ` sql += ` and username like ? `
queryParam = append(queryParam, query.Username) queryParam = append(queryParam, query.Username)
} }
sql += ` order by u.user_id desc ` sql += ` order by user_id desc `
_, err := o.Raw(sql, queryParam).QueryRows(&u) _, err := o.Raw(sql, queryParam).QueryRows(&u)
return u, err return u, err
@ -112,59 +111,50 @@ func ListUsers(query models.User) ([]models.User, error) {
// ToggleUserAdminRole gives a user admim role. // ToggleUserAdminRole gives a user admim role.
func ToggleUserAdminRole(u models.User) error { func ToggleUserAdminRole(u models.User) error {
projectRole := models.ProjectRole{PrID: 1} //admin project role
o := orm.NewOrm() o := orm.NewOrm()
var pr []models.ProjectRole sql := `update user set sysadmin_flag =not sysadmin_flag where user_id = ?`
n, err := o.Raw(`select user_id from user_project_role where user_id = ? and pr_id = ? `, u.UserID, projectRole.PrID).QueryRows(&pr) r, err := o.Raw(sql, u.UserID).Exec()
if err != nil { if err != nil {
return err return err
} }
var sql string if _, err := r.RowsAffected(); err != nil {
if n == 0 {
sql = `insert into user_project_role (user_id, pr_id) values (?, ?)`
} else {
sql = `delete from user_project_role where user_id = ? and pr_id = ?`
}
p, err := o.Raw(sql).Prepare()
if err != nil {
return err return err
} }
defer p.Close()
_, err = p.Exec(u.UserID, projectRole.PrID)
return err return nil
} }
// ChangeUserPassword ... // ChangeUserPassword ...
func ChangeUserPassword(u models.User, oldPassword ...string) error { func ChangeUserPassword(u models.User, oldPassword ...string) (err error) {
if len(oldPassword) > 1 {
return errors.New("Wrong numbers of params.")
}
o := orm.NewOrm() o := orm.NewOrm()
var err error
var r sql.Result var r sql.Result
if len(oldPassword) == 0 { if len(oldPassword) == 0 {
//In some cases, it may no need to check old password, just as Linux change password policies. //In some cases, it may no need to check old password, just as Linux change password policies.
_, err = o.Raw(`update user set password=?, salt=? where user_id=?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID).Exec() r, err = o.Raw(`update user set password=?, salt=? where user_id=?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID).Exec()
} else if len(oldPassword) == 1 {
r, err = o.Raw(`update user set password=?, salt=? where user_id=? and password = ?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID, utils.Encrypt(oldPassword[0], u.Salt)).Exec()
if err != nil {
return err
}
count, err := r.RowsAffected()
if err != nil {
return err
}
if count == 0 {
return errors.New("No record be changed, change password failed.")
}
} else { } else {
return errors.New("Wrong numbers of params.") r, err = o.Raw(`update user set password=?, salt=? where user_id=? and password = ?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserID, utils.Encrypt(oldPassword[0], u.Salt)).Exec()
} }
return err
if err != nil {
return err
}
c, err := r.RowsAffected()
if err != nil {
return err
}
if c == 0 {
return errors.New("No record has been modified, change password failed.")
}
return nil
} }
// ResetUserPassword ... // ResetUserPassword ...
@ -181,7 +171,7 @@ func ResetUserPassword(u models.User) error {
if count == 0 { if count == 0 {
return errors.New("No record be changed, reset password failed.") return errors.New("No record be changed, reset password failed.")
} }
return err return nil
} }
// UpdateUserResetUUID ... // UpdateUserResetUUID ...
@ -224,12 +214,14 @@ func CheckUserPassword(query models.User) (*models.User, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} else if n == 0 {
beego.Warning("User principal does not match password. Current:", currentUser)
return nil, nil
} else {
return &user[0], nil
} }
if n == 0 {
log.Warning("User principal does not match password. Current:", currentUser)
return nil, nil
}
return &user[0], nil
} }
// DeleteUser ... // DeleteUser ...

View File

@ -32,4 +32,6 @@ type Project struct {
Public int `orm:"column(public)"` Public int `orm:"column(public)"`
//This field does not have correspondent column in DB, this is just for UI to disable button //This field does not have correspondent column in DB, this is just for UI to disable button
Togglable bool Togglable bool
UpdateTime time.Time `orm:"update_time" json:"update_time"`
} }

View File

@ -16,33 +16,19 @@
package models package models
const ( const (
//SYSADMIN system administrator
SYSADMIN = 1
//PROJECTADMIN project administrator //PROJECTADMIN project administrator
PROJECTADMIN = 2 PROJECTADMIN = 1
//DEVELOPER developer //DEVELOPER developer
DEVELOPER = 3 DEVELOPER = 2
//GUEST guest //GUEST guest
GUEST = 4 GUEST = 3
) )
// Role holds the details of a role. // Role holds the details of a role.
type Role struct { type Role struct {
RoleID int `json:"role_id" orm:"column(role_id)"` RoleID int `orm:"column(role_id)" json:"role_id"`
RoleCode string `json:"role_code" orm:"column(role_code)"` RoleCode string `orm:"column(role_code)" json:"role_code"`
Name string `json:"role_name" orm:"column(name)"` Name string `orm:"column(name)" json:"role_name"`
}
// ProjectRole holds information about the relationship of project and role. RoleMask int `orm:"role_mask" json:"role_mask"`
type ProjectRole struct {
PrID int `orm:"column(pr_id)" json:"PrId"`
ProjectID int64 `orm:"column(project_id)" json:"ProjectId"`
RoleID int `orm:"column(role_id)" json:"RoleId"`
}
// UserProjectRole holds information about relationship of user, project and role.
type UserProjectRole struct {
UprID int `orm:"column(upr_id)" json:"UprId"`
UserID int `orm:"column(user_id)" json:"UserId"`
PrID int64 `orm:"column(pr_id)" json:"PrId"`
} }

View File

@ -15,6 +15,10 @@
package models package models
import (
"time"
)
// User holds the details of a user. // User holds the details of a user.
type User struct { type User struct {
UserID int `orm:"column(user_id)" json:"UserId"` UserID int `orm:"column(user_id)" json:"UserId"`
@ -27,7 +31,10 @@ type User struct {
Rolename string Rolename string
RoleID int `json:"RoleId"` RoleID int `json:"RoleId"`
RoleList []Role RoleList []Role
HasAdminRole int HasAdminRole int `orm:"column(sysadmin_flag)"`
ResetUUID string `orm:"column(reset_uuid)" json:"ResetUuid"` ResetUUID string `orm:"column(reset_uuid)" json:"ResetUuid"`
Salt string `orm:"column(salt)"` Salt string `orm:"column(salt)"`
CreationTime time.Time `orm:"creation_time" json:"creation_time"`
UpdateTime time.Time `orm:"update_time" json:"update_time"`
} }

View File

@ -332,7 +332,6 @@ jQuery(function(){
getUserRoleCallback(userId); getUserRoleCallback(userId);
}); });
$("#tblUser .glyphicon-trash").on("click", function(){ $("#tblUser .glyphicon-trash").on("click", function(){
var roleId = $(this).attr("roleid");
var userId = $(this).attr("userid"); var userId = $(this).attr("userid");
new AjaxUtil({ new AjaxUtil({
url: "/api/projects/" + $("#projectId").val() + "/members/" + userId, url: "/api/projects/" + $("#projectId").val() + "/members/" + userId,

View File

@ -197,15 +197,15 @@
<label for="txtRole" class="control-label">{{i18n .Lang "role"}}:</label> <label for="txtRole" class="control-label">{{i18n .Lang "role"}}:</label>
<ul class="list-group" id="lstRole"> <ul class="list-group" id="lstRole">
<li class="list-group-item"> <li class="list-group-item">
<input type="radio" name="chooseRole" id="chkRole2" value="2"> <input type="radio" name="chooseRole" id="chkRole2" value="1">
<label for="chkRole2" class="control-label">Project Admin</label> <label for="chkRole2" class="control-label">Project Admin</label>
</li> </li>
<li class="list-group-item"> <li class="list-group-item">
<input type="radio" name="chooseRole" id="chkRole3" value="3"> <input type="radio" name="chooseRole" id="chkRole3" value="2">
<label for="chkRole3" class="control-label">Developer</label> <label for="chkRole3" class="control-label">Developer</label>
</li> </li>
<li class="list-group-item"> <li class="list-group-item">
<input type="radio" name="chooseRole" id="chkRole4" value="4"> <input type="radio" name="chooseRole" id="chkRole4" value="3">
<label for="chkRole4" class="control-label">Guest</label> <label for="chkRole4" class="control-label">Guest</label>
</li> </li>
</ul> </ul>