Skip to content

Commit b4b8d54

Browse files
committed
first commit
1 parent ec1f398 commit b4b8d54

File tree

5 files changed

+175
-0
lines changed

5 files changed

+175
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .adapter import CasbinRule, Adapter
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)