aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--rest_framework/mixins.py5
-rw-r--r--rest_framework/tests/permissions.py20
2 files changed, 25 insertions, 0 deletions
diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py
index 61ac225b..ce633112 100644
--- a/rest_framework/mixins.py
+++ b/rest_framework/mixins.py
@@ -9,6 +9,7 @@ from __future__ import unicode_literals
from django.http import Http404
from rest_framework import status
from rest_framework.response import Response
+from rest_framework.request import clone_request
class CreateModelMixin(object):
@@ -90,6 +91,10 @@ class UpdateModelMixin(object):
try:
self.object = self.get_object()
except Http404:
+ # If this is a PUT-as-create operation, we need to ensure that
+ # we have relevant permissions, as if this was a POST request.
+ if not self.has_permission(clone_request(request, 'POST')):
+ self.permission_denied(self.request)
created = True
success_status_code = status.HTTP_201_CREATED
else:
diff --git a/rest_framework/tests/permissions.py b/rest_framework/tests/permissions.py
index c04d2110..a7777b57 100644
--- a/rest_framework/tests/permissions.py
+++ b/rest_framework/tests/permissions.py
@@ -44,9 +44,14 @@ class ModelPermissionsIntegrationTests(TestCase):
Permission.objects.get(codename='change_basicmodel'),
Permission.objects.get(codename='delete_basicmodel')
]
+ user = User.objects.create_user('updateonly', 'updateonly@example.com', 'password')
+ user.user_permissions = [
+ Permission.objects.get(codename='change_basicmodel'),
+ ]
self.permitted_credentials = basic_auth_header('permitted', 'password')
self.disallowed_credentials = basic_auth_header('disallowed', 'password')
+ self.updateonly_credentials = basic_auth_header('updateonly', 'password')
BasicModel(text='foo').save()
@@ -87,3 +92,18 @@ class ModelPermissionsIntegrationTests(TestCase):
request = factory.delete('/1', HTTP_AUTHORIZATION=self.disallowed_credentials)
response = instance_view(request, pk=1)
self.assertEquals(response.status_code, status.HTTP_403_FORBIDDEN)
+
+ def test_has_put_as_create_permissions(self):
+ # User only has update permissions - should be able to update an entity.
+ request = factory.put('/1', json.dumps({'text': 'foobar'}),
+ content_type='application/json',
+ HTTP_AUTHORIZATION=self.updateonly_credentials)
+ response = instance_view(request, pk='1')
+ self.assertEquals(response.status_code, status.HTTP_200_OK)
+
+ # But if PUTing to a new entity, permission should be denied.
+ request = factory.put('/2', json.dumps({'text': 'foobar'}),
+ content_type='application/json',
+ HTTP_AUTHORIZATION=self.updateonly_credentials)
+ response = instance_view(request, pk='2')
+ self.assertEquals(response.status_code, status.HTTP_403_FORBIDDEN)