Skip to content

feat(casbin): add support for multiple roles in GetImplicitPermissionsForUser#1479

Open
sokryptk wants to merge 8 commits intoapache:masterfrom
ApicaSystem:feat/OPL-12218-add-support-for-multi-role
Open

feat(casbin): add support for multiple roles in GetImplicitPermissionsForUser#1479
sokryptk wants to merge 8 commits intoapache:masterfrom
ApicaSystem:feat/OPL-12218-add-support-for-multi-role

Conversation

@sokryptk
Copy link

@sokryptk sokryptk commented Apr 9, 2025

No description provided.

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>
@sokryptk sokryptk force-pushed the feat/OPL-12218-add-support-for-multi-role branch from f098381 to 68cdb10 Compare April 10, 2025 08:56
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>
@sokryptk
Copy link
Author

sokryptk commented Apr 10, 2025

@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.

@sokryptk
Copy link
Author

@tangyang9464 @JalinWang any opinions?

@hsluoyz hsluoyz requested a review from Copilot November 1, 2025 17:43
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 GetImplicitPermissionsForUserFromAllRoles to 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))
Copy link

Copilot AI Nov 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug print statement should be removed. This appears to be leftover debugging code that outputs to stdout during tests.

Suggested change
fmt.Println(e.GetNamedImplicitRolesForUser("*", name))

Copilot uses AI. Check for mistakes.
Comment on lines +231 to +239
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
}
}
Copy link

Copilot AI Nov 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +235 to +238
} else {
assert.Policy = append(assert.Policy, rule)
assert.PolicyMap[strings.Join(rule, DefaultSep)] = len(model[sec]["*"].Policy) - 1
}
Copy link

Copilot AI Nov 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The else block is unnecessary since the if err != nil path returns early. Remove the else and unindent the code block for better readability.

Suggested change
} 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

Copilot uses AI. Check for mistakes.
func (e *Enforcer) GetImplicitPermissionsForUser(user string, domain ...string) ([][]string, error) {
return e.GetNamedImplicitPermissionsForUser("p", "g", user, domain...)
}

Copy link

Copilot AI Nov 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing documentation comment for the exported function GetImplicitPermissionsForUserFromAllRoles. The function should have a comment explaining its purpose, behavior, and how it differs from GetImplicitPermissionsForUser.

Suggested change
// 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.

Copilot uses AI. Check for mistakes.
@hsluoyz hsluoyz force-pushed the master branch 3 times, most recently from c622095 to b190fce Compare January 6, 2026 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants