feat(casbin): add support for multiple roles in GetImplicitPermissionsForUser#1479
feat(casbin): add support for multiple roles in GetImplicitPermissionsForUser#1479sokryptk wants to merge 8 commits intoapache:masterfrom
Conversation
Signed-off-by: Kevin <kevin.dsouza@apica.io>
Signed-off-by: Kevin <kevin.dsouza@apica.io>
Signed-off-by: Kevin <kevin.dsouza@apica.io>
Signed-off-by: Kevin <kevin.dsouza@apica.io>
f098381 to
68cdb10
Compare
Signed-off-by: Kevin <kevin.dsouza@apica.io>
Signed-off-by: Kevin <kevin.dsouza@apica.io>
Signed-off-by: Kevin <kevin.dsouza@apica.io>
Signed-off-by: Kevin <kevin.dsouza@apica.io>
|
@hsluoyz is there any other approach that I should take for this functionality? I don't know if this is the best way to approach this Right now - I keep a psuedo g reference (*) that gets built at startup and destroyed later on. this holds all the culminated roles here and we can then create a RoleManager on top of this and add all the links. This can then be queried. |
|
@tangyang9464 @JalinWang any opinions? |
There was a problem hiding this comment.
Pull Request Overview
This PR adds a new method GetImplicitPermissionsForUserFromAllRoles that retrieves implicit permissions for a user across all role definitions (g, g2, etc.) in models with multiple role types. The implementation introduces a special "*" role type that aggregates policies from all role definitions.
Key changes:
- New API method
GetImplicitPermissionsForUserFromAllRolesto get permissions from all role types - Internal "*" role type aggregation mechanism in the model
- Deduplication logic for implicit roles and users
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| rbac_api.go | Adds new GetImplicitPermissionsForUserFromAllRoles method and deduplication for GetImplicitRolesForUser and GetImplicitUsersForRole |
| rbac_api_test.go | Adds test case and helper function for the new API method |
| model/policy.go | Updates AddPolicy to synchronize policies to "*" assertion when multiple role definitions exist |
| model/model.go | Filters out "*" from ToText output to prevent serialization |
| enforcer.go | Initializes "*" assertion when multiple role definitions exist and removes it before saving |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func testGetImplicitPermissionsForUserFromAllRoles(t *testing.T, e *Enforcer, name string, res [][]string, domain ...string) { | ||
| t.Helper() | ||
| myRes, _ := e.GetImplicitPermissionsForUserFromAllRoles(name, domain...) | ||
| fmt.Println(e.GetNamedImplicitRolesForUser("*", name)) |
There was a problem hiding this comment.
Debug print statement should be removed. This appears to be leftover debugging code that outputs to stdout during tests.
| fmt.Println(e.GetNamedImplicitRolesForUser("*", name)) |
| if sec == "g" && len(model["g"]) > 1 { | ||
| assert, err := model.GetAssertion(sec, "*") | ||
| if err != nil { | ||
| return err | ||
| } else { | ||
| assert.Policy = append(assert.Policy, rule) | ||
| assert.PolicyMap[strings.Join(rule, DefaultSep)] = len(model[sec]["*"].Policy) - 1 | ||
| } | ||
| } |
There was a problem hiding this comment.
The synchronization to the '' assertion is not mirrored in RemovePolicy or RemovePoliciesWithAffected. When policies are removed, they will remain in the '' assertion, causing stale data. The removal functions need similar logic to keep the '*' assertion synchronized.
| } else { | ||
| assert.Policy = append(assert.Policy, rule) | ||
| assert.PolicyMap[strings.Join(rule, DefaultSep)] = len(model[sec]["*"].Policy) - 1 | ||
| } |
There was a problem hiding this comment.
The else block is unnecessary since the if err != nil path returns early. Remove the else and unindent the code block for better readability.
| } else { | |
| assert.Policy = append(assert.Policy, rule) | |
| assert.PolicyMap[strings.Join(rule, DefaultSep)] = len(model[sec]["*"].Policy) - 1 | |
| } | |
| } | |
| assert.Policy = append(assert.Policy, rule) | |
| assert.PolicyMap[strings.Join(rule, DefaultSep)] = len(model[sec]["*"].Policy) - 1 |
| func (e *Enforcer) GetImplicitPermissionsForUser(user string, domain ...string) ([][]string, error) { | ||
| return e.GetNamedImplicitPermissionsForUser("p", "g", user, domain...) | ||
| } | ||
|
|
There was a problem hiding this comment.
Missing documentation comment for the exported function GetImplicitPermissionsForUserFromAllRoles. The function should have a comment explaining its purpose, behavior, and how it differs from GetImplicitPermissionsForUser.
| // GetImplicitPermissionsForUserFromAllRoles gets implicit permissions for a user or role from all role managers. | |
| // Unlike GetImplicitPermissionsForUser, which retrieves permissions using the default role manager ("g"), | |
| // this function uses all available role managers ("*") to collect permissions inherited from any role manager. | |
| // This is useful when multiple role hierarchies are defined and you want to aggregate permissions across all of them. |
c622095 to
b190fce
Compare
No description provided.