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.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 12dd7a63137535febd2afdd316ef7c1a3d961ed35994bcad4a90168f3a9b11b8 |
|
MD5 | c4a95c961537b245d5db7bcd2f1e239f |
|
BLAKE2b-256 | f8da8b8ea0e8b92f0ed8d9cf85537b3363070802bc2480b709df9640870d3c6a |
Hashes for rest_framework_roles-0.4.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8ea1b6827260c61a2b44dd309f64593f40c5060ca062c51a814b8a56f006bc50 |
|
MD5 | 5679d4a8f50cbbd216433d88ff21115a |
|
BLAKE2b-256 | 23d2fe7502538f5505a806ceedd44916dc1bff4264890fde15b9e36b31e42ed4 |