aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/permissions.py
diff options
context:
space:
mode:
authorbwreilly2013-09-07 23:18:52 -0500
committerbwreilly2013-09-07 23:18:52 -0500
commit118645e4806effaa35726012a983676b2c55b6dd (patch)
tree576c4192773862b29909422876be653292d04771 /rest_framework/permissions.py
parent57d6b5fb7c2652bb4c68edd1bcc95be736b06b31 (diff)
downloaddjango-rest-framework-118645e4806effaa35726012a983676b2c55b6dd.tar.bz2
first pass at object level permissions and tests
Diffstat (limited to 'rest_framework/permissions.py')
-rw-r--r--rest_framework/permissions.py46
1 files changed, 46 insertions, 0 deletions
diff --git a/rest_framework/permissions.py b/rest_framework/permissions.py
index b67be414..2d8a30e9 100644
--- a/rest_framework/permissions.py
+++ b/rest_framework/permissions.py
@@ -7,6 +7,7 @@ import warnings
SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']
+from django.http import Http404
from rest_framework.compat import oauth2_provider_scope, oauth2_constants, guardian
@@ -152,9 +153,54 @@ class DjangoModelPermissionsOrAnonReadOnly(DjangoModelPermissions):
class DjangoObjectLevelModelPermissions(DjangoModelPermissions):
+ """
+ Basic object level permissions utilizing django-guardian.
+ """
+
def __init__(self):
assert guardian, 'Using DjangoObjectLevelModelPermissions, but django-guardian is not installed'
+ action_perm_map = {
+ 'list': 'read',
+ 'retrieve': 'read',
+ 'create': 'add',
+ 'partial_update': 'change',
+ 'update': 'change',
+ 'destroy': 'delete',
+ }
+
+ def _get_names(self, view):
+ model_cls = getattr(view, 'model', None)
+ queryset = getattr(view, 'queryset', None)
+
+ if model_cls is None and queryset is not None:
+ model_cls = queryset.model
+ if not model_cls: # no model, no model based permissions
+ return None
+ model_name = model_cls._meta.module_name
+ return model_name
+
+ def has_permission(self, request, view):
+ if view.action == 'list':
+ user = request.user
+ queryset = view.get_queryset()
+ model_name = self._get_names(view)
+ view.queryset = guardian.shortcuts.get_objects_for_user(user, 'read_' + model_name, queryset) #TODO: move to filter
+ return super(DjangoObjectLevelModelPermissions, self).has_permission(request, view)
+
+ def has_object_permission(self, request, view, obj):
+ user = request.user
+ model_name = self._get_names(view)
+ action = self.action_perm_map.get(view.action)
+
+ assert action, "Tried to determine object permissions but no action specified in view"
+
+ perm = "{action}_{model_name}".format(action=action, model_name=model_name)
+ check = user.has_perm(perm, obj)
+ if not check:
+ raise Http404
+ return user.has_perm(perm, obj)
+
class TokenHasReadWriteScope(BasePermission):
"""