Added direct access via teams to the access_list endpoint

This commit is contained in:
Akita Noek 2016-04-07 11:13:24 -04:00
parent 4531f276c2
commit 09f1473ef9
2 changed files with 71 additions and 32 deletions

View File

@ -1469,6 +1469,16 @@ class RoleSerializer(BaseSerializer):
class ResourceAccessListElementSerializer(UserSerializer):
def to_representation(self, user):
'''
With this method we derive "direct" and "indirect" access lists. Contained
in the direct access list are all the roles the user is a member of, and
all of the roles that are directly granted to any teams that the user is a
member of.
The indirect access list is a list of all of the roles that the user is
a member of that are ancestors of any roles that grant permissions to
the resource.
'''
ret = super(ResourceAccessListElementSerializer, self).to_representation(user)
object_id = self.context['view'].object_id
obj = self.context['view'].resource_model.objects.get(pk=object_id)
@ -1487,8 +1497,8 @@ class ResourceAccessListElementSerializer(UserSerializer):
pass
return { 'role': role_dict, 'permissions': get_role_permissions_on_resource(obj, role)}
def format_team_role_perm(team_role, all_permissive_role_ids):
role = team_role.children.filter(id__in=all_permissive_role_ids)[0]
def format_team_role_perm(team_role, permissive_role_ids):
role = team_role.children.filter(id__in=permissive_role_ids)[0]
role_dict = {
'id': role.id,
@ -1507,24 +1517,37 @@ class ResourceAccessListElementSerializer(UserSerializer):
team_content_type = ContentType.objects.get_for_model(Team)
content_type = ContentType.objects.get_for_model(obj)
direct_permissive_role_ids = RolePermission.objects.filter(content_type=content_type, object_id=obj.id).values_list('role__id')
direct_access_roles = user.roles.filter(id__in=direct_permissive_role_ids).all()
ret['summary_fields']['direct_access'] = [format_role_perm(r) for r in direct_access_roles]
direct_permissive_role_ids = RolePermission.objects.filter(content_type=content_type, object_id=obj.id).values_list('role__id')
all_permissive_role_ids = RolePermission.objects.filter(content_type=content_type, object_id=obj.id).values_list('role__ancestors__id')
team_roles = Role.objects \
.filter(content_type=team_content_type,
members=user,
children__in=all_permissive_role_ids)
direct_access_roles = user.roles \
.filter(id__in=direct_permissive_role_ids).all()
direct_team_roles = Role.objects \
.filter(content_type=team_content_type,
members=user,
children__in=direct_permissive_role_ids)
indirect_team_roles = Role.objects \
.filter(content_type=team_content_type,
members=user,
children__in=all_permissive_role_ids) \
.exclude(id__in=direct_team_roles)
indirect_access_roles = user.roles \
.filter(id__in=all_permissive_role_ids) \
.filter(id__in=all_permissive_role_ids) \
.exclude(id__in=direct_permissive_role_ids) \
.exclude(id__in=team_roles)
.exclude(id__in=direct_team_roles) \
.exclude(id__in=indirect_team_roles)
ret['summary_fields']['direct_access'] \
= [format_role_perm(r) for r in direct_access_roles] \
+ [format_team_role_perm(r, direct_permissive_role_ids) for r in direct_team_roles]
ret['summary_fields']['indirect_access'] \
= [format_role_perm(r) for r in indirect_access_roles] \
+ [format_team_role_perm(r, all_permissive_role_ids) for r in team_roles]
+ [format_team_role_perm(r, all_permissive_role_ids) for r in indirect_team_roles]
return ret

View File

@ -3,38 +3,54 @@ import pytest
from django.core.urlresolvers import reverse
@pytest.mark.django_db
def test_indirect_access_list(get, organization, project, team, alice, bob, admin):
def test_indirect_access_list(get, organization, project, team_factory, user, admin):
project_admin = user('project_admin')
org_admin_team_member = user('org_admin_team_member')
project_admin_team_member = user('project_admin_team_member')
project.admin_role.members.add(alice)
team.member_role.members.add(bob)
team.member_role.children.add(organization.admin_role)
org_admin_team = team_factory('org-admin-team')
project_admin_team = team_factory('project-admin-team')
project.admin_role.members.add(project_admin)
org_admin_team.member_role.members.add(org_admin_team_member)
org_admin_team.member_role.children.add(organization.admin_role)
project_admin_team.member_role.members.add(project_admin_team_member)
project_admin_team.member_role.children.add(project.admin_role)
result = get(reverse('api:project_access_list', args=(project.id,)), admin)
assert result.status_code == 200
# Result should be alice should have direct access, bob should have
# indirect access through being a team member -> org admin -> project admin,
# and admin should have access through system admin -> org admin -> project admin
assert result.data['count'] == 3
# Result should be:
# project_admin should have direct access,
# project_team_admin should have "direct" access through being a team member -> project admin,
# org_admin_team_member should have indirect access through being a team member -> org admin -> project admin,
# admin should have access through system admin -> org admin -> project admin
assert result.data['count'] == 4
alice_res = [r for r in result.data['results'] if r['id'] == alice.id][0]
bob_res = [r for r in result.data['results'] if r['id'] == bob.id][0]
project_admin_res = [r for r in result.data['results'] if r['id'] == project_admin.id][0]
org_admin_team_member_res = [r for r in result.data['results'] if r['id'] == org_admin_team_member.id][0]
project_admin_team_member_res = [r for r in result.data['results'] if r['id'] == project_admin_team_member.id][0]
admin_res = [r for r in result.data['results'] if r['id'] == admin.id][0]
assert len(alice_res['summary_fields']['direct_access']) == 1
assert len(alice_res['summary_fields']['indirect_access']) == 0
assert len(bob_res['summary_fields']['direct_access']) == 0
assert len(bob_res['summary_fields']['indirect_access']) == 1
assert len(project_admin_res['summary_fields']['direct_access']) == 1
assert len(project_admin_res['summary_fields']['indirect_access']) == 0
assert len(org_admin_team_member_res['summary_fields']['direct_access']) == 0
assert len(org_admin_team_member_res['summary_fields']['indirect_access']) == 1
assert len(admin_res['summary_fields']['direct_access']) == 0
assert len(admin_res['summary_fields']['indirect_access']) == 1
alice_entry = alice_res['summary_fields']['direct_access'][0]['role']
assert alice_entry['id'] == project.admin_role.id
project_admin_entry = project_admin_res['summary_fields']['direct_access'][0]['role']
assert project_admin_entry['id'] == project.admin_role.id
bob_entry = bob_res['summary_fields']['indirect_access'][0]['role']
assert bob_entry['id'] == organization.admin_role.id
assert bob_entry['team_id'] == team.id
assert bob_entry['team_name'] == team.name
project_admin_team_member_entry = project_admin_team_member_res['summary_fields']['direct_access'][0]['role']
assert project_admin_team_member_entry['id'] == project.admin_role.id
assert project_admin_team_member_entry['team_id'] == project_admin_team.id
assert project_admin_team_member_entry['team_name'] == project_admin_team.name
org_admin_team_member_entry = org_admin_team_member_res['summary_fields']['indirect_access'][0]['role']
assert org_admin_team_member_entry['id'] == organization.admin_role.id
assert org_admin_team_member_entry['team_id'] == org_admin_team.id
assert org_admin_team_member_entry['team_name'] == org_admin_team.name
admin_entry = admin_res['summary_fields']['indirect_access'][0]['role']
assert admin_entry['name'] == 'System Administrator'