db_role_refactor

This commit is contained in:
Wenkai Yin 2016-03-29 12:09:27 +08:00
parent ac5bbc4657
commit f1a2942f6a
11 changed files with 75 additions and 142 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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"`

View File

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

View File

@ -197,15 +197,15 @@
<label for="txtRole" class="control-label">{{i18n .Lang "role"}}:</label>
<ul class="list-group" id="lstRole">
<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>
</li>
<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>
</li>
<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>
</li>
</ul>