mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-13 05:06:53 +03:00
Enforce PUT-as-create permissions
This commit is contained in:
parent
84a1896b7d
commit
29136ef2c6
|
@ -9,6 +9,7 @@ from __future__ import unicode_literals
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.request import clone_request
|
||||||
|
|
||||||
|
|
||||||
class CreateModelMixin(object):
|
class CreateModelMixin(object):
|
||||||
|
@ -90,6 +91,10 @@ class UpdateModelMixin(object):
|
||||||
try:
|
try:
|
||||||
self.object = self.get_object()
|
self.object = self.get_object()
|
||||||
except Http404:
|
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
|
created = True
|
||||||
success_status_code = status.HTTP_201_CREATED
|
success_status_code = status.HTTP_201_CREATED
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -44,9 +44,14 @@ class ModelPermissionsIntegrationTests(TestCase):
|
||||||
Permission.objects.get(codename='change_basicmodel'),
|
Permission.objects.get(codename='change_basicmodel'),
|
||||||
Permission.objects.get(codename='delete_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.permitted_credentials = basic_auth_header('permitted', 'password')
|
||||||
self.disallowed_credentials = basic_auth_header('disallowed', 'password')
|
self.disallowed_credentials = basic_auth_header('disallowed', 'password')
|
||||||
|
self.updateonly_credentials = basic_auth_header('updateonly', 'password')
|
||||||
|
|
||||||
BasicModel(text='foo').save()
|
BasicModel(text='foo').save()
|
||||||
|
|
||||||
|
@ -87,3 +92,18 @@ class ModelPermissionsIntegrationTests(TestCase):
|
||||||
request = factory.delete('/1', HTTP_AUTHORIZATION=self.disallowed_credentials)
|
request = factory.delete('/1', HTTP_AUTHORIZATION=self.disallowed_credentials)
|
||||||
response = instance_view(request, pk=1)
|
response = instance_view(request, pk=1)
|
||||||
self.assertEquals(response.status_code, status.HTTP_403_FORBIDDEN)
|
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)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user