redesign of organization counts for RBAC branch

This commit is contained in:
AlanCoding 2016-03-22 08:28:06 -04:00
parent 17daade6e6
commit e7d36299be
2 changed files with 34 additions and 41 deletions

View File

@ -578,49 +578,37 @@ class OrganizationList(ListCreateAPIView):
return full_context
db_results = {}
org_qs = self.request.user.get_queryset(self.model)
org_qs = self.model.accessible_objects(self.request.user, {"read": True})
org_id_list = org_qs.values('id')
if len(org_id_list) == 0:
if self.request.method == 'POST':
full_context['related_field_counts'] = {}
return full_context
inv_qs = self.request.user.get_queryset(Inventory)
project_qs = self.request.user.get_queryset(Project)
user_qs = self.request.user.get_queryset(User)
inv_qs = Inventory.accessible_objects(self.request.user, {"read": True})
project_qs = Project.accessible_objects(self.request.user, {"read": True})
# Produce counts of Foreign Key relationships
db_results['inventories'] = inv_qs\
.values('organization').annotate(Count('organization')).order_by('organization')
db_results['teams'] = self.request.user.get_queryset(Team)\
db_results['teams'] = Team.accessible_objects(
self.request.user, {"read": True}).values('organization').annotate(
Count('organization')).order_by('organization')
JT_reference = 'project__organization'
db_results['job_templates'] = JobTemplate.accessible_objects(
self.request.user, {"read": True}).values(JT_reference).annotate(
Count(JT_reference)).order_by(JT_reference)
db_results['projects'] = project_qs\
.values('organization').annotate(Count('organization')).order_by('organization')
# TODO: When RBAC branch merges, change this to project relationship
JT_reference = 'inventory__organization'
# Extra filter is applied on the inventory, because this catches
# the case of deleted (and purged) inventory
db_results['job_templates'] = self.request.user.get_queryset(JobTemplate)\
.filter(inventory__in=inv_qs)\
.values(JT_reference).annotate(Count(JT_reference))\
.order_by(JT_reference)
# Produce counts of m2m relationships
db_results['projects'] = Organization.projects.through.objects\
.filter(project__in=project_qs, organization__in=org_qs)\
.values('organization')\
.annotate(Count('organization')).order_by('organization')
# TODO: When RBAC branch merges, change these to role relation
db_results['users'] = Organization.users.through.objects\
.filter(user__in=user_qs, organization__in=org_qs)\
.values('organization')\
.annotate(Count('organization')).order_by('organization')
db_results['admins'] = Organization.admins.through.objects\
.filter(user__in=user_qs, organization__in=org_qs)\
.values('organization')\
.annotate(Count('organization')).order_by('organization')
# Other members and admins of organization are always viewable
db_results['users'] = org_qs.annotate(
users=Count('member_role__members', distinct=True),
admins=Count('admin_role__members', distinct=True)
).values('id', 'users', 'admins')
count_context = {}
for org in org_id_list:
@ -632,11 +620,17 @@ class OrganizationList(ListCreateAPIView):
for res in db_results:
if res == 'job_templates':
org_reference = JT_reference
elif res == 'users':
org_reference = 'id'
else:
org_reference = 'organization'
for entry in db_results[res]:
org_id = entry[org_reference]
if org_id in count_context:
if res == 'users':
count_context[org_id]['admins'] = entry['admins']
count_context[org_id]['users'] = entry['users']
continue
count_context[org_id][res] = entry['%s__count' % org_reference]
full_context['related_field_counts'] = count_context

View File

@ -8,9 +8,8 @@ def resourced_organization(organization, project, team, inventory, user):
member_user = user('org-member')
# Associate one resource of every type with the organization
organization.users.add(member_user)
organization.admins.add(admin_user)
organization.projects.add(project)
organization.member_role.members.add(member_user)
organization.admin_role.members.add(admin_user)
# organization.teams.create(name='org-team')
# inventory = organization.inventories.create(name="associated-inv")
project.jobtemplates.create(name="test-jt",
@ -41,17 +40,17 @@ def test_org_counts_admin(resourced_organization, user, get):
def test_org_counts_member(resourced_organization, get):
# Check that a non-admin user can only see the full project and
# user count, consistent with the RBAC rules
member_user = resourced_organization.users.get(username='org-member')
member_user = resourced_organization.member_role.members.get(username='org-member')
response = get(reverse('api:organization_list', args=[]), member_user)
assert response.status_code == 200
counts = response.data['results'][0]['summary_fields']['related_field_counts']
assert counts == {
'users': 1, # User can see themselves
'admins': 0,
'users': 1, # Policy is that members can see other users and admins
'admins': 1,
'job_templates': 0,
'projects': 1, # Projects are shared with all the organization
'projects': 0,
'inventories': 0,
'teams': 0
}
@ -118,20 +117,20 @@ def test_JT_associated_with_project(organizations, project, user, get):
other_org = two_orgs[1]
unrelated_inv = other_org.inventories.create(name='not-in-organization')
organization.projects.add(project)
project.jobtemplates.create(name="test-jt",
description="test-job-template-desc",
inventory=unrelated_inv,
playbook="test_playbook.yml")
organization.projects.add(project)
response = get(reverse('api:organization_list', args=[]), external_admin)
assert response.status_code == 200
org_id = organization.id
counts = {}
for i in range(2):
working_id = response.data['results'][i]['id']
counts[working_id] = response.data['results'][i]['summary_fields']['related_field_counts']
for org_json in response.data['results']:
working_id = org_json['id']
counts[working_id] = org_json['summary_fields']['related_field_counts']
assert counts[org_id] == {
'users': 0,