mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix: recode project-role rpc handle to support group role assignment
results by user or project
This commit is contained in:
@@ -66,3 +66,41 @@ func (ra *SRoleAssignment) GetLoginIp() string {
|
||||
func (ra *SRoleAssignment) GetTokenString() string {
|
||||
return "faketoken"
|
||||
}
|
||||
|
||||
type RAInputObject struct {
|
||||
Id string `json:"id"`
|
||||
}
|
||||
|
||||
type RoleAssignmentsInput struct {
|
||||
User RAInputObject `json:"user"`
|
||||
Group RAInputObject `json:"group"`
|
||||
Role RAInputObject `json:"role"`
|
||||
|
||||
Scope struct {
|
||||
Project RAInputObject `json:"project"`
|
||||
Domain RAInputObject `json:"domain"`
|
||||
} `json:"scope"`
|
||||
|
||||
Users []string `json:"users"`
|
||||
Groups []string `json:"groups"`
|
||||
Roles []string `json:"roles"`
|
||||
Projects []string `json:"projects"`
|
||||
Domains []string `json:"domains"`
|
||||
|
||||
IncludeNames *bool `json:"include_names"`
|
||||
Effective *bool `json:"effective"`
|
||||
IncludeSubtree *bool `json:"include_subtree"`
|
||||
IncludeSystem *bool `json:"include_system"`
|
||||
IncludePolicies *bool `json:"include_policies"`
|
||||
|
||||
Limit *int `json:"limit"`
|
||||
Offset *int `json:"offset"`
|
||||
}
|
||||
|
||||
type RoleAssignmentsOutput struct {
|
||||
RoleAssignments []SRoleAssignment `json:"role_assignments,allowempty"`
|
||||
|
||||
Total int64 `json:"total"`
|
||||
Limit int `json:"limit"`
|
||||
Offset int `json:"offset"`
|
||||
}
|
||||
|
||||
@@ -430,37 +430,59 @@ func AddAdhocHandlers(version string, app *appsrv.Application) {
|
||||
|
||||
func roleAssignmentHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
_, query, _ := appsrv.FetchEnv(ctx, w, r)
|
||||
userId, _ := query.GetString("user", "id")
|
||||
groupId, _ := query.GetString("group", "id")
|
||||
roleId, _ := query.GetString("role", "id")
|
||||
domainId, _ := query.GetString("scope", "domain", "id")
|
||||
projectId, _ := query.GetString("scope", "project", "id")
|
||||
includeNames := query.Contains("include_names")
|
||||
effective := query.Contains("effective")
|
||||
includeSub := query.Contains("include_subtree")
|
||||
includeSystem := query.Contains("include_system")
|
||||
includePolicies := query.Contains("include_policies")
|
||||
limit, _ := query.Int("limit")
|
||||
offset, _ := query.Int("offset")
|
||||
|
||||
results, total, err := AssignmentManager.FetchAll(userId, groupId, roleId, domainId, projectId, includeNames, effective, includeSub, includeSystem, includePolicies, int(limit), int(offset))
|
||||
input := api.RoleAssignmentsInput{}
|
||||
err := query.Unmarshal(&input)
|
||||
if err != nil {
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
return
|
||||
}
|
||||
body := jsonutils.NewDict()
|
||||
body.Add(jsonutils.Marshal(results), "role_assignments")
|
||||
body.Add(jsonutils.NewInt(total), "total")
|
||||
if limit > 0 {
|
||||
body.Add(jsonutils.NewInt(limit), "limit")
|
||||
|
||||
includeNames := (input.IncludeNames != nil)
|
||||
effective := (input.Effective != nil)
|
||||
includeSub := (input.IncludeSubtree != nil)
|
||||
includeSystem := (input.IncludeSystem != nil)
|
||||
includePolicies := (input.IncludePolicies != nil)
|
||||
|
||||
limit := 0
|
||||
if input.Limit != nil {
|
||||
limit = *input.Limit
|
||||
}
|
||||
if offset > 0 {
|
||||
body.Add(jsonutils.NewInt(offset), "offset")
|
||||
offset := 0
|
||||
if input.Offset != nil {
|
||||
offset = *input.Offset
|
||||
}
|
||||
appsrv.SendJSON(w, body)
|
||||
|
||||
results, total, err := AssignmentManager.FetchAll(
|
||||
input.User.Id,
|
||||
input.Group.Id,
|
||||
input.Role.Id,
|
||||
input.Scope.Domain.Id,
|
||||
input.Scope.Project.Id,
|
||||
input.Users,
|
||||
input.Groups,
|
||||
input.Roles,
|
||||
input.Domains,
|
||||
input.Projects,
|
||||
includeNames, effective, includeSub, includeSystem, includePolicies,
|
||||
limit, offset)
|
||||
|
||||
if err != nil {
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
return
|
||||
}
|
||||
|
||||
output := api.RoleAssignmentsOutput{}
|
||||
output.RoleAssignments = results
|
||||
output.Total = total
|
||||
output.Limit = limit
|
||||
output.Offset = offset
|
||||
appsrv.SendJSON(w, jsonutils.Marshal(output))
|
||||
}
|
||||
|
||||
func (manager *SAssignmentManager) queryAll(userId, groupId, roleId, domainId, projectId string) *sqlchemy.SQuery {
|
||||
func (manager *SAssignmentManager) queryAll(
|
||||
userId, groupId, roleId, domainId, projectId string,
|
||||
users, groups, roles, domains, projects []string,
|
||||
) *sqlchemy.SQuery {
|
||||
assigments := manager.Query().SubQuery()
|
||||
q := assigments.Query(
|
||||
assigments.Field("type"),
|
||||
@@ -499,18 +521,58 @@ func (manager *SAssignmentManager) queryAll(userId, groupId, roleId, domainId, p
|
||||
if len(userId) > 0 {
|
||||
q = q.In("type", []string{api.AssignmentUserProject, api.AssignmentUserDomain}).Equals("user_id", userId)
|
||||
}
|
||||
if len(users) > 0 {
|
||||
subq := UserManager.Query("id")
|
||||
subq = subq.Filter(sqlchemy.OR(
|
||||
sqlchemy.In(subq.Field("id"), users),
|
||||
sqlchemy.ContainsAny(subq.Field("name"), users),
|
||||
))
|
||||
q = q.In("type", []string{api.AssignmentUserProject, api.AssignmentUserDomain}).In("user_id", subq.SubQuery())
|
||||
}
|
||||
if len(groupId) > 0 {
|
||||
q = q.In("type", []string{api.AssignmentGroupProject, api.AssignmentGroupDomain}).Equals("group_id", groupId)
|
||||
}
|
||||
if len(groups) > 0 {
|
||||
subq := GroupManager.Query("id")
|
||||
subq = subq.Filter(sqlchemy.OR(
|
||||
sqlchemy.In(subq.Field("id"), groups),
|
||||
sqlchemy.ContainsAny(subq.Field("name"), groups),
|
||||
))
|
||||
q = q.In("type", []string{api.AssignmentGroupProject, api.AssignmentGroupDomain}).In("group_id", subq.SubQuery())
|
||||
}
|
||||
if len(roleId) > 0 {
|
||||
q = q.Equals("role_id", roleId)
|
||||
}
|
||||
if len(roles) > 0 {
|
||||
subq := RoleManager.Query("id")
|
||||
subq = subq.Filter(sqlchemy.OR(
|
||||
sqlchemy.In(subq.Field("id"), roles),
|
||||
sqlchemy.ContainsAny(subq.Field("name"), roles),
|
||||
))
|
||||
q = q.In("role_id", subq.SubQuery())
|
||||
}
|
||||
if len(projectId) > 0 {
|
||||
q = q.Equals("project_id", projectId).In("type", []string{api.AssignmentUserProject, api.AssignmentGroupProject})
|
||||
}
|
||||
if len(projects) > 0 {
|
||||
subq := ProjectManager.Query("id")
|
||||
subq = subq.Filter(sqlchemy.OR(
|
||||
sqlchemy.In(subq.Field("id"), projects),
|
||||
sqlchemy.ContainsAny(subq.Field("name"), projects),
|
||||
))
|
||||
q = q.In("project_id", subq.SubQuery()).In("type", []string{api.AssignmentUserProject, api.AssignmentGroupProject})
|
||||
}
|
||||
if len(domainId) > 0 {
|
||||
q = q.Equals("domain_id", domainId).In("type", []string{api.AssignmentUserDomain, api.AssignmentGroupDomain})
|
||||
}
|
||||
if len(domains) > 0 {
|
||||
subq := DomainManager.Query("id")
|
||||
subq = subq.Filter(sqlchemy.OR(
|
||||
sqlchemy.In(subq.Field("id"), domains),
|
||||
sqlchemy.ContainsAny(subq.Field("name"), domains),
|
||||
))
|
||||
q = q.In("domain_id", subq.SubQuery()).In("type", []string{api.AssignmentUserDomain, api.AssignmentGroupDomain})
|
||||
}
|
||||
return q
|
||||
}
|
||||
|
||||
@@ -562,14 +624,18 @@ func (assign *sAssignmentInternal) getRoleAssignment(domains, projects, groups,
|
||||
return ra
|
||||
}
|
||||
|
||||
func (manager *SAssignmentManager) FetchAll(userId, groupId, roleId, domainId, projectId string, includeNames, effective, includeSub, includeSystem, includePolicies bool, limit, offset int) ([]api.SRoleAssignment, int64, error) {
|
||||
func (manager *SAssignmentManager) FetchAll(
|
||||
userId, groupId, roleId, domainId, projectId string,
|
||||
userStrs, groupStrs, roleStrs, domainStrs, projectStrs []string,
|
||||
includeNames, effective, includeSub, includeSystem, includePolicies bool,
|
||||
limit, offset int) ([]api.SRoleAssignment, int64, error) {
|
||||
var q *sqlchemy.SQuery
|
||||
if effective {
|
||||
usrq := manager.queryAll(userId, "", roleId, domainId, projectId).In("type", []string{api.AssignmentUserProject, api.AssignmentUserDomain})
|
||||
usrq := manager.queryAll(userId, "", roleId, domainId, projectId, userStrs, nil, roleStrs, domainStrs, projectStrs).In("type", []string{api.AssignmentUserProject, api.AssignmentUserDomain})
|
||||
|
||||
memberships := UsergroupManager.Query("user_id", "group_id").SubQuery()
|
||||
|
||||
grpproj := manager.queryAll("", groupId, roleId, domainId, projectId).In("type", []string{api.AssignmentGroupProject, api.AssignmentGroupDomain}).SubQuery()
|
||||
grpproj := manager.queryAll("", groupId, roleId, domainId, projectId, nil, groupStrs, roleStrs, domainStrs, projectStrs).In("type", []string{api.AssignmentGroupProject, api.AssignmentGroupDomain}).SubQuery()
|
||||
q2 := grpproj.Query(
|
||||
grpproj.Field("type"),
|
||||
memberships.Field("user_id"),
|
||||
@@ -585,7 +651,7 @@ func (manager *SAssignmentManager) FetchAll(userId, groupId, roleId, domainId, p
|
||||
|
||||
q = sqlchemy.Union(usrq, q2).Query().Distinct()
|
||||
} else {
|
||||
q = manager.queryAll(userId, groupId, roleId, domainId, projectId).Distinct()
|
||||
q = manager.queryAll(userId, groupId, roleId, domainId, projectId, userStrs, groupStrs, roleStrs, domainStrs, projectStrs).Distinct()
|
||||
}
|
||||
|
||||
if !includeSystem {
|
||||
|
||||
@@ -291,7 +291,9 @@ func (t *SAuthToken) getTokenV3(
|
||||
token.Token.Projects[i].Domain.Id = extProjs[i].DomainId
|
||||
token.Token.Projects[i].Domain.Name = extProjs[i].DomainName
|
||||
}*/
|
||||
assigns, _, err := models.AssignmentManager.FetchAll(user.Id, "", "", "", "", true, true, true, true, true, 0, 0)
|
||||
assigns, _, err := models.AssignmentManager.FetchAll(user.Id, "", "", "", "",
|
||||
nil, nil, nil, nil, nil,
|
||||
true, true, true, true, true, 0, 0)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "models.AssignmentManager.FetchAll")
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ func (manager *SCredentialManager) CreateAccessKeySecret(s *mcclient.ClientSessi
|
||||
return aksk, nil
|
||||
}
|
||||
|
||||
func (manager *SCredentialManager) DoCreateOIDCSecret(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
func (manager *SCredentialManager) DoCreateOidcSecret(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
redirectUri, _ := params.GetString("redirect_uri")
|
||||
|
||||
key, err := manager.CreateOIDCSecret(s, "", "", redirectUri)
|
||||
|
||||
@@ -18,8 +18,10 @@ import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
)
|
||||
@@ -130,13 +132,12 @@ var (
|
||||
RoleAssignments RoleAssignmentManagerV3
|
||||
)
|
||||
|
||||
// get project users for given project
|
||||
// get users for given project
|
||||
func (this *RoleAssignmentManagerV3) GetProjectUsers(s *mcclient.ClientSession, id string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
|
||||
query := jsonutils.NewDict()
|
||||
|
||||
effective, e := params.GetString("effective")
|
||||
if e == nil && effective == "true" {
|
||||
if params.Contains("effective") {
|
||||
query.Add(jsonutils.JSONNull, "effective")
|
||||
}
|
||||
|
||||
@@ -170,6 +171,8 @@ func (this *RoleAssignmentManagerV3) GetProjectUsers(s *mcclient.ClientSession,
|
||||
query.Add(jsonutils.NewString(id), resource, "id")
|
||||
}
|
||||
|
||||
query.Add(jsonutils.JSONNull, "include_policies")
|
||||
|
||||
result, err := this.List(s, query)
|
||||
if err != nil {
|
||||
return jsonutils.JSONNull, err
|
||||
@@ -217,8 +220,7 @@ func (this *RoleAssignmentManagerV3) GetProjectRole(s *mcclient.ClientSession, i
|
||||
data := jsonutils.NewDict()
|
||||
query := jsonutils.NewDict()
|
||||
|
||||
effective, e := params.GetString("effective")
|
||||
if e == nil && effective == "true" {
|
||||
if params.Contains("effective") {
|
||||
query.Add(jsonutils.JSONNull, "effective")
|
||||
}
|
||||
|
||||
@@ -242,6 +244,27 @@ func (this *RoleAssignmentManagerV3) GetProjectRole(s *mcclient.ClientSession, i
|
||||
return jsonutils.JSONNull, fmt.Errorf("not allowed resource %s", resource)
|
||||
}
|
||||
|
||||
// search by project id or name
|
||||
searchProjs := jsonutils.GetQueryStringArray(params, "projects")
|
||||
if len(searchProjs) > 0 {
|
||||
query.Add(jsonutils.NewStringArray(searchProjs), "projects")
|
||||
}
|
||||
// search by user id or name
|
||||
searchUsers := jsonutils.GetQueryStringArray(params, "users")
|
||||
if len(searchUsers) > 0 {
|
||||
query.Add(jsonutils.NewStringArray(searchUsers), "users")
|
||||
}
|
||||
|
||||
groupBy, _ := params.GetString("group_by")
|
||||
if len(groupBy) == 0 {
|
||||
groupBy = "project"
|
||||
}
|
||||
if groupBy == "project" {
|
||||
} else if groupBy == "user" {
|
||||
} else {
|
||||
return nil, errors.Wrapf(httperrors.ErrInputParameter, "unsupported group_by value %s", groupBy)
|
||||
}
|
||||
|
||||
query.Add(jsonutils.JSONNull, "include_names")
|
||||
|
||||
if scope {
|
||||
@@ -256,43 +279,53 @@ func (this *RoleAssignmentManagerV3) GetProjectRole(s *mcclient.ClientSession, i
|
||||
return jsonutils.JSONNull, err
|
||||
}
|
||||
|
||||
projects := make([]sProjectGroupRole, 0)
|
||||
lines := make([]sProjectGroupRole, 0)
|
||||
for _, roleAssign := range result.Data {
|
||||
roleId, _ := roleAssign.GetString("role", "id")
|
||||
roleName, _ := roleAssign.GetString("role", "name")
|
||||
projectId, _ := roleAssign.GetString("scope", "project", "id")
|
||||
projectName, _ := roleAssign.GetString("scope", "project", "name")
|
||||
|
||||
var groupById string
|
||||
var groupByName string
|
||||
|
||||
if groupBy == "project" {
|
||||
groupById, _ = roleAssign.GetString("scope", "project", "id")
|
||||
groupByName, _ = roleAssign.GetString("scope", "project", "name")
|
||||
} else if groupBy == "user" {
|
||||
groupById, _ = roleAssign.GetString("user", "id")
|
||||
groupByName, _ = roleAssign.GetString("user", "name")
|
||||
}
|
||||
|
||||
groupId, _ := roleAssign.GetString("group", "id")
|
||||
groupName, _ := roleAssign.GetString("group", "name")
|
||||
projPolicies, _ := jsonutils.GetStringArray(roleAssign, "policies", "project")
|
||||
domPolicies, _ := jsonutils.GetStringArray(roleAssign, "policies", "domain")
|
||||
sysPolicies, _ := jsonutils.GetStringArray(roleAssign, "policies", "system")
|
||||
|
||||
projIdx := -1
|
||||
for i := range projects {
|
||||
if projects[i].Id == projectId {
|
||||
projIdx = i
|
||||
lineIdx := -1
|
||||
for i := range lines {
|
||||
if lines[i].Id == groupById {
|
||||
lineIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if projIdx < 0 {
|
||||
projIdx = len(projects)
|
||||
projects = append(projects, sProjectGroupRole{
|
||||
Id: projectId,
|
||||
Name: projectName,
|
||||
if lineIdx < 0 {
|
||||
lineIdx = len(lines)
|
||||
lines = append(lines, sProjectGroupRole{
|
||||
Id: groupById,
|
||||
Name: groupByName,
|
||||
})
|
||||
}
|
||||
|
||||
projects[projIdx].add(groupId, groupName, roleId, roleName, projPolicies, domPolicies, sysPolicies)
|
||||
lines[lineIdx].add(groupId, groupName, roleId, roleName, projPolicies, domPolicies, sysPolicies)
|
||||
}
|
||||
|
||||
projJson := jsonutils.NewArray()
|
||||
for _, proj := range projects {
|
||||
projJson.Add(jsonutils.Marshal(proj))
|
||||
lineJson := jsonutils.NewArray()
|
||||
for _, line := range lines {
|
||||
lineJson.Add(jsonutils.Marshal(line))
|
||||
}
|
||||
data.Add(projJson, "data")
|
||||
data.Add(jsonutils.NewInt(int64(len(projects))), "total")
|
||||
data.Add(lineJson, "data")
|
||||
data.Add(jsonutils.NewInt(int64(len(lines))), "total")
|
||||
return data, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user