mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 00:57:44 +01:00
db_role_refactor
This commit is contained in:
parent
ac5bbc4657
commit
f1a2942f6a
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
76
dao/role.go
76
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
|
||||
}
|
||||
|
@ -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"`
|
||||
|
@ -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,
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user