feat: get all role/permission of an user (#1978)

This commit is contained in:
June 2023-06-16 21:44:21 +07:00 committed by GitHub
parent ebc0e0f2c9
commit edc6aa0d50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 20 deletions

View File

@ -264,18 +264,48 @@ func DeletePermission(permission *Permission) (bool, error) {
return affected != 0, nil return affected != 0, nil
} }
func GetPermissionsByUser(userId string) ([]*Permission, error) { func GetPermissionsAndRolesByUser(userId string) ([]*Permission, []*Role, error) {
permissions := []*Permission{} permissions := []*Permission{}
err := adapter.Engine.Where("users like ?", "%"+userId+"\"%").Find(&permissions) err := adapter.Engine.Where("users like ?", "%"+userId+"\"%").Find(&permissions)
if err != nil { if err != nil {
return permissions, err return nil, nil, err
} }
for i := range permissions { existedPerms := map[string]struct{}{}
permissions[i].Users = nil
for _, perm := range permissions {
perm.Users = nil
if _, ok := existedPerms[perm.Name]; !ok {
existedPerms[perm.Name] = struct{}{}
}
} }
return permissions, nil permFromRoles := []*Permission{}
roles, err := GetRolesByUser(userId)
if err != nil {
return nil, nil, err
}
for _, role := range roles {
perms := []*Permission{}
err := adapter.Engine.Where("roles like ?", "%"+role.Name+"\"%").Find(&perms)
if err != nil {
return nil, nil, err
}
permFromRoles = append(permFromRoles, perms...)
}
for _, perm := range permFromRoles {
perm.Users = nil
if _, ok := existedPerms[perm.Name]; !ok {
existedPerms[perm.Name] = struct{}{}
permissions = append(permissions, perm)
}
}
return permissions, roles, nil
} }
func GetPermissionsByRole(roleId string) ([]*Permission, error) { func GetPermissionsByRole(roleId string) ([]*Permission, error) {

View File

@ -267,7 +267,7 @@ func BatchEnforce(permissionId string, requests *[]CasbinRequest) ([]bool, error
} }
func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) []string { func getAllValues(userId string, fn func(enforcer *casbin.Enforcer) []string) []string {
permissions, err := GetPermissionsByUser(userId) permissions, _, err := GetPermissionsAndRolesByUser(userId)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -259,11 +259,22 @@ func GetRolesByUser(userId string) ([]*Role, error) {
return roles, err return roles, err
} }
for i := range roles { allRolesIds := make([]string, 0, len(roles))
roles[i].Users = nil
for _, role := range roles {
allRolesIds = append(allRolesIds, role.GetId())
} }
return roles, nil allRoles, err := GetAncestorRoles(allRolesIds...)
if err != nil {
return nil, err
}
for i := range allRoles {
allRoles[i].Users = nil
}
return allRoles, nil
} }
func roleChangeTrigger(oldName string, newName string) error { func roleChangeTrigger(oldName string, newName string) error {
@ -335,14 +346,22 @@ func GetRolesByNamePrefix(owner string, prefix string) ([]*Role, error) {
return roles, nil return roles, nil
} }
func GetAncestorRoles(roleId string) ([]*Role, error) { // GetAncestorRoles returns a list of roles that contain the given roleIds
func GetAncestorRoles(roleIds ...string) ([]*Role, error) {
var ( var (
result []*Role result = []*Role{}
roleMap = make(map[string]*Role) roleMap = make(map[string]*Role)
visited = make(map[string]bool) visited = make(map[string]bool)
) )
if len(roleIds) == 0 {
return result, nil
}
owner, _ := util.GetOwnerAndNameFromIdNoCheck(roleId) for _, roleId := range roleIds {
visited[roleId] = true
}
owner, _ := util.GetOwnerAndNameFromIdNoCheck(roleIds[0])
allRoles, err := GetRoles(owner) allRoles, err := GetRoles(owner)
if err != nil { if err != nil {
@ -360,7 +379,7 @@ func GetAncestorRoles(roleId string) ([]*Role, error) {
result = append(result, r) result = append(result, r)
} else if !ok { } else if !ok {
rId := r.GetId() rId := r.GetId()
visited[rId] = containsRole(r, roleId, roleMap, visited) visited[rId] = containsRole(r, roleMap, visited, roleIds...)
if visited[rId] { if visited[rId] {
result = append(result, r) result = append(result, r)
} }
@ -370,19 +389,19 @@ func GetAncestorRoles(roleId string) ([]*Role, error) {
return result, nil return result, nil
} }
// containsRole is a helper function to check if a slice of roles contains a specific roleId // containsRole is a helper function to check if a roles is related to any role in the given list roles
func containsRole(role *Role, roleId string, roleMap map[string]*Role, visited map[string]bool) bool { func containsRole(role *Role, roleMap map[string]*Role, visited map[string]bool, roleIds ...string) bool {
if isContain, ok := visited[role.GetId()]; ok { if isContain, ok := visited[role.GetId()]; ok {
return isContain return isContain
} }
for _, subRole := range role.Roles { for _, subRole := range role.Roles {
if subRole == roleId { if util.HasString(roleIds, subRole) {
return true return true
} }
r, ok := roleMap[subRole] r, ok := roleMap[subRole]
if ok && containsRole(r, roleId, roleMap, visited) { if ok && containsRole(r, roleMap, visited, roleIds...) {
return true return true
} }
} }

View File

@ -777,12 +777,11 @@ func ExtendUserWithRolesAndPermissions(user *User) (err error) {
return return
} }
user.Roles, err = GetRolesByUser(user.GetId()) user.Permissions, user.Roles, err = GetPermissionsAndRolesByUser(user.GetId())
if err != nil { if err != nil {
return return err
} }
user.Permissions, err = GetPermissionsByUser(user.GetId())
return return
} }

View File

@ -278,3 +278,13 @@ func GetEndPoint(endpoint string) string {
} }
return endpoint return endpoint
} }
// HasString reports if slice has input string.
func HasString(strs []string, str string) bool {
for _, i := range strs {
if i == str {
return true
}
}
return false
}