harbor/api/member.go

222 lines
7.0 KiB
Go
Raw Normal View History

2016-02-01 12:59:10 +01:00
/*
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.
*/
2016-02-26 11:54:14 +01:00
2016-02-01 12:59:10 +01:00
package api
import (
"net/http"
"strconv"
2016-02-01 12:59:10 +01:00
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/models"
2016-03-28 02:50:09 +02:00
"github.com/vmware/harbor/utils/log"
2016-02-01 12:59:10 +01:00
)
2016-02-26 11:35:55 +01:00
// ProjectMemberAPI handles request to /api/projects/{}/members/{}
2016-02-01 12:59:10 +01:00
type ProjectMemberAPI struct {
BaseAPI
memberID int
currentUserID int
2016-02-01 12:59:10 +01:00
project *models.Project
}
type memberReq struct {
2016-06-01 09:17:05 +02:00
Username string `json:"username"`
UserID int `json:"user_id"`
2016-02-01 12:59:10 +01:00
Roles []int `json:"roles"`
}
2016-02-26 11:35:55 +01:00
// Prepare validates the URL and parms
2016-02-01 12:59:10 +01:00
func (pma *ProjectMemberAPI) Prepare() {
pid, err := strconv.ParseInt(pma.Ctx.Input.Param(":pid"), 10, 64)
if err != nil {
2016-03-28 02:50:09 +02:00
log.Errorf("Error parsing project id: %d, error: %v", pid, err)
pma.CustomAbort(http.StatusBadRequest, "invalid project Id")
2016-02-01 12:59:10 +01:00
return
}
2016-02-26 04:26:54 +01:00
p, err := dao.GetProjectByID(pid)
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
log.Errorf("Error occurred in GetProjectById, error: %v", err)
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
2016-02-01 12:59:10 +01:00
}
if p == nil {
2016-03-28 02:50:09 +02:00
log.Warningf("Project with id: %d does not exist.", pid)
pma.CustomAbort(http.StatusNotFound, "Project does not exist")
2016-02-01 12:59:10 +01:00
}
pma.project = p
pma.currentUserID = pma.ValidateUser()
2016-02-01 12:59:10 +01:00
mid := pma.Ctx.Input.Param(":mid")
if mid == "current" {
pma.memberID = pma.currentUserID
2016-02-01 12:59:10 +01:00
} else if len(mid) == 0 {
pma.memberID = 0
2016-02-01 12:59:10 +01:00
} else if len(mid) > 0 {
memberID, err := strconv.Atoi(mid)
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
log.Errorf("Invalid member Id, error: %v", err)
pma.CustomAbort(http.StatusBadRequest, "Invalid member id")
2016-02-01 12:59:10 +01:00
}
pma.memberID = memberID
2016-02-01 12:59:10 +01:00
}
}
2016-02-26 11:35:55 +01:00
// Get ...
2016-02-01 12:59:10 +01:00
func (pma *ProjectMemberAPI) Get() {
2016-02-26 03:15:01 +01:00
pid := pma.project.ProjectID
2016-02-26 11:35:55 +01:00
if !checkProjectPermission(pma.currentUserID, pid) {
2016-03-28 02:50:09 +02:00
log.Warningf("Current user, user id: %d does not have permission for project, id: %d", pma.currentUserID, pid)
pma.RenderError(http.StatusForbidden, "")
2016-02-01 12:59:10 +01:00
return
}
if pma.memberID == 0 { //member id not set return list of the members
2016-02-01 12:59:10 +01:00
username := pma.GetString("username")
queryUser := models.User{Username: "%" + username + "%"}
2016-02-24 11:16:16 +01:00
userList, err := dao.GetUserByProject(pid, queryUser)
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
log.Errorf("Failed to query database for member list, error: %v", err)
pma.RenderError(http.StatusInternalServerError, "Internal Server Error")
2016-02-01 12:59:10 +01:00
return
}
pma.Data["json"] = userList
} else { //return detail of a member
roleList, err := listRoles(pma.memberID, pid)
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
2016-02-01 12:59:10 +01:00
}
//return empty role list to indicate if a user is not a member
result := make(map[string]interface{})
2016-02-26 03:15:01 +01:00
user, err := dao.GetUser(models.User{UserID: pma.memberID})
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
log.Errorf("Error occurred in GetUser, error: %v", err)
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
2016-02-01 12:59:10 +01:00
}
2016-06-01 09:17:05 +02:00
result["username"] = user.Username
result["user_id"] = pma.memberID
2016-02-01 12:59:10 +01:00
result["roles"] = roleList
pma.Data["json"] = result
}
pma.ServeJSON()
}
2016-02-26 11:35:55 +01:00
// Post ...
2016-02-01 12:59:10 +01:00
func (pma *ProjectMemberAPI) Post() {
currentUserID := pma.currentUserID
projectID := pma.project.ProjectID
if !hasProjectAdminRole(currentUserID, projectID) {
log.Warningf("Current user, id: %d does not have project admin role for project, id:", currentUserID, projectID)
pma.RenderError(http.StatusForbidden, "")
2016-02-01 12:59:10 +01:00
return
}
2016-03-29 06:09:27 +02:00
2016-02-01 12:59:10 +01:00
var req memberReq
pma.DecodeJSONReq(&req)
2016-02-01 12:59:10 +01:00
username := req.Username
2016-02-26 11:35:55 +01:00
userID := checkUserExists(username)
if userID <= 0 {
2016-03-28 02:50:09 +02:00
log.Warningf("User does not exist, user name: %s", username)
pma.RenderError(http.StatusNotFound, "User does not exist")
2016-02-01 12:59:10 +01:00
return
}
rolelist, err := dao.GetUserProjectRoles(userID, projectID)
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
2016-02-01 12:59:10 +01:00
}
if len(rolelist) > 0 {
log.Warningf("user is already added to project, user id: %d, project id: %d", userID, projectID)
pma.RenderError(http.StatusConflict, "user is ready in project")
2016-02-01 12:59:10 +01:00
return
}
2016-09-19 11:58:29 +02:00
if len(req.Roles) <= 0 || len(req.Roles) > 1 {
pma.CustomAbort(http.StatusBadRequest, "only one role is supported")
}
rid := req.Roles[0]
if !(rid == models.PROJECTADMIN ||
rid == models.DEVELOPER ||
rid == models.GUEST) {
pma.CustomAbort(http.StatusBadRequest, "invalid role")
}
err = dao.AddProjectMember(projectID, userID, rid)
if err != nil {
log.Errorf("Failed to update DB to add project user role, project id: %d, user id: %d, role id: %d", projectID, userID, rid)
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
return
2016-02-01 12:59:10 +01:00
}
}
2016-02-26 11:35:55 +01:00
// Put ...
2016-02-01 12:59:10 +01:00
func (pma *ProjectMemberAPI) Put() {
currentUserID := pma.currentUserID
2016-02-26 03:15:01 +01:00
pid := pma.project.ProjectID
if !hasProjectAdminRole(currentUserID, pid) {
log.Warningf("Current user, id: %d does not have project admin role for project, id:", currentUserID, pid)
pma.RenderError(http.StatusForbidden, "")
2016-02-01 12:59:10 +01:00
return
}
mid := pma.memberID
2016-02-01 12:59:10 +01:00
var req memberReq
pma.DecodeJSONReq(&req)
2016-03-29 06:09:27 +02:00
roleList, err := dao.GetUserProjectRoles(mid, pid)
2016-02-01 12:59:10 +01:00
if len(roleList) == 0 {
2016-03-28 02:50:09 +02:00
log.Warningf("User is not in project, user id: %d, project id: %d", mid, pid)
pma.RenderError(http.StatusNotFound, "user not exist in project")
2016-02-01 12:59:10 +01:00
return
}
//TODO: delete and insert should in one transaction
//delete user project role record for the given user
2016-03-28 09:34:41 +02:00
err = dao.DeleteProjectMember(pid, mid)
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
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")
2016-02-01 12:59:10 +01:00
return
}
//insert roles in request
for _, rid := range req.Roles {
2016-03-29 06:09:27 +02:00
err = dao.AddProjectMember(pid, mid, int(rid))
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
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")
2016-02-01 12:59:10 +01:00
return
}
}
}
2016-02-26 11:35:55 +01:00
// Delete ...
2016-02-01 12:59:10 +01:00
func (pma *ProjectMemberAPI) Delete() {
currentUserID := pma.currentUserID
2016-02-26 03:15:01 +01:00
pid := pma.project.ProjectID
if !hasProjectAdminRole(currentUserID, pid) {
log.Warningf("Current user, id: %d does not have project admin role for project, id:", currentUserID, pid)
pma.RenderError(http.StatusForbidden, "")
2016-02-01 12:59:10 +01:00
return
}
mid := pma.memberID
err := dao.DeleteProjectMember(pid, mid)
2016-02-01 12:59:10 +01:00
if err != nil {
2016-03-28 02:50:09 +02:00
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")
2016-02-01 12:59:10 +01:00
return
}
}