Skip to content

Commit e0a64f9

Browse files
Chimou0nomeguy
authored andcommitted
feat: add new APIs: add_policies_ex() and add_named_policies_ex() (#391)
1 parent b42b0be commit e0a64f9

File tree

5 files changed

+88
-0
lines changed

5 files changed

+88
-0
lines changed

casbin/internal_enforcer.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,27 @@ def _add_policies(self, sec, ptype, rules):
5959

6060
return rules_added
6161

62+
def _add_policies_ex(self, sec, ptype, rules):
63+
"""adds rules to the current policy."""
64+
rules_added = self.model.add_policies_ex(sec, ptype, rules)
65+
if not rules_added:
66+
return rules_added
67+
68+
if self.adapter and self.auto_save:
69+
if hasattr(self.adapter, "add_policies_ex") is False:
70+
return False
71+
72+
if self.adapter.add_policies_ex(sec, ptype, rules) is False:
73+
return False
74+
75+
if self.watcher and self.auto_notify_watcher:
76+
if callable(getattr(self.watcher, "update_for_add_policies_ex", None)):
77+
self.watcher.update_for_add_policies_ex(sec, ptype, rules)
78+
else:
79+
self.watcher.update()
80+
81+
return rules_added
82+
6283
def _update_policy(self, sec, ptype, old_rule, new_rule):
6384
"""updates a rule from the current policy."""
6485
rule_updated = self.model.update_policy(sec, ptype, old_rule, new_rule)

casbin/management_enforcer.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ def add_policies(self, rules):
117117
"""
118118
return self.add_named_policies("p", rules)
119119

120+
def add_policies_ex(self, rules):
121+
"""add_policies_ex adds authorization rules to the current policy.
122+
123+
If the rule already exists, the rule will not be added.
124+
But unlike add_policies, other non-existent rules are added instead of returning false directly.
125+
"""
126+
return self.add_named_policies_ex("p", rules)
127+
120128
def add_named_policy(self, ptype, *params):
121129
"""adds an authorization rule to the current named policy.
122130
@@ -139,6 +147,14 @@ def add_named_policies(self, ptype, rules):
139147
Otherwise the function returns true for the corresponding by adding the new rule."""
140148
return self._add_policies("p", ptype, rules)
141149

150+
def add_named_policies_ex(self, ptype, rules):
151+
"""add_named_policies_ex adds authorization rules to the current policy.
152+
153+
If the rule already exists, the rule will not be added.
154+
But unlike add_named_policies, other non-existent rules are added instead of returning false directly.
155+
"""
156+
return self._add_policies_ex("p", ptype, rules)
157+
142158
def update_policy(self, old_rule, new_rule):
143159
"""updates an authorization rule from the current policy."""
144160
return self.update_named_policy("p", old_rule, new_rule)

casbin/model/policy.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,20 @@ def add_policies(self, sec, ptype, rules):
158158

159159
return True
160160

161+
def add_policies_ex(self, sec, ptype, rules):
162+
"""
163+
add_policies_ex adds authorization rules to the current policy.
164+
If the rule already exists, the rule will not be added.
165+
But unlike add_policies, other non-existent rules are added instead of returning false directly.
166+
"""
167+
rules_added = False
168+
for rule in rules:
169+
if self.has_policy(sec, ptype, rule):
170+
continue
171+
self.add_policy(sec, ptype, rule)
172+
rules_added = True
173+
return rules_added
174+
161175
def update_policy(self, sec, ptype, old_rule, new_rule):
162176
"""update a policy rule from the model."""
163177

casbin/synced_enforcer.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,24 @@ def add_policies(self, rules):
600600
with self._wl:
601601
return self._e.add_policies(rules)
602602

603+
def add_policies_ex(self, rules):
604+
"""add_policies_ex adds authorization rules to the current policy.
605+
606+
If the rule already exists, the rule will not be added.
607+
But unlike add_policies, other non-existent rules are added instead of returning false directly.
608+
"""
609+
with self._wl:
610+
return self._e.add_policies_ex(rules)
611+
612+
def add_named_policies_ex(self, ptype, rules):
613+
"""add_named_policies_ex adds authorization rules to the current policy.
614+
615+
If the rule already exists, the rule will not be added.
616+
But unlike add_named_policies, other non-existent rules are added instead of returning false directly.
617+
"""
618+
with self._wl:
619+
return self._e.add_named_policies_ex(ptype, rules)
620+
603621
def add_named_policies(self, ptype, rules):
604622
"""adds authorization rules to the current named policy.
605623

tests/test_management_api.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,25 @@ def test_modify_policy_api(self):
317317
],
318318
)
319319

320+
e.clear_policy()
321+
e.add_policies_ex([["user1", "data1", "read"], ["user1", "data1", "read"]])
322+
self.assertEqual(
323+
e.get_policy(),
324+
[["user1", "data1", "read"]],
325+
)
326+
e.add_policies_ex([["user1", "data1", "read"], ["user2", "data2", "read"]])
327+
self.assertEqual(
328+
e.get_policy(),
329+
[["user1", "data1", "read"], ["user2", "data2", "read"]],
330+
)
331+
e.add_named_policies_ex(
332+
"p", [["user1", "data1", "read"], ["user2", "data2", "read"], ["user3", "data3", "read"]]
333+
)
334+
self.assertEqual(
335+
e.get_policy(),
336+
[["user1", "data1", "read"], ["user2", "data2", "read"], ["user3", "data3", "read"]],
337+
)
338+
320339

321340
class TestManagementApiSynced(TestManagementApi):
322341
def get_enforcer(self, model=None, adapter=None):

0 commit comments

Comments
 (0)