diff options
| author | bwreilly | 2013-09-07 23:18:52 -0500 |
|---|---|---|
| committer | bwreilly | 2013-09-07 23:18:52 -0500 |
| commit | 118645e4806effaa35726012a983676b2c55b6dd (patch) | |
| tree | 576c4192773862b29909422876be653292d04771 /rest_framework/permissions.py | |
| parent | 57d6b5fb7c2652bb4c68edd1bcc95be736b06b31 (diff) | |
| download | django-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.py | 46 |
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): """ |
