aboutsummaryrefslogtreecommitdiffstats
path: root/djangorestframework/permissions.py
diff options
context:
space:
mode:
Diffstat (limited to 'djangorestframework/permissions.py')
-rw-r--r--djangorestframework/permissions.py52
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