Skip to content

Commit

Permalink
Merge e33ae5c into 8271dd4
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosgalvez-tiendeo committed Apr 8, 2021
2 parents 8271dd4 + e33ae5c commit 8eace53
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 9 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -34,3 +34,6 @@ nosetests.xml
.mr.developer.cfg
.project
.pydevproject

# IDE
.vscode
17 changes: 10 additions & 7 deletions flask_rbac/__init__.py
Expand Up @@ -398,7 +398,7 @@ def _check_permission(self, roles, method, resource):
self._setup_acl()

for r, m, res in itertools.product(_roles, _methods, _resources):
if self.acl.is_denied(r.get_name(), m, res):
if not r or self.acl.is_denied(r.get_name(), m, res):
return False

if not is_allowed and self.acl.is_allowed(r.get_name(), m, res):
Expand All @@ -420,28 +420,31 @@ def _deny_hook(self):

def _setup_acl(self):
for rn, method, resource, with_children in self.before_acl['allow']:
role = self._role_model.get_by_name(rn)
if rn == 'anonymous':
role = anonymous
else:
role = self._role_model.get_by_name(rn)
if not role:
continue
self.acl.allow(role, method, resource, with_children)

if not self.use_white:
to_deny_map = defaultdict(list)
all_roles = {x.get_name() if not isinstance(x, str)
else x for x in self._role_model.get_all()}

for role, method, resource, with_children in self.before_acl['allow']:
to_deny_map[(resource, role, with_children)].append(method)
for role, method, resource, in self.acl._allowed:
to_deny_map[(resource, role, False)].append(method)
for k, methods in to_deny_map.items():
view, role, with_children, = k
for r, m in itertools.product(all_roles - {role}, methods):
rule = (r, m, view, with_children)
if rule not in self.before_acl['allow']:
self.before_acl['deny'].append(rule)
rule = (r, m, view)
if rule not in self.acl._allowed:
self.before_acl['deny'].append(rule + (False,))

for rn, method, resource, with_children in self.before_acl['deny']:
role = self._role_model.get_by_name(rn)
if not role:
continue
self.acl.deny(role, method, resource, with_children)
self.acl.seted = True
2 changes: 1 addition & 1 deletion flask_rbac/model.py
Expand Up @@ -67,7 +67,7 @@ def get_by_name(name):
:param name: The name of role.
"""
return RoleMixin.roles[name]
return RoleMixin.roles.get(name)

@classmethod
def get_all(cls):
Expand Down
28 changes: 27 additions & 1 deletion test_rbac.py
Expand Up @@ -125,8 +125,21 @@ def g():
def h():
return Response('Hello from /h')

return app
@app.route('/i', methods=['GET'])
@after_decorator
@rbac.allow(['nonexistent'], methods=['GET'], with_children=False)
@before_decorator
def i():
return Response('Hello from /i')

@app.route('/j', methods=['GET'])
@after_decorator
@rbac.deny(['nonexistent'], methods=['GET'], with_children=False)
@before_decorator
def j():
return Response('Hello from /j')

return app

class UseWhiteApplicationUnitTests(unittest.TestCase):

Expand Down Expand Up @@ -242,6 +255,15 @@ def test_exempt(self):
current_user = normal_user
self.assertEqual(self.client.open('/g').data.decode('utf-8'), 'Hello from /g')

def test_allow_nonexistent_role(self):
current_user = normal_user
self.assertEqual(self.client.open('/i').status_code, 403)

def test_deny_nonexistent_role(self):
current_user = normal_user
self.assertEqual(self.client.open('/j').status_code, 403)



class NoWhiteApplicationUnitTests(unittest.TestCase):

Expand Down Expand Up @@ -289,6 +311,10 @@ def test_has_permission(self):
self.assertTrue(self.rbac.has_permission('GET', 'd'))
self.assertFalse(self.rbac.has_permission('POST', 'f'))

def test_deny_nonexistent_role(self):
current_user = normal_user
self.assertEqual(self.client.open('/j').data.decode('utf-8'), 'Hello from /j')


class RoleMixInUnitTests(unittest.TestCase):

Expand Down

0 comments on commit 8eace53

Please sign in to comment.