diff --git a/lib/main/rbac.py b/lib/main/rbac.py index 8ee036baf8..f9af183510 100644 --- a/lib/main/rbac.py +++ b/lib/main/rbac.py @@ -28,7 +28,13 @@ class CustomRbac(permissions.BasePermission): if not self._common_user_check(request): return False if obj is None: - # filtering happens in the view + if getattr(view, 'list_permissions_check', None): + if request.user.is_superuser: + return True + if not view.list_permissions_check(request): + raise PermissionDenied() + elif not getattr(view, 'item_permissions_check', None): + raise Exception("internal error, list_permissions_check or item_permissions_check must be defined") return True else: # haven't tested around these confines yet @@ -39,6 +45,6 @@ class CustomRbac(permissions.BasePermission): return True if not self._common_user_check(request): return False - if not view.permissions_check(request, obj): + if not view.item_permissions_check(request, obj): raise PermissionDenied() return True diff --git a/lib/main/serializers.py b/lib/main/serializers.py index 7a69c9eb85..b57c09447f 100644 --- a/lib/main/serializers.py +++ b/lib/main/serializers.py @@ -2,6 +2,10 @@ from django.contrib.auth.models import User as DjangoUser from lib.main.models import User, Organization, Project from rest_framework import serializers, pagination +# FIXME: add all fields here +# FIXME: make proper fields read only +# FIXME: add URLs for sub resources like /organizations/2/projects/ + class OrganizationSerializer(serializers.ModelSerializer): url = serializers.CharField(source='get_absolute_url', read_only=True) diff --git a/lib/main/tests.py b/lib/main/tests.py index 0a569a196d..882384bc6b 100644 --- a/lib/main/tests.py +++ b/lib/main/tests.py @@ -185,7 +185,23 @@ class OrganizationsTest(BaseTest): pass def test_post_item(self): - pass + + new_org = dict(name='magic test org', description='8675309') + + # need to be a valid user + self.post(self.collection(), new_org, expect=401, auth=None) + self.post(self.collection(), new_org, expect=401, auth=self.get_invalid_credentials()) + + # only super users can create organizations + self.post(self.collection(), new_org, expect=403, auth=self.get_normal_credentials()) + self.post(self.collection(), new_org, expect=403, auth=self.get_other_credentials()) + data1 = self.post(self.collection(), new_org, expect=201, auth=self.get_super_credentials()) + + # duplicate post results in 400 + data2 = self.post(self.collection(), new_org, expect=400, auth=self.get_super_credentials()) + + # look at what we got back from the post, make sure we added an org + self.assertTrue(data1['url'].endswith("/11/")) def test_post_item_subobjects_projects(self): pass @@ -222,6 +238,9 @@ class OrganizationsTest(BaseTest): # super user can also put even though they aren't added to the org users or admins list self.put(urls[1], new_data1, expect=200, auth=self.get_super_credentials()) + # make sure posting to this URL is not supported + self.post(urls[1], new_data1, expect=405, auth=self.get_super_credentials()) + def test_put_item_subobjects_projects(self): pass diff --git a/lib/main/views.py b/lib/main/views.py index 3f81b5a892..3398b422ab 100644 --- a/lib/main/views.py +++ b/lib/main/views.py @@ -25,7 +25,13 @@ class OrganizationsList(generics.ListCreateAPIView): return Organization.objects.filter(active = True, admins__in = [ self.request.user.application_user ]).distinct() | \ Organization.objects.filter(active = True, users__in = [ self.request.user.application_user ]).distinct() - def permissions_check(self, request, obj): + def list_permissions_check(self, request, obj=None): + if request.method == 'GET': + # everybody can call get, but it's filtered + return True + if request.method == 'POST': + # superusers have already been cleared, so deny regular users + return False raise exceptions.NotImplementedError @@ -38,13 +44,13 @@ class OrganizationsDetail(generics.RetrieveUpdateDestroyAPIView): #def pre_save(self, obj): # obj.owner = self.request.user - def permissions_check(self, request, obj): - admin = request.user.application_user in obj.admins.all() - user = request.user.application_user in obj.users.all() - if request.method == 'GET': - return admin or user - if request.method == 'PUT': - return admin + def item_permissions_check(self, request, obj): + admin = request.user.application_user in obj.admins.all() + user = request.user.application_user in obj.users.all() + if request.method == 'GET': + return admin or user + if request.method == 'PUT': + return admin