mirror of
https://github.com/goharbor/harbor
synced 2025-04-24 02:28:13 +00:00
1. user can get repositories of public project without login 2. add basic auth support for repository API 3. system admin can CRUD members of all projects
This commit is contained in:
parent
91ef155da5
commit
6cd1813b86
@ -114,23 +114,10 @@ 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(pma.currentUserID, pid)
|
||||
if err != nil {
|
||||
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
|
||||
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
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:", pma.currentUserID, pid)
|
||||
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, "")
|
||||
return
|
||||
}
|
||||
@ -144,21 +131,21 @@ func (pma *ProjectMemberAPI) Post() {
|
||||
pma.RenderError(http.StatusNotFound, "User does not exist")
|
||||
return
|
||||
}
|
||||
rolelist, err = dao.GetUserProjectRoles(userID, pid)
|
||||
rolelist, err := dao.GetUserProjectRoles(userID, projectID)
|
||||
if err != nil {
|
||||
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
|
||||
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
if len(rolelist) > 0 {
|
||||
log.Warningf("user is already added to project, user id: %d, project id: %d", userID, pid)
|
||||
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")
|
||||
return
|
||||
}
|
||||
|
||||
for _, rid := range req.Roles {
|
||||
err = dao.AddProjectMember(pid, userID, int(rid))
|
||||
err = dao.AddProjectMember(projectID, userID, int(rid))
|
||||
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", projectID, userID, rid)
|
||||
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
|
||||
return
|
||||
}
|
||||
@ -167,27 +154,16 @@ func (pma *ProjectMemberAPI) Post() {
|
||||
|
||||
// Put ...
|
||||
func (pma *ProjectMemberAPI) Put() {
|
||||
currentUserID := pma.currentUserID
|
||||
pid := pma.project.ProjectID
|
||||
mid := pma.memberID
|
||||
|
||||
rolelist, err := dao.GetUserProjectRoles(pma.currentUserID, pid)
|
||||
if err != nil {
|
||||
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
|
||||
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
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)
|
||||
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, "")
|
||||
return
|
||||
}
|
||||
|
||||
mid := pma.memberID
|
||||
|
||||
var req memberReq
|
||||
pma.DecodeJSONReq(&req)
|
||||
roleList, err := dao.GetUserProjectRoles(mid, pid)
|
||||
@ -217,51 +193,20 @@ func (pma *ProjectMemberAPI) Put() {
|
||||
|
||||
// Delete ...
|
||||
func (pma *ProjectMemberAPI) Delete() {
|
||||
currentUserID := pma.currentUserID
|
||||
pid := pma.project.ProjectID
|
||||
mid := pma.memberID
|
||||
|
||||
rolelist, err := dao.GetUserProjectRoles(pma.currentUserID, pid)
|
||||
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)
|
||||
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, "")
|
||||
return
|
||||
}
|
||||
err = dao.DeleteProjectMember(pid, mid)
|
||||
|
||||
mid := pma.memberID
|
||||
|
||||
err := dao.DeleteProjectMember(pid, mid)
|
||||
if err != nil {
|
||||
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")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//sysadmin has all privileges to all projects
|
||||
func listRoles(userID int, projectID int64) ([]models.Role, error) {
|
||||
roles := make([]models.Role, 1)
|
||||
isSysAdmin, err := dao.IsAdminRole(userID)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
}
|
||||
if isSysAdmin {
|
||||
role, err := dao.GetRoleByID(models.PROJECTADMIN)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
}
|
||||
roles = append(roles, *role)
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
rs, err := dao.GetUserProjectRoles(userID, projectID)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
}
|
||||
roles = append(roles, rs...)
|
||||
return roles, nil
|
||||
}
|
||||
|
@ -38,19 +38,19 @@ import (
|
||||
// the security of registry
|
||||
type RepositoryAPI struct {
|
||||
BaseAPI
|
||||
userID int
|
||||
//userID int
|
||||
}
|
||||
|
||||
// Prepare will set a non existent user ID in case the request tries to view repositories under a project he doesn't has permission.
|
||||
func (ra *RepositoryAPI) Prepare() {
|
||||
ra.userID = ra.ValidateUser()
|
||||
}
|
||||
//func (ra *RepositoryAPI) Prepare() {
|
||||
// ra.userID = ra.ValidateUser()
|
||||
//}
|
||||
|
||||
// Get ...
|
||||
func (ra *RepositoryAPI) Get() {
|
||||
projectID, err0 := ra.GetInt64("project_id")
|
||||
if err0 != nil {
|
||||
log.Errorf("Failed to get project id, error: %v", err0)
|
||||
projectID, err := ra.GetInt64("project_id")
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get project id, error: %v", err)
|
||||
ra.RenderError(http.StatusBadRequest, "Invalid project id")
|
||||
return
|
||||
}
|
||||
@ -64,9 +64,14 @@ func (ra *RepositoryAPI) Get() {
|
||||
ra.RenderError(http.StatusNotFound, "")
|
||||
return
|
||||
}
|
||||
if p.Public == 0 && !checkProjectPermission(ra.userID, projectID) {
|
||||
ra.RenderError(http.StatusForbidden, "")
|
||||
return
|
||||
|
||||
if p.Public == 0 {
|
||||
userID := ra.ValidateUser()
|
||||
|
||||
if !checkProjectPermission(userID, projectID) {
|
||||
ra.RenderError(http.StatusForbidden, "")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
repoList, err := svc_utils.GetRepoFromCache()
|
||||
@ -239,15 +244,44 @@ func (ra *RepositoryAPI) GetManifests() {
|
||||
}
|
||||
|
||||
func (ra *RepositoryAPI) initializeRepositoryClient(repoName string) (r *registry.Repository, err error) {
|
||||
u := models.User{
|
||||
UserID: ra.userID,
|
||||
}
|
||||
user, err := dao.GetUser(u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var username string
|
||||
var sessionUsername, sessionUserID interface{}
|
||||
|
||||
// get username from basic auth
|
||||
username, _, ok := ra.Ctx.Request.BasicAuth()
|
||||
if ok {
|
||||
goto enter
|
||||
}
|
||||
|
||||
// get username from session
|
||||
sessionUsername = ra.GetSession("username")
|
||||
if sessionUsername != nil {
|
||||
username, ok = sessionUsername.(string)
|
||||
if ok {
|
||||
goto enter
|
||||
}
|
||||
}
|
||||
|
||||
// if username does not exist in session, try to get userId from sessiion
|
||||
// and then get username from DB according to the userId
|
||||
sessionUserID = ra.GetSession("userId")
|
||||
if sessionUserID != nil {
|
||||
userID, ok := sessionUserID.(int)
|
||||
if ok {
|
||||
u := models.User{
|
||||
UserID: userID,
|
||||
}
|
||||
user, err := dao.GetUser(u)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
username = user.Username
|
||||
goto enter
|
||||
}
|
||||
}
|
||||
|
||||
enter:
|
||||
endpoint := os.Getenv("REGISTRY_URL")
|
||||
|
||||
return registry.NewRepositoryWithUsername(repoName, endpoint, user.Username)
|
||||
return registry.NewRepositoryWithUsername(repoName, endpoint, username)
|
||||
}
|
||||
|
48
api/utils.go
48
api/utils.go
@ -22,20 +22,52 @@ import (
|
||||
)
|
||||
|
||||
func checkProjectPermission(userID int, projectID int64) bool {
|
||||
exist, err := dao.IsAdminRole(userID)
|
||||
roles, err := listRoles(userID, projectID)
|
||||
if err != nil {
|
||||
log.Errorf("Error occurred in IsAdminRole, error: %v", err)
|
||||
log.Errorf("error occurred in getProjectPermission: %v", err)
|
||||
return false
|
||||
}
|
||||
if exist {
|
||||
return true
|
||||
}
|
||||
roleList, err := dao.GetUserProjectRoles(userID, projectID)
|
||||
return len(roles) > 0
|
||||
}
|
||||
|
||||
func hasProjectAdminRole(userID int, projectID int64) bool {
|
||||
roles, err := listRoles(userID, projectID)
|
||||
if err != nil {
|
||||
log.Errorf("Error occurred in GetUserProjectRoles, error: %v", err)
|
||||
log.Errorf("error occurred in getProjectPermission: %v", err)
|
||||
return false
|
||||
}
|
||||
return len(roleList) > 0
|
||||
|
||||
for _, role := range roles {
|
||||
if role.RoleID == models.PROJECTADMIN {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
//sysadmin has all privileges to all projects
|
||||
func listRoles(userID int, projectID int64) ([]models.Role, error) {
|
||||
roles := make([]models.Role, 1)
|
||||
isSysAdmin, err := dao.IsAdminRole(userID)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
}
|
||||
if isSysAdmin {
|
||||
role, err := dao.GetRoleByID(models.PROJECTADMIN)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
}
|
||||
roles = append(roles, *role)
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
rs, err := dao.GetUserProjectRoles(userID, projectID)
|
||||
if err != nil {
|
||||
return roles, err
|
||||
}
|
||||
roles = append(roles, rs...)
|
||||
return roles, nil
|
||||
}
|
||||
|
||||
func checkUserExists(name string) int {
|
||||
|
Loading…
x
Reference in New Issue
Block a user