mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-21 14:21:36 +01:00
Change status code for projects API
Update to projects API so it will not differentiate if a project does not exist or the user doesn't have permission to access it. Signed-off-by: Daniel Jiang <jiangd@vmware.com>
This commit is contained in:
parent
c993103e01
commit
f73aa3ce80
@ -84,24 +84,20 @@ func (b *BaseController) RequireAuthenticated() bool {
|
||||
|
||||
// HasProjectPermission returns true when the request has action permission on project subresource
|
||||
func (b *BaseController) HasProjectPermission(projectIDOrName interface{}, action rbac.Action, subresource ...rbac.Resource) (bool, error) {
|
||||
projectID, projectName, err := utils.ParseProjectIDOrName(projectIDOrName)
|
||||
_, _, err := utils.ParseProjectIDOrName(projectIDOrName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if projectName != "" {
|
||||
project, err := b.ProjectMgr.Get(projectName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if project == nil {
|
||||
return false, errors.NotFoundError(nil).WithMessage("project %s not found", projectName)
|
||||
}
|
||||
|
||||
projectID = project.ProjectID
|
||||
project, err := b.ProjectMgr.Get(projectIDOrName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if project == nil {
|
||||
return false, errors.NotFoundError(fmt.Errorf("project %v not found", projectIDOrName))
|
||||
}
|
||||
|
||||
resource := rbac.NewProjectNamespace(projectID).Resource(subresource...)
|
||||
resource := rbac.NewProjectNamespace(project.ProjectID).Resource(subresource...)
|
||||
if !b.SecurityCtx.Can(action, resource) {
|
||||
return false, nil
|
||||
}
|
||||
@ -114,24 +110,42 @@ func (b *BaseController) HasProjectPermission(projectIDOrName interface{}, actio
|
||||
func (b *BaseController) RequireProjectAccess(projectIDOrName interface{}, action rbac.Action, subresource ...rbac.Resource) bool {
|
||||
hasPermission, err := b.HasProjectPermission(projectIDOrName, action, subresource...)
|
||||
if err != nil {
|
||||
b.SendError(err)
|
||||
|
||||
if errors.IsNotFoundErr(err) {
|
||||
b.handleProjectNotFound(projectIDOrName)
|
||||
} else {
|
||||
b.SendError(err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if !hasPermission {
|
||||
if !b.SecurityCtx.IsAuthenticated() {
|
||||
b.SendError(errors.UnauthorizedError(errors.New("Unauthorized")))
|
||||
} else {
|
||||
b.SendError(errors.New(errors.New(b.SecurityCtx.GetUsername())).WithCode(errors.ForbiddenCode))
|
||||
}
|
||||
|
||||
b.SendPermissionError()
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// This should be called when a project is not found, if the caller is a system admin it returns 404.
|
||||
// If it's regular user, it will render permission error
|
||||
func (b *BaseController) handleProjectNotFound(projectIDOrName interface{}) {
|
||||
if b.SecurityCtx.IsSysAdmin() {
|
||||
b.SendNotFoundError(fmt.Errorf("project %v not found", projectIDOrName))
|
||||
} else {
|
||||
b.SendPermissionError()
|
||||
}
|
||||
}
|
||||
|
||||
// SendPermissionError is a shortcut for sending different http error based on authentication status.
|
||||
func (b *BaseController) SendPermissionError() {
|
||||
if !b.SecurityCtx.IsAuthenticated() {
|
||||
b.SendUnAuthorizedError(errors.New("UnAuthorized"))
|
||||
} else {
|
||||
b.SendForbiddenError(errors.New(b.SecurityCtx.GetUsername()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// WriteJSONData writes the JSON data to the client.
|
||||
func (b *BaseController) WriteJSONData(object interface{}) {
|
||||
b.Data["json"] = object
|
||||
|
@ -69,7 +69,7 @@ func (m *MetadataAPI) Prepare() {
|
||||
}
|
||||
|
||||
if project == nil {
|
||||
m.SendNotFoundError(fmt.Errorf("project %d not found", id))
|
||||
m.handleProjectNotFound(id)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -65,10 +65,10 @@ func TestValidateProjectMetadata(t *testing.T) {
|
||||
func TestMetaAPI(t *testing.T) {
|
||||
client := newHarborAPI()
|
||||
|
||||
// non-exist project
|
||||
// non-exist project, it should return 401 if user is not logged in.
|
||||
code, _, err := client.PostMeta(*unknownUsr, int64(1000), nil)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, http.StatusNotFound, code)
|
||||
assert.Equal(t, http.StatusUnauthorized, code)
|
||||
|
||||
// non-login
|
||||
code, _, err = client.PostMeta(*unknownUsr, int64(1), nil)
|
||||
|
@ -79,7 +79,7 @@ func (p *ProjectAPI) Prepare() {
|
||||
}
|
||||
|
||||
if project == nil {
|
||||
p.SendNotFoundError(fmt.Errorf("project %d not found", id))
|
||||
p.handleProjectNotFound(id)
|
||||
return
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user