diff options
Diffstat (limited to 'djangorestframework/permissions.py')
| -rw-r--r-- | djangorestframework/permissions.py | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/djangorestframework/permissions.py b/djangorestframework/permissions.py index aa4cd631..335a7213 100644 --- a/djangorestframework/permissions.py +++ b/djangorestframework/permissions.py @@ -20,6 +20,8 @@ __all__ = ( 'PerResourceThrottling' ) +SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS'] + _403_FORBIDDEN_RESPONSE = ImmediateResponse( {'detail': 'You do not have permission to access this resource. ' + @@ -84,8 +86,54 @@ class IsUserOrIsAnonReadOnly(BasePermission): def check_permission(self, user): if (not user.is_authenticated() and - self.view.method != 'GET' and - self.view.method != 'HEAD'): + self.view.method not in SAFE_METHODS): + raise _403_FORBIDDEN_RESPONSE + + +class DjangoModelPermissions(BasePermission): + """ + The request is authenticated using `django.contrib.auth` permissions. + See: https://docs.djangoproject.com/en/dev/topics/auth/#permissions + + It ensures that the user is authenticated, and has the appropriate + `add`/`change`/`delete` permissions on the model. + + This permission should only be used on views with a `ModelResource`. + """ + + # Map methods into required permission codes. + # Override this if you need to also provide 'read' permissions, + # or if you want to provide custom permission codes. + perms_map = { + 'GET': [], + 'OPTIONS': [], + 'HEAD': [], + 'POST': ['%(app_label)s.add_%(model_name)s'], + 'PUT': ['%(app_label)s.change_%(model_name)s'], + 'PATCH': ['%(app_label)s.change_%(model_name)s'], + 'DELETE': ['%(app_label)s.delete_%(model_name)s'], + } + + def get_required_permissions(self, method, model_cls): + """ + Given a model and an HTTP method, return the list of permission + codes that the user is required to have. + """ + kwargs = { + 'app_label': model_cls._meta.app_label, + 'model_name': model_cls._meta.module_name + } + try: + return [perm % kwargs for perm in self.perms_map[method]] + except KeyError: + ErrorResponse(status.HTTP_405_METHOD_NOT_ALLOWED) + + def check_permission(self, user): + method = self.view.method + model_cls = self.view.resource.model + perms = self.get_required_permissions(method, model_cls) + + if not user.is_authenticated or not user.has_perms(perms): raise _403_FORBIDDEN_RESPONSE |
