Skip to content

Commit

Permalink
fix: allow permissions management to use additional p-types (#256)
Browse files Browse the repository at this point in the history
* fix: allow permissions management to use additional p-types

* code reuse and change a function name
  • Loading branch information
Nekotoxin authored Apr 30, 2022
1 parent 1db47e0 commit 37892e1
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 2 deletions.
30 changes: 28 additions & 2 deletions casbin/enforcer.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,26 @@ def get_implicit_permissions_for_user(self, user, domain="", filter_policy_dom=T
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
"""
return self.get_named_implicit_permissions_for_user("p", user, domain, filter_policy_dom)

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
Expand All @@ -182,7 +202,9 @@ def get_implicit_permissions_for_user(self, user, domain="", filter_policy_dom=T
domain = partial(domain_matching_func, domain)

for role in roles:
permissions = self.get_permissions_for_user_in_domain(role, domain if filter_policy_dom else "")
permissions = self.get_named_permissions_for_user_in_domain(
ptype, role, domain if filter_policy_dom else ""
)
res.extend(permissions)

return res
Expand Down Expand Up @@ -235,4 +257,8 @@ def delete_roles_for_user_in_domain(self, user, role, domain):

def get_permissions_for_user_in_domain(self, user, domain):
"""gets permissions for a user or role inside domain."""
return self.get_filtered_policy(0, user, domain)
return self.get_named_permissions_for_user_in_domain("p", user, domain)

def get_named_permissions_for_user_in_domain(self, ptype, user, domain):
"""gets permissions for a user or role with named policy inside domain."""
return self.get_filtered_named_policy(ptype, 0, user, domain)
22 changes: 22 additions & 0 deletions casbin/synced_enforcer.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,23 @@ def get_implicit_permissions_for_user(self, user, *domain, filter_policy_dom=Tru
with self._rl:
return self._e.get_implicit_permissions_for_user(user, *domain, filter_policy_dom=filter_policy_dom)

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"]].
"""
with self._rl:
return self._e.get_named_implicit_permissions_for_user(
ptype, user, *domain, filter_policy_dom=filter_policy_dom
)

def get_implicit_users_for_permission(self, *permission):
"""
gets implicit users for a permission.
Expand Down Expand Up @@ -505,6 +522,11 @@ def get_permissions_for_user_in_domain(self, user, domain):
with self._rl:
return self._e.get_permissions_for_user_in_domain(user, domain)

def get_named_permissions_for_user_in_domain(self, ptype, user, domain):
"""gets permissions for a user or role by named policy inside domain."""
with self._rl:
return self._e.get_named_permissions_for_user_in_domain(ptype, user, domain)

def enable_auto_build_role_links(self, auto_build_role_links):
"""controls whether to rebuild the role inheritance relations when a role is added or deleted."""
with self._wl:
Expand Down
16 changes: 16 additions & 0 deletions examples/rbac_with_multiple_policy_model.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[request_definition]
r = user, thing, action

[policy_definition]
p = role, thing, action
p2 = role, action

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.user, p.role) && r.thing == p.thing && r.action == p.action
m2 = g(r.user, p2.role) && r.action == p.action

[role_definition]
g = _,_
8 changes: 8 additions & 0 deletions examples/rbac_with_multiple_policy_policy.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
p, user, /data, GET
p, admin, /data, POST

p2, user, view
p2, admin, create

g, admin, user
g, alice, admin
25 changes: 25 additions & 0 deletions tests/test_rbac_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,31 @@ def test_enforce_implicit_permissions_api(self):
sorted([["bob", "data2", "write"]]),
)

def test_enforce_implicit_permissions_api_with_multiple_policy(self):
e = self.get_enforcer(
get_examples("rbac_with_multiple_policy_model.conf"),
get_examples("rbac_with_multiple_policy_policy.csv"),
)

self.assertEqual(
sorted(e.get_named_implicit_permissions_for_user("p", "alice")),
sorted(
[
["user", "/data", "GET"],
["admin", "/data", "POST"],
]
),
)
self.assertEqual(
sorted(e.get_named_implicit_permissions_for_user("p2", "alice")),
sorted(
[
["user", "view"],
["admin", "create"],
]
),
)

def test_enforce_implicit_permissions_api_with_domain(self):
e = self.get_enforcer(
get_examples("rbac_with_domains_model.conf"),
Expand Down

0 comments on commit 37892e1

Please sign in to comment.