Skip to content

Commit

Permalink
- Sanitize and test RoleManager role handling
Browse files Browse the repository at this point in the history
  • Loading branch information
dataflake committed May 12, 2017
1 parent 87e0d29 commit d7373d8
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 20 deletions.
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ For changes before version 3.0, see ``HISTORY.rst``.
4.0a6 (unreleased)
------------------

- Sanitize and test `RoleManager` role handling

- Drop `Record` dependency, which now does its own security declaration.


Expand Down
26 changes: 6 additions & 20 deletions src/AccessControl/rolemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,41 +386,27 @@ def valid_roles(self):
"""Return list of valid roles.
"""
obj = self
valid = {}
valid = set()
x = 0
while x < 100:
if hasattr(obj, '__ac_roles__'):
roles = obj.__ac_roles__
for role in roles:
if role not in valid:
valid[role] = 1
valid.update(getattr(obj, '__ac_roles__', ()))
if getattr(obj, '__parent__', None) is None:
break
obj = obj.__parent__
x = x + 1
roles = sorted(valid.keys())
return tuple(roles)
return tuple(sorted(valid))

def validate_roles(self, roles):
"""Return true if all given roles are valid.
"""
valid = self.valid_roles()
for role in roles:
if role not in valid:
return 0
return 1
return set(roles) <= set(self.valid_roles())

security.declareProtected(change_permissions, 'userdefined_roles')
def userdefined_roles(self):
"""Return list of user-defined roles.
"""
roles = list(self.__ac_roles__)
for role in classattr(self.__class__, '__ac_roles__'):
try:
roles.remove(role)
except:
pass
return tuple(roles)
default_roles = classattr(self.__class__, '__ac_roles__')
return tuple(set(self.__ac_roles__) - set(default_roles))

def possible_permissions(self):
d = {}
Expand Down
39 changes: 39 additions & 0 deletions src/AccessControl/tests/testRole.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,42 @@ def test_manage_delLocalRoles(self):
root.context1.manage_delLocalRoles(['user1'])
roles = root.context1.get_local_roles_for_userid('user1')
self.assertEqual(roles, ())

def test_valid_roles(self):
from AccessControl.rolemanager import RoleManager
root, user = _makeRootAndUser()

# default case, __ac_roles__ not overridden
self.assertEqual(set(root.context1.valid_roles()),
set(RoleManager.__ac_roles__))

# forcing our own roles
root.context1.__ac_roles__ = ('Role2', 'Role1')
roles = root.context1.valid_roles()
self.assertEqual(roles, ('Role1', 'Role2'))

def test_validate_roles(self):
from AccessControl.rolemanager import RoleManager
root, user = _makeRootAndUser()

# default case, __ac_roles__ not overridden
self.assertTrue(root.context1.validate_roles(RoleManager.__ac_roles__))
self.assertFalse(root.context1.validate_roles(('Role1', 'Role2')))

# forcing our own roles
root.context1.__ac_roles__ = ('Role2', 'Role1')
self.assertFalse(root.context1.validate_roles(RoleManager.__ac_roles__))
self.assertTrue(root.context1.validate_roles(('Role1', 'Role2')))

def test_userdefined_roles(self):
from AccessControl.rolemanager import RoleManager
root, user = _makeRootAndUser()

# default case, __ac_roles__ not overridden
self.assertEqual(root.context1.userdefined_roles(), ())

# forcing our own roles
root.context1.__ac_roles__ = ('Role2', 'Role1')
self.assertEqual(set(root.context1.userdefined_roles()),
set(('Role1', 'Role2')))

0 comments on commit d7373d8

Please sign in to comment.