Role-based permissions for Django REST Framework and vanilla Django.
Project description
REST Framework Roles
Role-based permissions for Django and Django REST Framework (functions or classes).
- Decouple permissions from views and models.
- Easy declarative configuration (still allowing complex scenarios).
- View redirection works out-of-the-box.
- Gradual integration with existing projects.
Install
Install
pip install rest-framework-roles
settings.py
INSTALLED_APPS = {
..
'rest_framework',
'rest_framework_roles', # Must be after rest_framework
}
REST_FRAMEWORK_ROLES = {
'roles': 'myproject.roles.ROLES',
}
REST_FRAMEWORK = {
..
'permission_classes': [], # This ensures that by default noone is allowed access
..
}
Usage
First you need to define some roles. Below we use the ones already working with Django out-of-the-box.
roles.py
from rest_framework_roles.roles import is_user, is_anon, is_admin
ROLES = {
'admin': is_admin,
'user': is_user,
'anon': is_anon,
}
is_admin
, is_user
and is_anon
are simple functions that take request
and view
as arguments and return a boolean - denoting if a user request matches a role.
We now need to define when permission should be granted for a matching role.
views.py
from rest_framework.viewsets import ModelViewSet
from rest_framework_roles.granting import is_self
class UserViewSet(ModelViewSet):
serializer_class = UserSerializer
queryset = User.objects.all()
view_permissions = {
'retrieve': {'user': is_self, 'admin': True},
'create': {'anon': True},
'list': {'admin': True},
}
@allowed('admin', 'user')
@action(detail=False, methods=['get'])
def me(self, request):
self.kwargs['pk'] = request.user.pk
return self.retrieve(request)
In this example only anonymous users can create a new user account. Admin can retrieve any user's acount and list users. Users can only retrieve their own information.
You can use any of @allowed, @disallowed or view_permissions to specify permissions.
How it works
The library is using a permission table internally but at a high level the behaviour is outlined below
- First roles are checked in order of cost (as set by
@role_checker
) - A matching role is further checked to see if permission is granted.
- Truthful booleans and functions will grant permission.
- In case of a collection (e.g.
@anyof
), the grant checkers are evaluated in order. If truthful, permission is granted. - In case of not a truthful result, we fallback to the framework permissions. For REST Framework
that is
permission_classes
.
Note in the snippet below, admin is a user so he would match both roles. However the first rule will not grant permission, while the second will.
view_permissions = {
'retrieve': {'user': is_self, 'admin': True},
}
For more complex scenarios you can specify multiple functions to be checked when determining if permission should be granted.
from rest_framework_roles.granting import allof
def not_updating_email(request, view):
return 'email' not in request.data
class UserViewSet(ModelViewSet):
view_permissions = {
'update': {
'user': allof(is_self, not_updating_email),
'admin': True,
},
}
..
In this case the user can only update their information as long as they don't update their email.
Role checking order
Roles are checked in order of cost.
from rest_framework_roles.decorators import role_checker
@role_checker(cost=0)
def is_freebie_user(request, view):
return request.user.is_authenticated and request.user.plan == 'freebie'
@role_checker(cost=0)
def is_payed_user(request, view):
return request.user.is_authenticated and not request.user.plan
@role_checker(cost=50)
def is_creator(request, view):
obj = view.get_object()
if hasattr(obj, 'creator'):
return request.user == obj.creator
return False
In this example, roles with cost 0 would be checked first, and lastly the creator role would be checked.
Note this is similar to Django REST's
check_permissions
andcheck_object_permissions
but with much more room for refinement since you can have arbitrary number of costs.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for rest_framework_roles-0.4.1.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | ef153bb62d66c545cf4b3c6a404a80d0e772cab4fccc6c7827c9c7416b59db0c |
|
MD5 | 77b69426866f9f8d54571667ef7da3f6 |
|
BLAKE2b-256 | 6632bec1a84ff635a11243cd603072cdb1d7fcc54b0cf3b733654b8ec45c702a |
Hashes for rest_framework_roles-0.4.1-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 83afe2d0863b54a7b3b13fc64014a20640830d507565fac0dabd1023d0e5bf13 |
|
MD5 | 226c8185d519e7ef90c767b56f342c61 |
|
BLAKE2b-256 | b6028109cda2d5bbda72aae545fca7ceff358cd22582e412e7ed8dae75fe175a |