diff options
| author | bwreilly | 2013-09-06 12:35:06 -0500 | 
|---|---|---|
| committer | bwreilly | 2013-09-06 12:35:06 -0500 | 
| commit | b07de86ad372a185c05c1dd77ccd7bee3801996e (patch) | |
| tree | 99586e7fa97b3c4cd939bf5ebf055e14d02bcfa0 | |
| parent | 4a9dcfa76089143bbeb5cd43fa3a406365d89e96 (diff) | |
| download | django-rest-framework-b07de86ad372a185c05c1dd77ccd7bee3801996e.tar.bz2 | |
some properly failing tests, set up for standard permissions
| -rw-r--r-- | rest_framework/permissions.py | 2 | ||||
| -rw-r--r-- | rest_framework/runtests/settings.py | 11 | ||||
| -rw-r--r-- | rest_framework/tests/test_permissions.py | 109 | ||||
| -rw-r--r-- | tox.ini | 8 | 
4 files changed, 84 insertions, 46 deletions
| diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py index 6d213ba1..b67be414 100644 --- a/rest_framework/permissions.py +++ b/rest_framework/permissions.py @@ -153,7 +153,7 @@ class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions):  class DjangoObjectLevelModelPermissions(DjangoModelPermissions):      def __init__(self): -        assert guardian, 'Using DjangoObjectLevelModelPermissions, but guardian is not installed' +        assert guardian, 'Using DjangoObjectLevelModelPermissions, but django-guardian is not installed'  class TokenHasReadWriteScope(BasePermission): diff --git a/rest_framework/runtests/settings.py b/rest_framework/runtests/settings.py index b3702d0b..6750376f 100644 --- a/rest_framework/runtests/settings.py +++ b/rest_framework/runtests/settings.py @@ -123,6 +123,17 @@ else:          'provider.oauth2',      ) +# guardian is optional +try: +    import guardian +except ImportError: +    pass +else: +    ANONYMOUS_USER_ID = -1 +    INSTALLED_APPS += ( +        'guardian', +    ) +  STATIC_URL = '/static/'  PASSWORD_HASHERS = ( diff --git a/rest_framework/tests/test_permissions.py b/rest_framework/tests/test_permissions.py index d1171cce..dcdb4eea 100644 --- a/rest_framework/tests/test_permissions.py +++ b/rest_framework/tests/test_permissions.py @@ -3,17 +3,14 @@ from django.contrib.auth.models import User, Permission  from django.db import models  from django.test import TestCase  from rest_framework import generics, status, permissions, authentication, HTTP_HEADER_ENCODING -from rest_framework.test import APIRequestFactory  from rest_framework.compat import guardian +from rest_framework.test import APIRequestFactory +from rest_framework.tests.models import BasicModel +from rest_framework.settings import api_settings  import base64  factory = APIRequestFactory() - -class BasicModel(models.Model): -    text = models.CharField(max_length=100) - -  class RootView(generics.ListCreateAPIView):      model = BasicModel      authentication_classes = [authentication.BasicAuthentication] @@ -145,45 +142,67 @@ class ModelPermissionsIntegrationTests(TestCase):          self.assertEqual(list(response.data['actions'].keys()), ['PUT']) -class OwnerModel(models.Model): -    text = models.CharField(max_length=100) -    owner = models.ForeignKey(User) +class BasicPermModel(BasicModel): +    class Meta: +        app_label = 'tests' +        permissions = ( +            ('read_basicpermmodel', "Can view basic perm model"), +            # add, change, delete built in to django +        ) -class IsOwnerPermission(permissions.BasePermission): -    def has_object_permission(self, request, view, obj): -        return request.user == obj.owner - - -class OwnerInstanceView(generics.RetrieveUpdateDestroyAPIView): -    model = OwnerModel +class ObjectPermissionInstanceView(generics.RetrieveUpdateDestroyAPIView): +    model = BasicModel      authentication_classes = [authentication.BasicAuthentication] -    permission_classes = [IsOwnerPermission] - - -owner_instance_view = OwnerInstanceView.as_view() - - -class ObjectPermissionsIntegrationTests(TestCase): -    """ -    Integration tests for the object level permissions API. -    """ - -    def setUp(self): -        User.objects.create_user('not_owner', 'not_owner@example.com', 'password') -        user = User.objects.create_user('owner', 'owner@example.com', 'password') - -        self.not_owner_credentials = basic_auth_header('not_owner', 'password') -        self.owner_credentials = basic_auth_header('owner', 'password') - -        OwnerModel(text='foo', owner=user).save() - -    def test_owner_has_delete_permissions(self): -        request = factory.delete('/1', HTTP_AUTHORIZATION=self.owner_credentials) -        response = owner_instance_view(request, pk='1') -        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - -    def test_non_owner_does_not_have_delete_permissions(self): -        request = factory.delete('/1', HTTP_AUTHORIZATION=self.not_owner_credentials) -        response = owner_instance_view(request, pk='1') -        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) +    permission_classes = [permissions.DjangoObjectLevelModelPermissions] + + +object_permissions_view = ObjectPermissionInstanceView.as_view() + +if guardian: +    class ObjectPermissionsIntegrationTests(TestCase): +        """ +        Integration tests for the object level permissions API. +        """ + +        def setUp(self): +            # create users +            User.objects.create_user('no_permission', 'no_permission@example.com', 'password') +            reader = User.objects.create_user('reader', 'reader@example.com', 'password') +            writer = User.objects.create_user('writer', 'writer@example.com', 'password') +            full_access = User.objects.create_user('full_access', 'full_access@example.com', 'password') +             +            model = BasicPermModel.objects.create(text='foo') + +            # assign permissions appropriately +            from guardian.shortcuts import assign_perm + +            read = "read_basicpermmodel" +            write = "change_basicpermmodel" +            delete = "delete_basicpermmodel" +            app_label = 'tests.' +            # model level permissions +            assign_perm(app_label + delete, full_access, obj=model) +            (assign_perm(app_label + write, user, obj=model) for user in (writer, full_access)) +            (assign_perm(app_label + read, user, obj=model) for user in (reader, writer, full_access)) + +            # object level permissions +            assign_perm(delete, full_access, obj=model) +            (assign_perm(write, user, obj=model) for user in (writer, full_access)) +            (assign_perm(read, user, obj=model) for user in (reader, writer, full_access)) + +            self.no_permission_credentials = basic_auth_header('no_permission', 'password') +            self.reader_credentials = basic_auth_header('reader', 'password') +            self.writer_credentials = basic_auth_header('writer', 'password') +            self.full_access_credentials = basic_auth_header('full_access', 'password') + + +        def test_has_delete_permissions(self): +            request = factory.delete('/1', HTTP_AUTHORIZATION=self.full_access_credentials) +            response = object_permissions_view(request, pk='1') +            self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + +        def test_no_delete_permissions(self): +            request = factory.delete('/1', HTTP_AUTHORIZATION=self.writer_credentials) +            response = object_permissions_view(request, pk='1') +            self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) @@ -25,6 +25,7 @@ deps = https://www.djangoproject.com/download/1.6a1/tarball/         django-oauth-plus==2.0         oauth2==1.5.211         django-oauth2-provider==0.2.4 +       django-guardian==1.1.1  [testenv:py2.6-django1.6]  basepython = python2.6 @@ -34,6 +35,7 @@ deps = https://www.djangoproject.com/download/1.6a1/tarball/         django-oauth-plus==2.0         oauth2==1.5.211         django-oauth2-provider==0.2.4 +       django-guardian==1.1.1  [testenv:py3.3-django1.5]  basepython = python3.3 @@ -55,6 +57,7 @@ deps = django==1.5         django-oauth-plus==2.0         oauth2==1.5.211         django-oauth2-provider==0.2.3 +       django-guardian==1.1.1  [testenv:py2.6-django1.5]  basepython = python2.6 @@ -64,6 +67,7 @@ deps = django==1.5         django-oauth-plus==2.0         oauth2==1.5.211         django-oauth2-provider==0.2.3 +       django-guardian==1.1.1  [testenv:py2.7-django1.4]  basepython = python2.7 @@ -73,6 +77,7 @@ deps = django==1.4.3         django-oauth-plus==2.0         oauth2==1.5.211         django-oauth2-provider==0.2.3 +       django-guardian==1.1.1  [testenv:py2.6-django1.4]  basepython = python2.6 @@ -82,6 +87,7 @@ deps = django==1.4.3         django-oauth-plus==2.0         oauth2==1.5.211         django-oauth2-provider==0.2.3 +       django-guardian==1.1.1  [testenv:py2.7-django1.3]  basepython = python2.7 @@ -91,6 +97,7 @@ deps = django==1.3.5         django-oauth-plus==2.0         oauth2==1.5.211         django-oauth2-provider==0.2.3 +       django-guardian==1.1.1  [testenv:py2.6-django1.3]  basepython = python2.6 @@ -100,3 +107,4 @@ deps = django==1.3.5         django-oauth-plus==2.0         oauth2==1.5.211         django-oauth2-provider==0.2.3 +       django-guardian==1.1.1 | 
