Skip to content

Commit 0d29ca7

Browse files
authored
Merge pull request #2 from wf-yamaday/feat/load_filtered_policy_with_raw_query
Support load_filtered_policy() with raw query
2 parents d44bd19 + f851317 commit 0d29ca7

File tree

3 files changed

+83
-5
lines changed

3 files changed

+83
-5
lines changed

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,39 @@ With this library, Casbin can load policy from MongoDB or save policy to it.
1616
Motor support a coroutine-based API for non-blocking access to MongoDB.
1717
So that, this adapter allows you to use pycasbin's [AsyncEnforcer](https://github.com/casbin/pycasbin/blob/master/casbin/async_enforcer.py).
1818

19+
### `load_policy()`
20+
21+
`load_policy()` loads all policies from storage.
22+
23+
```py
24+
import casbin_motor_adapter
25+
import casbin
26+
27+
adapter = casbin_motor_adapter.Adapter('mongodb://localhost:27017/', "dbname")
28+
29+
e = casbin.AsyncEnforcer('path/to/model.conf', adapter, True)
30+
await e.load_policy()
31+
32+
sub = "alice" # the user that wants to access a resource.
33+
obj = "data1" # the resource that is going to be accessed.
34+
act = "read" # the operation that the user performs on the resource.
35+
36+
if e.enforce(sub, obj, act):
37+
# permit alice to read data1
38+
pass
39+
else:
40+
# deny the request, show an error
41+
pass
42+
```
43+
44+
### `load_filtered_policy()`
45+
46+
`load_filtered_policy()` loads filtered policies from storage. This is useful for performance optimization.
47+
48+
> Policy Subset Loading, https://casbin.org/docs/policy-subset-loading
49+
50+
Additionally, `load_filtered_policy()` supports the MongoDB native queries for filtering conditions.
51+
1952
```py
2053
import casbin_motor_adapter
2154
import casbin
@@ -24,6 +57,22 @@ adapter = casbin_motor_adapter.Adapter('mongodb://localhost:27017/', "dbname")
2457

2558
e = casbin.AsyncEnforcer('path/to/model.conf', adapter, True)
2659

60+
# define filter conditions
61+
filter = Filter()
62+
filter.ptype = ["p"]
63+
filter.v0 = ["alice"]
64+
65+
# support MongoDB native query
66+
filter.raw_query = {
67+
"ptype": "p",
68+
"v0": {
69+
"$in": ["alice"]
70+
}
71+
}
72+
73+
# In this case, load only policies with sub value alice
74+
await e.load_filtered_policy(filter)
75+
2776
sub = "alice" # the user that wants to access a resource.
2877
obj = "data1" # the resource that is going to be accessed.
2978
act = "read" # the operation that the user performs on the resource.
@@ -34,6 +83,7 @@ if e.enforce(sub, obj, act):
3483
else:
3584
# deny the request, show an error
3685
pass
86+
3787
```
3888

3989
## Acknowledgments

casbin_motor_adapter/adapter.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class Filter:
2525
v4 = []
2626
v5 = []
2727

28+
# `raw_query` expected dict.
29+
# if set `raw_query`, all other filters are ignored
30+
raw_query = None
31+
2832

2933
class CasbinRule:
3034
"""
@@ -108,10 +112,13 @@ async def load_filtered_policy(self, model, filter):
108112
filter (Filter): Filter rule object
109113
"""
110114
query = {}
111-
for attr in ("ptype", "v0", "v1", "v2", "v3", "v4", "v5"):
112-
if len(getattr(filter, attr)) > 0:
113-
value = getattr(filter, attr)
114-
query[attr] = {'$in': value}
115+
if getattr(filter, "raw_query", None) is None:
116+
for attr in ("ptype", "v0", "v1", "v2", "v3", "v4", "v5"):
117+
if len(getattr(filter, attr)) > 0:
118+
value = getattr(filter, attr)
119+
query[attr] = {'$in': value}
120+
else:
121+
query = getattr(filter, "raw_query")
115122

116123
async for line in self._collection.find(query):
117124
if "ptype" not in line:

tests/test_adapter.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,25 @@ async def test_filtered_policy(self):
268268
self.assertFalse(e.enforce("bob", "data2", "read"))
269269
self.assertTrue(e.enforce("bob", "data2", "write"))
270270
self.assertFalse(e.enforce("data2_admin", "data2", "read"))
271-
self.assertTrue(e.enforce("data2_admin", "data2", "write"))
271+
self.assertTrue(e.enforce("data2_admin", "data2", "write"))
272+
273+
async def test_filtered_policy_with_raw_query(self):
274+
"""
275+
test filtered_policy
276+
"""
277+
e = await get_enforcer()
278+
filter = Filter()
279+
filter.raw_query = {
280+
"ptype": "p",
281+
"v0": {"$in": ["alice", "bob"]}
282+
}
283+
284+
await e.load_filtered_policy(filter)
285+
self.assertTrue(e.enforce("alice", "data1", "read"))
286+
self.assertFalse(e.enforce("alice", "data1", "write"))
287+
self.assertFalse(e.enforce("alice", "data2", "read"))
288+
self.assertFalse(e.enforce("alice", "data2", "write"))
289+
self.assertFalse(e.enforce("bob", "data1", "read"))
290+
self.assertFalse(e.enforce("bob", "data1", "write"))
291+
self.assertFalse(e.enforce("bob", "data2", "read"))
292+
self.assertTrue(e.enforce("bob", "data2", "write"))

0 commit comments

Comments
 (0)