pycasbin
pycasbin copied to clipboard
[Bug] Error When Calling `get_implicit_permissions_for_user`
Error When Calling get_implicit_permissions_for_user
In the above scenario, calling the function get_implicit_permissions_for_user results in an error.
From the code, we can see:
def get_named_implicit_permissions_for_user(self, ptype, user, domain="", filter_policy_dom=True):
"""
gets implicit permissions for a user or role by named policy.
Compared to get_permissions_for_user(), this function retrieves permissions for inherited roles.
For example:
p, admin, data1, read
p, alice, data2, read
g, alice, admin
get_permissions_for_user("alice") can only get: [["alice", "data2", "read"]].
But get_implicit_permissions_for_user("alice") will get: [["admin", "data1", "read"], ["alice", "data2", "read"]].
For given domain policies are filtered by corresponding domain matching function of DomainManager
Inherited roles can be matched by domain. For domain neutral policies set:
filter_policy_dom = False
filter_policy_dom: bool - For given *domain*, policies will be filtered by domain as well. Default = True
"""
roles = self.get_implicit_roles_for_user(user, domain)
roles.insert(0, user)
res = []
# policy domain should be matched by domain_match_fn of DomainManager
domain_matching_func = self.get_role_manager().domain_matching_func
if domain and domain_matching_func != None:
domain = partial(domain_matching_func, domain)
for role in roles:
permissions = self.get_named_permissions_for_user_in_domain(
ptype, role, domain if filter_policy_dom else ""
)
res.extend(permissions)
return res
This function calls get_role_manager, which is defined as follows:
def get_role_manager(self):
"""gets the current role manager."""
return self.rm_map["g"]
At this point, rm_map does not contain g, because g is in cond_rm_map.
Originally posted by @zhou93 in https://github.com/casbin/pycasbin/issues/350#issuecomment-2188033094
@techoner @Nekotoxin
Additionally, functions like get_implicit_roles_for_user do not return the correct results when g is defined with conditions. Is this the expected behavior?
For example:
def get_implicit_roles_for_user(self, name, domain=""):
"""
gets implicit roles that a user has.
Compared to get_roles_for_user(), this function retrieves indirect roles besides direct roles.
For example:
g, alice, role:admin
g, role:admin, role:user
get_roles_for_user("alice") can only get: ["role:admin"].
But get_implicit_roles_for_user("alice") will get: ["role:admin", "role:user"].
"""
res = []
queue = [name]
while queue:
name = queue.pop(0)
for rm in self.rm_map.values():
roles = rm.get_roles(name, domain)
for r in roles:
if r not in res:
res.append(r)
queue.append(r)
return res
In the above function, it only retrieves roles from rm_map and does not check cond_rm_map. I expect that the roles assigned under conditions should also be retrieved.
@zhou93 you should use batch_enforce API, see docs: https://casbin.org/docs/data-permissions