Enforce PUT-as-create permissions

This commit is contained in:
Tom Christie 2013-02-10 16:50:46 +00:00
parent 84a1896b7d
commit 29136ef2c6
2 changed files with 25 additions and 0 deletions

View File

@ -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:

View File

@ -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)