From 6a45aa28239fd495efd705d2c2d611ae2c38d4c2 Mon Sep 17 00:00:00 2001 From: Michael DeHaan Date: Sat, 23 Mar 2013 15:34:16 -0400 Subject: [PATCH] Added ability to list users under an organization, model additions to support. Simplified queryset lookup for various models. --- lib/main/base_views.py | 5 +++- lib/main/rbac.py | 1 + lib/main/tests.py | 17 ++++++++---- lib/main/views.py | 62 ++++++++++++++---------------------------- 4 files changed, 36 insertions(+), 49 deletions(-) diff --git a/lib/main/base_views.py b/lib/main/base_views.py index e84bd54519..cc16e68994 100644 --- a/lib/main/base_views.py +++ b/lib/main/base_views.py @@ -26,7 +26,10 @@ class BaseList(generics.ListCreateAPIView): raise exceptions.NotImplementedError def get_queryset(self): - return self._get_queryset().filter(active=True) + if self.__class__.model == User: + return self._get_queryset().filter(is_active=True) + else: + return self._get_queryset().filter(active=True) class BaseSubList(BaseList): diff --git a/lib/main/rbac.py b/lib/main/rbac.py index 2c44badb01..6ae2ded04c 100644 --- a/lib/main/rbac.py +++ b/lib/main/rbac.py @@ -48,3 +48,4 @@ class CustomRbac(permissions.BasePermission): if not view.item_permissions_check(request, obj): raise PermissionDenied() return True + diff --git a/lib/main/tests.py b/lib/main/tests.py index 93cb50cca1..26bdd2d601 100644 --- a/lib/main/tests.py +++ b/lib/main/tests.py @@ -224,15 +224,15 @@ class OrganizationsTest(BaseTest): self.get(projects0_url, expect=401, auth=None) self.get(projects0_url, expect=401, auth=self.get_invalid_credentials()) - # normal user is just a member of the first org, but can't see any projects yet - projects0a = self.get(projects0_url, expect=200, auth=self.get_normal_credentials()) - self.assertEquals(projects0a['count'], 0) + # normal user is just a member of the first org, but can't see any projects under the org + projects0a = self.get(projects0_url, expect=403, auth=self.get_normal_credentials()) # however in the second org, he's an admin and should see all of them projects1a = self.get(projects1_url, expect=200, auth=self.get_normal_credentials()) self.assertEquals(projects1a['count'], 5) - projects1b = self.get(projects1_url, expect=200, auth=self.get_other_credentials()) - self.assertEquals(projects1b['count'], 0) + + # but the non-admin cannot access the list of projects in the org. He should use /projects/ instead! + projects1b = self.get(projects1_url, expect=403, auth=self.get_other_credentials()) # superuser should be able to read anything projects9a = self.get(projects9_url, expect=200, auth=self.get_super_credentials()) @@ -240,7 +240,12 @@ class OrganizationsTest(BaseTest): def test_get_item_subobjects_users(self): - pass + + # see if we can list the users added to the organization + orgs = self.get(self.collection(), expect=200, auth=self.get_super_credentials()) + org1_users_url = orgs['results'][1]['related']['users'] + org1_users = self.get(org1_users_url, expect=200, auth=self.get_normal_credentials()) + self.assertEquals(org1_users['count'], 1) def test_get_item_subobjects_admins(self): pass diff --git a/lib/main/views.py b/lib/main/views.py index 437b9f8b79..cce35f4b80 100644 --- a/lib/main/views.py +++ b/lib/main/views.py @@ -26,11 +26,13 @@ class OrganizationsList(BaseList): # I am a member of the organization def _get_queryset(self): + ''' I can see organizations when I am a superuser, or I am an admin or user in that organization ''' + base = Organization.objects if self.request.user.is_superuser: - return Organization.objects.all() - return Organization.objects.filter( + return base.all() + return base.filter( admins__in = [ self.request.user ] - ).distinct() | Organization.objects.filter( + ).distinct() | base.filter( users__in = [ self.request.user ] ).distinct() @@ -52,19 +54,12 @@ class OrganizationsUsersList(BaseList): serializer_class = UserSerializer permission_classes = (CustomRbac,) - # I can see the users in the organization if: - # I am a super user - # I am an admin of the organization - def _get_queryset(self): - # FIXME: - base = User.objects.all(organizations__pk__in = [ self.kwargs.get('pk') ]) - if self.request.user.is_superuser: - return base.all() - return base.objects.filter( - organizations__organization__admins__in = [ self.request.user ] - ).distinct() - + ''' to list users in the organization, I must be a superuser or org admin ''' + organization = Organization.objects.get(pk=self.kwargs['pk']) + if not (self.request.user.is_superuser or self.request.user in organization.admins.all()): + raise PermissionDenied() + return User.objects.filter(organizations__in = [ organization ]) class OrganizationsAdminsList(BaseList): @@ -72,21 +67,12 @@ class OrganizationsAdminsList(BaseList): serializer_class = UserSerializer permission_classes = (CustomRbac,) - # I can see the admins in the organization if: - # I am a super user - # I am an admin of the organization - def _get_queryset(self): - - # FIXME - base = User.objects.all(admin_of_organizations__pk__in = [ self.kwargs.get('pk') ]) - - if self.request.user.is_superuser: - return base.all() - return base.filter( - organizations__organization__admins__in = [ self.request.user ] - ).distinct() - + ''' to list admins in the organization, I must be a superuser or org admin ''' + organization = Organization.objects.get(pk=self.kwargs['pk']) + if not self.request.user.is_superuser or self.request.user in organizations.admins.all(): + raise PermissionDenied() + return User.objects.all(admin_of_organizations__in = [ organization ]) class OrganizationsProjectsList(BaseSubList): @@ -97,20 +83,12 @@ class OrganizationsProjectsList(BaseSubList): parent_model = Organization # for sub list relationship = 'projects' # " " - # I can see the projects from the organization if: - # I'm the superuser - # I am a an administrator of the organization - # I am a member of a team on the project - def _get_queryset(self): - base = Project.objects.filter(organizations__in = [ self.kwargs.get('pk') ]) - if self.request.user.is_superuser: - return base.all() - return base.filter( - organizations__admins__in = [ self.request.user ] - ).distinct() | base.filter( - teams__users__in = [ self.request.user ] - ).distinct() + ''' to list projects in the organization, I must be a superuser or org admin ''' + organization = Organization.objects.get(pk=self.kwargs['pk']) + if not (self.request.user.is_superuser or self.request.user in organization.admins.all()): + raise PermissionDenied() + return Project.objects.filter(organizations__in = [ organization ]) class OrganizationsTagsList(BaseList): # FIXME: guts & tests