aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
authorTom Christie2013-02-11 12:47:56 +0000
committerTom Christie2013-02-12 08:58:28 +0000
commit09b01887f234be55c14943028330f569823b2369 (patch)
tree6457258308dbc63a24c7a4f16b544999adc6c2b3 /rest_framework
parentaa03425c09c2eb4fc0a24276de92a320af09c33e (diff)
downloaddjango-rest-framework-09b01887f234be55c14943028330f569823b2369.tar.bz2
New style object-level permission checks
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/generics.py2
-rw-r--r--rest_framework/permissions.py27
-rw-r--r--rest_framework/renderers.py2
-rw-r--r--rest_framework/tests/permissions.py4
-rw-r--r--rest_framework/tests/renderers.py2
-rw-r--r--rest_framework/views.py18
6 files changed, 41 insertions, 14 deletions
diff --git a/rest_framework/generics.py b/rest_framework/generics.py
index 5abb915b..19dca7e6 100644
--- a/rest_framework/generics.py
+++ b/rest_framework/generics.py
@@ -131,7 +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_permission(self.request, obj):
+ if not self.has_object_permission(self.request, obj):
self.permission_denied(self.request)
return obj
diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py
index c9bbf4c4..306f00ca 100644
--- a/rest_framework/permissions.py
+++ b/rest_framework/permissions.py
@@ -2,6 +2,8 @@
Provides a set of pluggable permission policies.
"""
from __future__ import unicode_literals
+import inspect
+import warnings
SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']
@@ -11,11 +13,22 @@ class BasePermission(object):
A base class from which all permission classes should inherit.
"""
- def has_permission(self, request, view, obj=None):
+ def has_permission(self, request, view):
"""
Return `True` if permission is granted, `False` otherwise.
"""
- raise NotImplementedError(".has_permission() must be overridden.")
+ return True
+
+ def has_object_permission(self, request, view, obj):
+ """
+ Return `True` if permission is granted, `False` otherwise.
+ """
+ if len(inspect.getargspec(self.has_permission)[0]) == 4:
+ 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_permission(request, view, obj)
+ return True
class AllowAny(BasePermission):
@@ -25,7 +38,7 @@ class AllowAny(BasePermission):
permission_classes list, but it's useful because it makes the intention
more explicit.
"""
- def has_permission(self, request, view, obj=None):
+ def has_permission(self, request, view):
return True
@@ -34,7 +47,7 @@ class IsAuthenticated(BasePermission):
Allows access only to authenticated users.
"""
- def has_permission(self, request, view, obj=None):
+ def has_permission(self, request, view):
if request.user and request.user.is_authenticated():
return True
return False
@@ -45,7 +58,7 @@ class IsAdminUser(BasePermission):
Allows access only to admin users.
"""
- def has_permission(self, request, view, obj=None):
+ def has_permission(self, request, view):
if request.user and request.user.is_staff:
return True
return False
@@ -56,7 +69,7 @@ class IsAuthenticatedOrReadOnly(BasePermission):
The request is authenticated as a user, or is a read-only request.
"""
- def has_permission(self, request, view, obj=None):
+ def has_permission(self, request, view):
if (request.method in SAFE_METHODS or
request.user and
request.user.is_authenticated()):
@@ -100,7 +113,7 @@ class DjangoModelPermissions(BasePermission):
}
return [perm % kwargs for perm in self.perms_map[method]]
- def has_permission(self, request, view, obj=None):
+ def has_permission(self, request, view):
model_cls = getattr(view, 'model', None)
if not model_cls:
return True
diff --git a/rest_framework/renderers.py b/rest_framework/renderers.py
index 960d4849..e7df8758 100644
--- a/rest_framework/renderers.py
+++ b/rest_framework/renderers.py
@@ -301,7 +301,7 @@ class BrowsableAPIRenderer(BaseRenderer):
request = clone_request(request, method)
try:
- if not view.has_permission(request, obj):
+ if not view.has_permission(request):
return # Don't have permission
except Exception:
return # Don't have permission and exception explicitly raise
diff --git a/rest_framework/tests/permissions.py b/rest_framework/tests/permissions.py
index 26a34319..b8e1d89c 100644
--- a/rest_framework/tests/permissions.py
+++ b/rest_framework/tests/permissions.py
@@ -115,9 +115,7 @@ class OwnerModel(models.Model):
class IsOwnerPermission(permissions.BasePermission):
- def has_permission(self, request, view, obj=None):
- if not obj:
- return True
+ def has_object_permission(self, request, view, obj):
return request.user == obj.owner
diff --git a/rest_framework/tests/renderers.py b/rest_framework/tests/renderers.py
index 72405336..e3f45ce6 100644
--- a/rest_framework/tests/renderers.py
+++ b/rest_framework/tests/renderers.py
@@ -95,7 +95,7 @@ urlpatterns = patterns('',
class POSTDeniedPermission(permissions.BasePermission):
- def has_permission(self, request, view, obj=None):
+ def has_permission(self, request, view):
return request.method != 'POST'
diff --git a/rest_framework/views.py b/rest_framework/views.py
index fd6b4313..dd8889ae 100644
--- a/rest_framework/views.py
+++ b/rest_framework/views.py
@@ -13,6 +13,7 @@ from rest_framework.response import Response
from rest_framework.request import Request
from rest_framework.settings import api_settings
import re
+import warnings
def _remove_trailing_string(content, trailing):
@@ -261,8 +262,23 @@ class APIView(View):
"""
Return `True` if the request should be 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
+
+ def has_object_permission(self, request, obj):
+ """
+ Return `True` if the request should be permitted for a given object.
+ """
for permission in self.get_permissions():
- if not permission.has_permission(request, self, obj):
+ if not permission.has_object_permission(request, self, obj):
return False
return True