Add role list in project response

This commit fixes #9771

It compares the roles to return the one with highest permission in the
response of `GET /api/projects`.
In addition to that, it adds the role list to the response, because a
user can have multiple roles in a project.
It also removes the togglable attribute as it's not used anywhere.

Signed-off-by: Daniel Jiang <jiangd@vmware.com>
This commit is contained in:
Daniel Jiang 2019-11-10 15:54:03 +08:00
parent 5cebfd17d2
commit 64dc5122e6
5 changed files with 88 additions and 18 deletions

View File

@ -4871,7 +4871,14 @@ definitions:
description: Correspond to the UI about whether the project's publicity is updatable (for UI)
current_user_role_id:
type: integer
description: The role ID of the current user who triggered the API (for UI)
description: The role ID with highest permission of the current user who triggered the API (for UI)
deprecated: true
current_user_role_ids:
type: array
items:
type: integer
format: int32
description: The list of role ID of the current user who triggered the API (for UI)
repo_count:
type: integer
description: The number of the repositories under this project.

View File

@ -39,8 +39,8 @@ type Project struct {
UpdateTime time.Time `orm:"column(update_time);auto_now" json:"update_time"`
Deleted bool `orm:"column(deleted)" json:"deleted"`
OwnerName string `orm:"-" json:"owner_name"`
Togglable bool `orm:"-" json:"togglable"`
Role int `orm:"-" json:"current_user_role_id"`
RoleList []int `orm:"-" json:"current_user_role_ids"`
RepoCount int64 `orm:"-" json:"repo_count"`
ChartCount uint64 `orm:"-" json:"chart_count"`
Metadata map[string]string `orm:"-" json:"metadata"`

View File

@ -460,14 +460,8 @@ func (p *ProjectAPI) List() {
func (p *ProjectAPI) populateProperties(project *models.Project) error {
if p.SecurityCtx.IsAuthenticated() {
roles := p.SecurityCtx.GetProjectRoles(project.ProjectID)
if len(roles) != 0 {
project.Role = roles[0]
}
if project.Role == common.RoleProjectAdmin ||
p.SecurityCtx.IsSysAdmin() {
project.Togglable = true
}
project.RoleList = roles
project.Role = highestRole(roles)
}
total, err := dao.GetTotalOfRepositories(&models.RepositoryQuery{
@ -712,3 +706,27 @@ func getProjectMemberSummary(projectID int64, summary *models.ProjectSummary) {
wg.Wait()
}
// Returns the highest role in the role list.
// This func should be removed once we deprecate the "current_user_role_id" in project API
// A user can have multiple roles and they may not have a strict ranking relationship
func highestRole(roles []int) int {
if roles == nil {
return 0
}
rolePower := map[int]int{
common.RoleProjectAdmin: 50,
common.RoleMaster: 40,
common.RoleDeveloper: 30,
common.RoleGuest: 20,
common.RoleLimitedGuest: 10,
}
var highest, highestPower int
for _, role := range roles {
if p, ok := rolePower[role]; ok && p > highestPower {
highest = role
highestPower = p
}
}
return highest
}

View File

@ -15,6 +15,7 @@ package api
import (
"fmt"
"github.com/goharbor/harbor/src/common"
"net/http"
"strconv"
"testing"
@ -529,3 +530,54 @@ func TestProjectSummary(t *testing.T) {
fmt.Printf("\n")
}
func TestHighestRole(t *testing.T) {
cases := []struct {
input []int
expect int
}{
{
[]int{},
0,
},
{
[]int{
common.RoleDeveloper,
common.RoleMaster,
common.RoleLimitedGuest,
},
common.RoleMaster,
},
{
[]int{
common.RoleProjectAdmin,
common.RoleMaster,
common.RoleMaster,
},
common.RoleProjectAdmin,
},
{
[]int{
99,
33,
common.RoleLimitedGuest,
},
common.RoleLimitedGuest,
},
{
[]int{
99,
99,
99,
},
0,
},
{
nil,
0,
},
}
for _, c := range cases {
assert.Equal(t, c.expect, highestRole(c.input))
}
}

View File

@ -18,7 +18,6 @@ import (
"fmt"
"strings"
"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/dao"
"github.com/goharbor/harbor/src/common/models"
"github.com/goharbor/harbor/src/common/utils"
@ -96,13 +95,7 @@ func (s *SearchAPI) Get() {
if isAuthenticated {
roles := s.SecurityCtx.GetProjectRoles(p.ProjectID)
if len(roles) != 0 {
p.Role = roles[0]
}
if p.Role == common.RoleProjectAdmin || isSysAdmin {
p.Togglable = true
}
p.Role = highestRole(roles)
}
total, err := dao.GetTotalOfRepositories(&models.RepositoryQuery{