Skip to content

Commit ff30f53

Browse files
feat:align RoleManager behavior with documentation(#1404)
1 parent f2818d0 commit ff30f53

File tree

1 file changed

+69
-2
lines changed

1 file changed

+69
-2
lines changed

rbac/default-role-manager/role_manager.go

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package defaultrolemanager
1616

1717
import (
18+
"errors"
1819
"fmt"
1920
"strings"
2021
"sync"
@@ -35,6 +36,7 @@ type Role struct {
3536
matchedBy *sync.Map
3637
linkConditionFuncMap *sync.Map
3738
linkConditionFuncParamsMap *sync.Map
39+
level int
3840
}
3941

4042
func newRole(name string) *Role {
@@ -46,12 +48,41 @@ func newRole(name string) *Role {
4648
r.matchedBy = &sync.Map{}
4749
r.linkConditionFuncMap = &sync.Map{}
4850
r.linkConditionFuncParamsMap = &sync.Map{}
51+
r.level = -1
4952
return &r
5053
}
5154

55+
func (r *Role) updateLevel() {
56+
maxLevel := 0
57+
hasParent := false
58+
r.users.Range(func(_, value interface{}) bool {
59+
hasParent = true
60+
parentRole := value.(*Role)
61+
if parentRole.level >= 0 && parentRole.level+1 > maxLevel {
62+
maxLevel = parentRole.level + 1
63+
}
64+
return true
65+
})
66+
67+
newLevel := 0
68+
if hasParent {
69+
newLevel = maxLevel
70+
}
71+
72+
if newLevel != r.level {
73+
r.level = newLevel
74+
r.roles.Range(func(_, value interface{}) bool {
75+
role := value.(*Role)
76+
role.updateLevel()
77+
return true
78+
})
79+
}
80+
}
81+
5282
func (r *Role) addRole(role *Role) {
5383
r.roles.Store(role.name, role)
5484
role.addUser(r)
85+
r.updateLevel()
5586
}
5687

5788
func (r *Role) removeRole(role *Role) {
@@ -331,6 +362,9 @@ func (rm *RoleManagerImpl) Clear() error {
331362
func (rm *RoleManagerImpl) AddLink(name1 string, name2 string, domains ...string) error {
332363
user, _ := rm.getRole(name1)
333364
role, _ := rm.getRole(name2)
365+
if rm.maxHierarchyLevel > 0 && role.level >= rm.maxHierarchyLevel-1 {
366+
return errors.New("exceeded level limit")
367+
}
334368
user.addRole(role)
335369
return nil
336370
}
@@ -392,7 +426,25 @@ func (rm *RoleManagerImpl) GetRoles(name string, domains ...string) ([]string, e
392426
if created {
393427
defer rm.removeRole(user.name)
394428
}
395-
return user.getRoles(), nil
429+
430+
if rm.maxHierarchyLevel <= 0 {
431+
return user.getRoles(), nil
432+
}
433+
434+
allRoles := user.getRoles()
435+
var filteredRoles []string
436+
437+
for _, roleName := range allRoles {
438+
role, roleCreated := rm.getRole(roleName)
439+
if roleCreated {
440+
defer rm.removeRole(role.name)
441+
}
442+
if role.level <= rm.maxHierarchyLevel {
443+
filteredRoles = append(filteredRoles, roleName)
444+
}
445+
}
446+
447+
return filteredRoles, nil
396448
}
397449

398450
// GetUsers gets the users of a role.
@@ -402,7 +454,22 @@ func (rm *RoleManagerImpl) GetUsers(name string, domain ...string) ([]string, er
402454
if created {
403455
defer rm.removeRole(role.name)
404456
}
405-
return role.getUsers(), nil
457+
458+
if rm.maxHierarchyLevel <= 0 {
459+
return role.getUsers(), nil
460+
}
461+
462+
allUsers := role.getUsers()
463+
var filteredUsers []string
464+
465+
for _, userName := range allUsers {
466+
user, _ := rm.getRole(userName)
467+
if user.level < rm.maxHierarchyLevel {
468+
filteredUsers = append(filteredUsers, userName)
469+
}
470+
}
471+
472+
return filteredUsers, nil
406473
}
407474

408475
func (rm *RoleManagerImpl) toString() []string {

0 commit comments

Comments
 (0)