aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbwreilly2013-09-06 12:35:06 -0500
committerbwreilly2013-09-06 12:35:06 -0500
commitb07de86ad372a185c05c1dd77ccd7bee3801996e (patch)
tree99586e7fa97b3c4cd939bf5ebf055e14d02bcfa0
parent4a9dcfa76089143bbeb5cd43fa3a406365d89e96 (diff)
downloaddjango-rest-framework-b07de86ad372a185c05c1dd77ccd7bee3801996e.tar.bz2
some properly failing tests, set up for standard permissions
-rw-r--r--rest_framework/permissions.py2
-rw-r--r--rest_framework/runtests/settings.py11
-rw-r--r--rest_framework/tests/test_permissions.py109
-rw-r--r--tox.ini8
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)
diff --git a/tox.ini b/tox.ini
index aa97fd35..6e3b8e0a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -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