Skip to content

Commit

Permalink
security: add Creator & Owner roles
Browse files Browse the repository at this point in the history
  • Loading branch information
Bertrand Mathieu committed May 20, 2015
1 parent 4baa009 commit 029d506
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
4 changes: 3 additions & 1 deletion abilian/services/security/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
__all__ = ['RoleAssignment', 'SecurityAudit', 'InheritSecurity',
'Permission', 'MANAGE', 'READ', 'WRITE',
'Role', 'Anonymous', 'Authenticated', 'Admin', 'Manager',
'Reader', 'Writer',
'Creator', 'Owner', 'Reader', 'Writer',
'RoleType']


Expand Down Expand Up @@ -119,6 +119,8 @@ def process_result_value(self, value, dialect):
#: marker for `manager` role
Manager = Role('manager', _l(u'role_manager'), assignable=False)

Creator = Role('creator', assignable=False)
Owner = Role('owner', assignable=False)
Reader = Role('reader', assignable=False)
Writer = Role('writer', assignable=False)

Expand Down
20 changes: 17 additions & 3 deletions abilian/services/security/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from abilian.services import Service, ServiceState
from abilian.services.security.models import (
SecurityAudit, RoleAssignment, Anonymous, Admin, Manager,
Owner, Creator,
InheritSecurity, Role, Permission, READ, WRITE
)

Expand Down Expand Up @@ -137,12 +138,19 @@ def get_roles(self, principal, object=None):
assert isinstance(object, Entity)

q = q.filter(RoleAssignment.object == object)
return [i[0] for i in q.all()]
roles = {i[0] for i in q.all()}

if object is not None:
for attr, role in (('creator', Creator), ('owner', Owner)):
if getattr(object, attr) == principal:
roles.add(role)
return list(roles)

@require_flush
def get_principals(self, role, anonymous=True, users=True, groups=True,
object=None):
""" Return all users which are assigned given role
"""
Return all users which are assigned given role
"""
if not isinstance(role, Role):
role = Role(role)
Expand All @@ -158,8 +166,14 @@ def get_principals(self, role, anonymous=True, users=True, groups=True,
q = q.filter(RoleAssignment.group == None)

q = q.filter(RoleAssignment.object == object)
principals = {(ra.user or ra.group) for ra in q.all()}

if object is not None and role in (Creator, Owner):
p = object.creator if role == Creator else object.owner
if p:
principals.add(p)

return [(ra.user or ra.group) for ra in q.all()]
return list(principals)

@require_flush
def _all_roles(self, principal):
Expand Down
25 changes: 24 additions & 1 deletion abilian/services/security/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from . import (
security, RoleAssignment, InheritSecurity, SecurityAudit,
Role, Permission, READ, WRITE, Reader, Writer,
Role, Permission, READ, WRITE, Reader, Writer, Owner, Creator,
Admin, Anonymous, Authenticated)


Expand Down Expand Up @@ -100,6 +100,7 @@ def test_grant_basic_roles(self):
assert security.has_role(user, Admin)
assert security.get_roles(user) == [Admin]
assert security.get_roles(user) == ['admin']
assert security.get_principals(Admin) == [user]

# clear roles cache for better coverage: has_permission uses
# _fill_role_cache_batch(), get_roles uses _fill_role_cache()
Expand All @@ -111,6 +112,7 @@ def test_grant_basic_roles(self):
security.ungrant_role(user, "admin")
assert not security.has_role(user, "admin")
assert security.get_roles(user) == []
assert security.get_principals(Admin) == []

assert not security.has_permission(user, "read")
assert not security.has_permission(user, "write")
Expand All @@ -126,6 +128,7 @@ def test_grant_basic_roles_on_groups(self):
security.grant_role(group, "admin")
assert security.has_role(group, "admin")
assert security.get_roles(group) == ['admin']
assert security.get_principals(Admin) == [group]

assert security.has_permission(user, "read")
assert security.has_permission(user, "write")
Expand All @@ -134,6 +137,7 @@ def test_grant_basic_roles_on_groups(self):
security.ungrant_role(group, "admin")
assert not security.has_role(group, "admin")
assert security.get_roles(group) == []
assert security.get_principals(Admin) == []

assert not security.has_permission(user, "read")
assert not security.has_permission(user, "write")
Expand All @@ -151,6 +155,8 @@ def test_grant_roles_on_objects(self):
security.grant_role(user, "reader", obj)
assert security.has_role(user, "reader", obj)
assert security.get_roles(user, obj) == ['reader']
assert security.get_principals(Reader) == []
assert security.get_principals(Reader, object=obj) == [user]

assert security.has_permission(user, "read", obj)
assert not security.has_permission(user, "write", obj)
Expand All @@ -167,6 +173,23 @@ def test_grant_roles_on_objects(self):
assert not security.has_permission(user, "write", obj)
assert not security.has_permission(user, "manage", obj)

# owner / creator roles
assert security.get_principals(Owner, object=obj) == []
assert security.get_principals(Creator, object=obj) == []
old_owner = obj.owner
old_creator = obj.creator
obj.owner = user
assert security.get_roles(user, obj) == [Owner]
assert security.get_principals(Owner, object=obj) == [user]
assert security.get_principals(Creator, object=obj) == []
obj.owner = old_owner
obj.creator = user
assert security.get_roles(user, obj) == [Creator]
assert security.get_principals(Owner, object=obj) == []
assert security.get_principals(Creator, object=obj) == [user]
obj.creator = old_creator

# permissions through group membership
security.grant_role(group, "manager", obj)
assert security.has_role(group, "manager", obj)
assert security.get_roles(group, obj) == ['manager']
Expand Down

0 comments on commit 029d506

Please sign in to comment.