mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 17:47:04 +03:00
Tidy up internal view permission checking logic.
Also document correctly - these methods are now public and will fall under the deprecation policy from now on.
This commit is contained in:
parent
09b01887f2
commit
f5a0275547
|
@ -150,7 +150,7 @@ As well as global permissions, that are run against all incoming requests, you c
|
|||
# Instance must have an attribute named `owner`.
|
||||
return obj.owner == request.user
|
||||
|
||||
Note that the generic views will check the appropriate object level permissions, but if you're writing your own custom views, you'll need to make sure you check the object level permission checks yourself, by calling `self.has_object_permission(request, obj)` from the view.
|
||||
Note that the generic views will check the appropriate object level permissions, but if you're writing your own custom views, you'll need to make sure you check the object level permission checks yourself. You can do so by calling `self.check_object_permissions(request, obj)` from the view once you have the object instance. This call will raise an appropriate `APIException` if any object-level permission checks fail, and will otherwise simply return.
|
||||
|
||||
[cite]: https://developer.apple.com/library/mac/#documentation/security/Conceptual/AuthenticationAndAuthorizationGuide/Authorization/Authorization.html
|
||||
[authentication]: authentication.md
|
||||
|
|
|
@ -76,11 +76,11 @@ The following methods are used by REST framework to instantiate the various plug
|
|||
|
||||
The following methods are called before dispatching to the handler method.
|
||||
|
||||
### .check_permissions(...)
|
||||
### .check_permissions(self, request)
|
||||
|
||||
### .check_throttles(...)
|
||||
### .check_throttles(self, request)
|
||||
|
||||
### .perform_content_negotiation(...)
|
||||
### .perform_content_negotiation(self, request, force=False)
|
||||
|
||||
## Dispatch methods
|
||||
|
||||
|
|
|
@ -131,8 +131,7 @@ class SingleObjectAPIView(SingleObjectMixin, GenericAPIView):
|
|||
Override default to add support for object-level permissions.
|
||||
"""
|
||||
obj = super(SingleObjectAPIView, self).get_object(queryset)
|
||||
if not self.has_object_permission(self.request, obj):
|
||||
self.permission_denied(self.request)
|
||||
self.check_object_permissions(self.request, obj)
|
||||
return obj
|
||||
|
||||
|
||||
|
|
|
@ -93,8 +93,7 @@ class UpdateModelMixin(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)
|
||||
self.check_permissions(clone_request(request, 'POST'))
|
||||
created = True
|
||||
success_status_code = status.HTTP_201_CREATED
|
||||
else:
|
||||
|
|
|
@ -21,8 +21,7 @@ from rest_framework.request import clone_request
|
|||
from rest_framework.utils import dict2xml
|
||||
from rest_framework.utils import encoders
|
||||
from rest_framework.utils.breadcrumbs import get_breadcrumbs
|
||||
from rest_framework import VERSION, status
|
||||
from rest_framework import parsers
|
||||
from rest_framework import exceptions, parsers, status, VERSION
|
||||
|
||||
|
||||
class BaseRenderer(object):
|
||||
|
@ -299,12 +298,10 @@ class BrowsableAPIRenderer(BaseRenderer):
|
|||
if not api_settings.FORM_METHOD_OVERRIDE:
|
||||
return # Cannot use form overloading
|
||||
|
||||
request = clone_request(request, method)
|
||||
try:
|
||||
if not view.has_permission(request):
|
||||
return # Don't have permission
|
||||
except Exception:
|
||||
return # Don't have permission and exception explicitly raise
|
||||
view.check_permissions(clone_request(request, method))
|
||||
except exceptions.APIException:
|
||||
return False # Doesn't have permissions
|
||||
return True
|
||||
|
||||
def serializer_to_form_fields(self, serializer):
|
||||
|
|
|
@ -258,33 +258,28 @@ class APIView(View):
|
|||
return (renderers[0], renderers[0].media_type)
|
||||
raise
|
||||
|
||||
def has_permission(self, request, obj=None):
|
||||
def check_permissions(self, request):
|
||||
"""
|
||||
Return `True` if the request should be permitted.
|
||||
Check if the request should be permitted.
|
||||
Raises an appropriate exception if the request is not permitted.
|
||||
"""
|
||||
if obj is not None:
|
||||
warnings.warn('The `obj` argument in `has_permission` is due to be deprecated. '
|
||||
'Use `has_object_permission()` instead for object permissions.',
|
||||
PendingDeprecationWarning, stacklevel=2)
|
||||
return self.has_object_permission(request, obj)
|
||||
|
||||
for permission in self.get_permissions():
|
||||
if not permission.has_permission(request, self):
|
||||
return False
|
||||
return True
|
||||
self.permission_denied(request)
|
||||
|
||||
def has_object_permission(self, request, obj):
|
||||
def check_object_permissions(self, request, obj):
|
||||
"""
|
||||
Return `True` if the request should be permitted for a given object.
|
||||
Check if the request should be permitted for a given object.
|
||||
Raises an appropriate exception if the request is not permitted.
|
||||
"""
|
||||
for permission in self.get_permissions():
|
||||
if not permission.has_object_permission(request, self, obj):
|
||||
return False
|
||||
return True
|
||||
self.permission_denied(request)
|
||||
|
||||
def check_throttles(self, request):
|
||||
"""
|
||||
Check if request should be throttled.
|
||||
Raises an appropriate exception if the request is throttled.
|
||||
"""
|
||||
for throttle in self.get_throttles():
|
||||
if not throttle.allow_request(request, self):
|
||||
|
@ -311,8 +306,7 @@ class APIView(View):
|
|||
self.format_kwarg = self.get_format_suffix(**kwargs)
|
||||
|
||||
# Ensure that the incoming request is permitted
|
||||
if not self.has_permission(request):
|
||||
self.permission_denied(request)
|
||||
self.check_permissions(request)
|
||||
self.check_throttles(request)
|
||||
|
||||
# Perform content negotiation and store the accepted info on the request
|
||||
|
|
Loading…
Reference in New Issue
Block a user