Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b4b8d54

Browse files
first commit
1 parent ec1f398 commit b4b8d54

File tree

5 files changed

+175
-0
lines changed

5 files changed

+175
-0
lines changed

‎casbin_sqlobject_adapter/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .adapter import CasbinRule, Adapter

‎casbin_sqlobject_adapter/adapter.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
from casbin import persist
2+
from sqlobject import *
3+
4+
5+
class CasbinRule(SQLObject):
6+
7+
class sqlmeta:
8+
9+
table = 'casbin_rule'
10+
11+
ptype = StringCol(length=255)
12+
v0 = StringCol(length=255, default=None)
13+
v1 = StringCol(length=255, default=None)
14+
v2 = StringCol(length=255, default=None)
15+
v3 = StringCol(length=255, default=None)
16+
v4 = StringCol(length=255, default=None)
17+
v5 = StringCol(length=255, default=None)
18+
19+
def __str__(self):
20+
arr = [self.ptype]
21+
for v in (self.v0, self.v1, self.v2, self.v3, self.v4, self.v5):
22+
if v is None:
23+
break
24+
arr.append(v)
25+
return ', '.join(arr)
26+
27+
def __repr__(self):
28+
return '<CasbinRule {}: "{}">'.format(self.id, str(self))
29+
30+
31+
32+
33+
34+
class Adapter(persist.Adapter):
35+
"""the interface for Casbin adapters."""
36+
37+
def __init__(self, connection_string):
38+
self._conhandler = connectionForURI(connection_string)
39+
sqlhub.processConnection = self._conhandler
40+
41+
42+
def load_policy(self, model):
43+
"""loads all policy rules from the storage."""
44+
count = CasbinRule.select().count()
45+
for i in range(1,1+count):
46+
line = CasbinRule.get(i)
47+
persist.load_policy_line(str(line), model)
48+
49+
def _save_policy_line(self, ptype, rule):
50+
line = CasbinRule.selectBy(ptype=ptype)
51+
for i, v in enumerate(rule):
52+
setattr(line, 'v{}'.format(i), v)
53+
54+
55+
def save_policy(self, model):
56+
"""saves all policy rules to the storage."""
57+
for sec in ["p", "g"]:
58+
if sec not in model.model.keys():
59+
continue
60+
for ptype, ast in model.model[sec].items():
61+
for rule in ast.policy:
62+
self._save_policy_line(ptype, rule)
63+
64+
return True
65+
66+
def add_policy(self, sec, ptype, rule):
67+
"""adds a policy rule to the storage."""
68+
self._save_policy_line(ptype, rule)
69+
70+
71+
def remove_policy(self, sec, ptype, rule):
72+
"""removes a policy rule from the storage."""
73+
pass
74+
75+
def remove_filtered_policy(self, sec, ptype, field_index, *field_values):
76+
"""removes policy rules that match the filter from the storage.
77+
This is part of the Auto-Save feature.
78+
"""
79+
pass
80+
81+
82+

‎tests/rbac_model.conf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[request_definition]
2+
r = sub, obj, act
3+
4+
[policy_definition]
5+
p = sub, obj, act
6+
7+
[role_definition]
8+
g = _, _
9+
10+
[policy_effect]
11+
e = some(where (p.eft == allow))
12+
13+
[matchers]
14+
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

‎tests/rbac_policy.csv

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
p, alice, data1, read
2+
p, bob, data2, write
3+
p, data2_admin, data2, read
4+
p, data2_admin, data2, write
5+
6+
g, alice, data2_admin

‎tests/test_adapter.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import os
2+
import unittest
3+
4+
import casbin
5+
6+
from casbin_sqlobject_adapter import Adapter
7+
from casbin_sqlobject_adapter import CasbinRule
8+
9+
10+
def get_fixture(path):
11+
dir_path = os.path.split(os.path.realpath(__file__))[0] + "/"
12+
return os.path.abspath(dir_path + path)
13+
14+
15+
def get_enforcer():
16+
con_string = 'sqlite:/:memory:'
17+
adapter = Adapter(con_string)
18+
19+
CasbinRule.createTable(ifNotExists=True)
20+
CasbinRule(ptype='p', v0='alice', v1='data1', v2='read')
21+
CasbinRule(ptype='p', v0='bob', v1='data2', v2='write')
22+
CasbinRule(ptype='p', v0='data2_admin', v1='data2', v2='read')
23+
CasbinRule(ptype='p', v0='data2_admin', v1='data2', v2='write')
24+
CasbinRule(ptype='g', v0='alice', v1='data2_admin')
25+
26+
return casbin.Enforcer(get_fixture('rbac_model.conf'), adapter)
27+
28+
29+
class TestConfig(unittest.TestCase):
30+
31+
def test_enforcer_basic(self):
32+
e = get_enforcer()
33+
34+
self.assertTrue(e.enforce('alice', 'data1', 'read'))
35+
self.assertFalse(e.enforce('bob', 'data1', 'read'))
36+
self.assertTrue(e.enforce('bob', 'data2', 'write'))
37+
self.assertTrue(e.enforce('alice', 'data2', 'read'))
38+
self.assertTrue(e.enforce('alice', 'data2', 'write'))
39+
40+
def test_add_policy(self):
41+
e = get_enforcer()
42+
43+
self.assertFalse(e.enforce('eve', 'data3', 'read'))
44+
res = e.add_permission_for_user('eve', 'data3', 'read')
45+
self.assertTrue(res)
46+
self.assertTrue(e.enforce('eve', 'data3', 'read'))
47+
48+
def test_save_policy(self):
49+
e = get_enforcer()
50+
self.assertFalse(e.enforce('alice', 'data4', 'read'))
51+
52+
model = e.get_model()
53+
model.clear_policy()
54+
55+
model.add_policy('p', 'p', ['alice', 'data4', 'read'])
56+
57+
adapter = e.get_adapter()
58+
adapter.save_policy(model)
59+
self.assertTrue(e.enforce('alice', 'data4', 'read'))
60+
61+
def test_str(self):
62+
rule = CasbinRule(ptype='p', v0='alice', v1='data1', v2='read')
63+
self.assertEqual(str(rule), 'p, alice, data1, read')
64+
65+
66+
def test_repr(self):
67+
rule = CasbinRule(ptype='p', v0='alice', v1='data1', v2='read')
68+
self.assertRegex(repr(rule), r'<CasbinRule \d+: "p, alice, data1, read">')
69+
70+
if(__name__=='__main__'):
71+
unittest.main()
72+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /