2011-05-19 21:36:30 +04:00
|
|
|
"""
|
2012-02-24 01:34:20 +04:00
|
|
|
The :mod:`permissions` module bundles a set of permission classes that are used
|
|
|
|
for checking if a request passes a certain set of constraints.
|
|
|
|
|
|
|
|
Permission behavior is provided by mixing the :class:`mixins.PermissionsMixin` class into a :class:`View` class.
|
2011-05-19 21:36:30 +04:00
|
|
|
"""
|
|
|
|
|
2011-05-10 13:49:28 +04:00
|
|
|
__all__ = (
|
|
|
|
'BasePermission',
|
|
|
|
'FullAnonAccess',
|
|
|
|
'IsAuthenticated',
|
|
|
|
'IsAdminUser',
|
|
|
|
'IsUserOrIsAnonReadOnly',
|
2011-06-14 13:31:18 +04:00
|
|
|
'PerUserThrottling',
|
|
|
|
'PerViewThrottling',
|
2011-05-10 13:49:28 +04:00
|
|
|
)
|
|
|
|
|
2012-02-11 22:43:58 +04:00
|
|
|
SAFE_METHODS = ['GET', 'HEAD', 'OPTIONS']
|
|
|
|
|
2011-05-10 13:49:28 +04:00
|
|
|
|
2011-04-27 21:08:32 +04:00
|
|
|
class BasePermission(object):
|
2011-05-10 13:49:28 +04:00
|
|
|
"""
|
|
|
|
A base class from which all permission classes should inherit.
|
|
|
|
"""
|
2011-04-27 21:08:32 +04:00
|
|
|
def __init__(self, view):
|
2011-05-10 13:49:28 +04:00
|
|
|
"""
|
|
|
|
Permission classes are always passed the current view on creation.
|
|
|
|
"""
|
2011-04-27 21:08:32 +04:00
|
|
|
self.view = view
|
2011-12-09 16:35:42 +04:00
|
|
|
|
2012-09-05 00:58:35 +04:00
|
|
|
def check_permission(self, request, obj=None):
|
2011-05-10 13:49:28 +04:00
|
|
|
"""
|
2012-02-07 15:15:30 +04:00
|
|
|
Should simply return, or raise an :exc:`response.ImmediateResponse`.
|
2011-05-10 13:49:28 +04:00
|
|
|
"""
|
2012-09-05 00:58:35 +04:00
|
|
|
raise NotImplementedError(".check_permission() must be overridden.")
|
2011-05-10 13:49:28 +04:00
|
|
|
|
2011-05-04 12:21:17 +04:00
|
|
|
|
2011-04-27 21:08:32 +04:00
|
|
|
class IsAuthenticated(BasePermission):
|
2011-05-10 13:49:28 +04:00
|
|
|
"""
|
|
|
|
Allows access only to authenticated users.
|
|
|
|
"""
|
2011-04-27 21:08:32 +04:00
|
|
|
|
2012-09-05 00:58:35 +04:00
|
|
|
def check_permission(self, request, obj=None):
|
2012-09-05 16:04:07 +04:00
|
|
|
if request.user and request.user.is_authenticated():
|
2012-09-05 00:58:35 +04:00
|
|
|
return True
|
|
|
|
return False
|
2011-04-27 21:08:32 +04:00
|
|
|
|
2011-05-19 11:36:55 +04:00
|
|
|
|
2011-05-19 00:13:48 +04:00
|
|
|
class IsAdminUser(BasePermission):
|
2011-05-10 13:49:28 +04:00
|
|
|
"""
|
|
|
|
Allows access only to admin users.
|
|
|
|
"""
|
|
|
|
|
2012-09-05 00:58:35 +04:00
|
|
|
def check_permission(self, request, obj=None):
|
2012-09-06 16:49:15 +04:00
|
|
|
if request.user and request.user.is_staff:
|
2012-09-05 00:58:35 +04:00
|
|
|
return True
|
|
|
|
return False
|
2011-05-10 13:49:28 +04:00
|
|
|
|
|
|
|
|
2012-09-05 00:58:35 +04:00
|
|
|
class IsAuthenticatedOrReadOnly(BasePermission):
|
2011-05-10 13:49:28 +04:00
|
|
|
"""
|
|
|
|
The request is authenticated as a user, or is a read-only request.
|
|
|
|
"""
|
|
|
|
|
2012-09-05 00:58:35 +04:00
|
|
|
def check_permission(self, request, obj=None):
|
2012-09-05 16:04:07 +04:00
|
|
|
if (request.method in SAFE_METHODS or
|
|
|
|
request.user and
|
|
|
|
request.user.is_authenticated()):
|
2012-09-05 00:58:35 +04:00
|
|
|
return True
|
|
|
|
return False
|
2011-05-10 13:49:28 +04:00
|
|
|
|
2011-06-14 14:08:29 +04:00
|
|
|
|
2012-02-11 21:48:35 +04:00
|
|
|
class DjangoModelPermissions(BasePermission):
|
2012-02-11 04:49:28 +04:00
|
|
|
"""
|
2012-02-11 22:29:24 +04:00
|
|
|
The request is authenticated using `django.contrib.auth` permissions.
|
|
|
|
See: https://docs.djangoproject.com/en/dev/topics/auth/#permissions
|
2012-02-11 04:49:28 +04:00
|
|
|
|
2012-02-11 22:29:24 +04:00
|
|
|
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`.
|
2012-02-11 17:00:38 +04:00
|
|
|
"""
|
2012-02-11 04:54:28 +04:00
|
|
|
|
2012-02-11 17:00:38 +04:00
|
|
|
# Map methods into required permission codes.
|
2012-09-06 16:49:15 +04:00
|
|
|
# Override this if you need to also provide 'view' permissions,
|
2012-02-12 01:15:06 +04:00
|
|
|
# or if you want to provide custom permission codes.
|
2012-02-11 17:00:38 +04:00
|
|
|
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,
|
2012-02-11 22:29:24 +04:00
|
|
|
'model_name': model_cls._meta.module_name
|
2012-02-11 04:49:28 +04:00
|
|
|
}
|
2012-08-25 16:43:28 +04:00
|
|
|
return [perm % kwargs for perm in self.perms_map[method]]
|
2012-02-11 04:49:28 +04:00
|
|
|
|
2012-09-05 00:58:35 +04:00
|
|
|
def check_permission(self, request, obj=None):
|
|
|
|
model_cls = self.view.model
|
|
|
|
perms = self.get_required_permissions(request.method, model_cls)
|
2011-06-11 22:34:54 +04:00
|
|
|
|
2012-09-05 16:04:07 +04:00
|
|
|
if (request.user and
|
|
|
|
request.user.is_authenticated() and
|
|
|
|
request.user.has_perms(perms, obj)):
|
2012-09-05 00:58:35 +04:00
|
|
|
return True
|
|
|
|
return False
|