From f1a2942f6aafe46801e219814de37f54b9647d43 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Tue, 29 Mar 2016 12:09:27 +0800 Subject: [PATCH] db_role_refactor --- api/member.go | 69 ++++++++++++++++----------- api/project.go | 14 ++++-- api/utils.go | 2 +- controllers/itemdetail.go | 7 +-- dao/dao_test.go | 11 ++--- dao/project.go | 2 +- dao/projectmember.go | 18 ++----- dao/role.go | 76 ++---------------------------- models/role.go | 11 ++--- static/resources/js/item-detail.js | 1 - views/item-detail.tpl | 6 +-- 11 files changed, 75 insertions(+), 142 deletions(-) diff --git a/api/member.go b/api/member.go index d7ee03545..2d32d7318 100644 --- a/api/member.go +++ b/api/member.go @@ -16,7 +16,6 @@ package api import ( - "fmt" "net/http" "strconv" @@ -24,7 +23,6 @@ import ( "github.com/vmware/harbor/models" "github.com/astaxie/beego" - "github.com/vmware/harbor/utils/log" ) // ProjectMemberAPI handles request to /api/projects/{}/members/{} @@ -95,7 +93,7 @@ func (pma *ProjectMemberAPI) Get() { } pma.Data["json"] = userList } 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 { beego.Error("Error occurred in GetUserProjectRoles:", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") @@ -118,17 +116,27 @@ func (pma *ProjectMemberAPI) Get() { // Post ... func (pma *ProjectMemberAPI) Post() { 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 { beego.Error("Error occurred in GetUserProjectRoles:", err) 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 { beego.Warning("Current user, id:", pma.currentUserID, "does not have project admin role for project, id:", pid) pma.RenderError(http.StatusForbidden, "") return } + var req memberReq pma.DecodeJSONReq(&req) username := req.Username @@ -138,7 +146,7 @@ func (pma *ProjectMemberAPI) Post() { pma.RenderError(http.StatusNotFound, "User does not exist") return } - rolelist, err = dao.GetUserProjectRoles(models.User{UserID: userID}, pid) + rolelist, err = dao.GetUserProjectRoles(userID, pid) if err != nil { beego.Error("Error occurred in GetUserProjectRoles:", err) pma.CustomAbort(http.StatusInternalServerError, "Internal error.") @@ -150,13 +158,7 @@ func (pma *ProjectMemberAPI) Post() { } for _, rid := range req.Roles { - role, err := dao.IntToRole(rid) - if err != nil { - log.Error(err) - pma.RenderError(http.StatusBadRequest, fmt.Sprintf("Invalid role: %d", rid)) - } - - err = dao.AddProjectMember(pid, userID, role) + err = dao.AddProjectMember(pid, userID, int(rid)) if err != nil { beego.Error("Failed to update DB to add project user role, project id:", pid, ", user id:", userID, ", role id:", rid) pma.RenderError(http.StatusInternalServerError, "Failed to update data in database") @@ -169,20 +171,29 @@ func (pma *ProjectMemberAPI) Post() { func (pma *ProjectMemberAPI) Put() { pid := pma.project.ProjectID 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 { beego.Error("Error occurred in GetUserProjectRoles:", err) 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 { beego.Warning("Current user, id:", pma.currentUserID, ", does not have project admin role for project, id:", pid) pma.RenderError(http.StatusForbidden, "") return } var req memberReq pma.DecodeJSONReq(&req) - roleList, err := dao.GetUserProjectRoles(models.User{UserID: mid}, pid) + roleList, err := dao.GetUserProjectRoles(mid, pid) if len(roleList) == 0 { beego.Warning("User is not in project, user id:", mid, ", project id:", pid) pma.RenderError(http.StatusNotFound, "user not exist in project") @@ -198,13 +209,7 @@ func (pma *ProjectMemberAPI) Put() { } //insert roles in request for _, rid := range req.Roles { - role, err := dao.IntToRole(rid) - if err != nil { - log.Error(err) - pma.RenderError(http.StatusBadRequest, fmt.Sprintf("Invalid role: %d", rid)) - } - - err = dao.AddProjectMember(pid, mid, role) + err = dao.AddProjectMember(pid, mid, int(rid)) if err != nil { beego.Error("Failed to update DB to add project user role, project id:", pid, ", user id:", mid, ", role id:", rid) pma.RenderError(http.StatusInternalServerError, "Failed to update data in database") @@ -217,9 +222,17 @@ func (pma *ProjectMemberAPI) Put() { func (pma *ProjectMemberAPI) Delete() { pid := pma.project.ProjectID mid := pma.memberID - userQuery := models.User{UserID: pma.currentUserID, RoleID: models.PROJECTADMIN} - rolelist, err := dao.GetUserProjectRoles(userQuery, pid) - if len(rolelist) == 0 { + + rolelist, err := dao.GetUserProjectRoles(pma.currentUserID, pid) + hasProjectAdminRole := false + for _, role := range rolelist { + if role.RoleID == models.PROJECTADMIN { + hasProjectAdminRole = true + break + } + } + + if !hasProjectAdminRole { beego.Warning("Current user, id:", pma.currentUserID, ", does not have project admin role for project, id:", pid) pma.RenderError(http.StatusForbidden, "") return diff --git a/api/project.go b/api/project.go index fc8c86f33..2b8656e0c 100644 --- a/api/project.go +++ b/api/project.go @@ -189,13 +189,21 @@ func (p *ProjectAPI) FilterAccessLog() { } func isProjectAdmin(userID int, pid int64) bool { - userQuery := models.User{UserID: userID, RoleID: models.PROJECTADMIN} - rolelist, err := dao.GetUserProjectRoles(userQuery, pid) + rolelist, err := dao.GetUserProjectRoles(userID, pid) if err != nil { beego.Error("Error occurred in GetUserProjectRoles:", err, ", returning 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 { diff --git a/api/utils.go b/api/utils.go index 700bf9fb9..84ef6327c 100644 --- a/api/utils.go +++ b/api/utils.go @@ -31,7 +31,7 @@ func checkProjectPermission(userID int, projectID int64) bool { if exist { return true } - roleList, err := dao.GetUserProjectRoles(models.User{UserID: userID}, projectID) + roleList, err := dao.GetUserProjectRoles(userID, projectID) if err != nil { beego.Error("Error occurred in GetUserProjectRoles:", err) return false diff --git a/controllers/itemdetail.go b/controllers/itemdetail.go index 95d393fb9..e13fe146f 100644 --- a/controllers/itemdetail.go +++ b/controllers/itemdetail.go @@ -21,7 +21,6 @@ import ( "os" "github.com/vmware/harbor/dao" - "github.com/vmware/harbor/models" "github.com/astaxie/beego" ) @@ -69,7 +68,7 @@ func (idc *ItemDetailController) Get() { idc.Data["Username"] = idc.GetSession("username") idc.Data["UserId"] = userID - roleList, err := dao.GetUserProjectRoles(models.User{UserID: userID}, projectID) + roleList, err := dao.GetUserProjectRoles(userID, projectID) if err != nil { beego.Error("Error occurred in GetUserProjectRoles:", err) idc.CustomAbort(http.StatusInternalServerError, "Internal error.") @@ -86,9 +85,7 @@ func (idc *ItemDetailController) Get() { return } - if isAdmin { - idc.Data["RoleId"] = models.SYSADMIN - } else if len(roleList) > 0 { + if len(roleList) > 0 { idc.Data["RoleId"] = roleList[0].RoleID } } diff --git a/dao/dao_test.go b/dao/dao_test.go index 96ecbc351..e65c1bb42 100644 --- a/dao/dao_test.go +++ b/dao/dao_test.go @@ -539,10 +539,9 @@ func TestQueryProject(t *testing.T) { } func TestGetUserProjectRoles(t *testing.T) { - user := *currentUser - r, err := GetUserProjectRoles(user, currentProject.ProjectID) + r, err := GetUserProjectRoles(currentUser.UserID, currentProject.ProjectID) 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. @@ -579,12 +578,12 @@ func TestQueryRelevantProjects(t *testing.T) { } func TestAddProjectMember(t *testing.T) { - err := AddProjectMember(currentProject.ProjectID, 1, Developer) + err := AddProjectMember(currentProject.ProjectID, 1, models.DEVELOPER) if err != nil { t.Errorf("Error occurred in AddProjectMember: %v", err) } - roles, err := GetUserProjectRoles(models.User{UserID: 1}, currentProject.ProjectID) + roles, err := GetUserProjectRoles(1, currentProject.ProjectID) if err != nil { t.Errorf("Error occurred in GetUserProjectRoles: %v", err) } @@ -608,7 +607,7 @@ func TestDeleteProjectMember(t *testing.T) { t.Errorf("Error occurred in DeleteProjectMember: %v", err) } - roles, err := GetUserProjectRoles(models.User{UserID: 1}, currentProject.ProjectID) + roles, err := GetUserProjectRoles(1, currentProject.ProjectID) if err != nil { t.Errorf("Error occurred in GetUserProjectRoles: %v", err) } diff --git a/dao/project.go b/dao/project.go index 6582d26f2..78f8ec7cc 100644 --- a/dao/project.go +++ b/dao/project.go @@ -56,7 +56,7 @@ func AddProject(project models.Project) error { return err } - if err = AddProjectMember(projectID, project.OwnerID, ProjectAdmin); err != nil { + if err = AddProjectMember(projectID, project.OwnerID, models.PROJECTADMIN); err != nil { return err } diff --git a/dao/projectmember.go b/dao/projectmember.go index fac182444..a4357bc38 100644 --- a/dao/projectmember.go +++ b/dao/projectmember.go @@ -21,17 +21,12 @@ import ( ) // AddProjectMember inserts a record to table project_member -func AddProjectMember(projectID int64, userID int, r role) error { +func AddProjectMember(projectID int64, userID int, role int) error { o := orm.NewOrm() sql := "insert into project_member (project_id, user_id , role) values (?, ?, ?)" - rr, err := getRole(r) - if err != nil { - return err - } - - if _, err = o.Raw(sql, projectID, userID, rr.RoleID).Exec(); err != nil { + if _, err := o.Raw(sql, projectID, userID, role).Exec(); err != nil { return err } @@ -39,17 +34,12 @@ func AddProjectMember(projectID int64, userID int, r role) error { } // UpdateProjectMember updates the record in table project_member -func UpdateProjectMember(projectID int64, userID int, r role) error { +func UpdateProjectMember(projectID int64, userID int, role int) error { o := orm.NewOrm() sql := "update project_member set role = ? where project_id = ? and user_id = ?" - rr, err := getRole(r) - if err != nil { - return err - } - - if _, err := o.Raw(sql, rr.RoleID, projectID, userID).Exec(); err != nil { + if _, err := o.Raw(sql, role, projectID, userID).Exec(); err != nil { return err } diff --git a/dao/role.go b/dao/role.go index 28d8d3ea7..210e1949b 100644 --- a/dao/role.go +++ b/dao/role.go @@ -16,41 +16,12 @@ package dao import ( - "fmt" - - "github.com/vmware/harbor/models" - "github.com/astaxie/beego/orm" + "github.com/vmware/harbor/models" ) -type role int - -// Start from 2 to guarantee the compatibility with former code -const ( - ProjectAdmin role = 2 - Developer = 3 - Guest = 4 -) - -var roleList = make(map[role]*models.Role) - -// IntToRole is used to convert int to role. -func IntToRole(i int) (r role, err error) { - switch i { - case 2: - r = ProjectAdmin - case 3: - r = Developer - case 4: - r = Guest - default: - err = fmt.Errorf("no role is correspondent with the input: %d", i) - } - return -} - // 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() @@ -62,11 +33,9 @@ func GetUserProjectRoles(userQuery models.User, projectID int64) ([]models.Role, from project_member where project_id = ? and user_id = ? )` - queryParam := make([]interface{}, 1) - queryParam = append(queryParam, userQuery.UserID) var roleList []models.Role - _, err := o.Raw(sql, projectID, userQuery.UserID).QueryRows(&roleList) + _, err := o.Raw(sql, projectID, userID).QueryRows(&roleList) if err != nil { return nil, err @@ -88,42 +57,3 @@ func IsAdminRole(userID int) (bool, error) { return user.HasAdminRole == 1, nil } - -func getRole(r role) (*models.Role, error) { - if roleList[r] != nil { - return roleList[r], nil - } - - o := orm.NewOrm() - var roles []*models.Role - - sql := "select role_id, role_code, name, role_mask from role" - - _, err := o.Raw(sql).QueryRows(&roles) - if err != nil { - return nil, err - } - - for _, rr := range roles { - if rr.RoleCode == "MDRWS" { - roleList[ProjectAdmin] = rr - continue - } - - if rr.RoleCode == "RWS" { - roleList[Developer] = rr - continue - } - - if rr.RoleCode == "RS" { - roleList[Guest] = rr - continue - } - } - - if roleList[r] == nil { - return nil, fmt.Errorf("unsupported role type: %v", r) - } - - return roleList[r], nil -} diff --git a/models/role.go b/models/role.go index 169e17ae7..34a9400bc 100644 --- a/models/role.go +++ b/models/role.go @@ -15,18 +15,15 @@ package models -/* const ( - //SYSADMIN system administrator - SYSADMIN = 1 //PROJECTADMIN project administrator - PROJECTADMIN = 2 + PROJECTADMIN = 1 //DEVELOPER developer - DEVELOPER = 3 + DEVELOPER = 2 //GUEST guest - GUEST = 4 + GUEST = 3 ) -*/ + // Role holds the details of a role. type Role struct { RoleID int `orm:"column(role_id)" json:"role_id"` diff --git a/static/resources/js/item-detail.js b/static/resources/js/item-detail.js index 4b4477cd7..e13075ecf 100644 --- a/static/resources/js/item-detail.js +++ b/static/resources/js/item-detail.js @@ -332,7 +332,6 @@ jQuery(function(){ getUserRoleCallback(userId); }); $("#tblUser .glyphicon-trash").on("click", function(){ - var roleId = $(this).attr("roleid"); var userId = $(this).attr("userid"); new AjaxUtil({ url: "/api/projects/" + $("#projectId").val() + "/members/" + userId, diff --git a/views/item-detail.tpl b/views/item-detail.tpl index daa038c07..a1ce83e96 100644 --- a/views/item-detail.tpl +++ b/views/item-detail.tpl @@ -197,15 +197,15 @@