Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django rest model permissions

I'm using Django 2.1 and djangorestframework 3.9.2. I wish to be able to control access to REST operations on Django model objects via the Django admin interface, ideally using user permissions. For example, only users who have read permissions on model object Foo should be able to see Foo in my REST API.

I read the docs and it seems maybe I could use DjangoModelPermissions or DjangoObjectPermissions.

However, when I clear all user permissions in the DB, and set DEFAULT_PERMISSIONS_CLASS to either DjangoModelPermissions or DjangoObjectPermissions, I am still able to see things in the REST API. That means lack of permissions is not preventing me from seeing objects as I hoped.

Example settings:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.DjangoModelPermissions',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
}

An example object view:

from rest_framework import routers, serializers, viewsets
from .models import Example

class ExampleSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Example
        fields = '__all__'

class ExampleViewSet(viewsets.ModelViewSet):
    queryset = Example.objects.all()
    serializer_class = ExampleSerializer

router = routers.DefaultRouter()
router.register(r'examples', ExampleViewSet)

Suggestions?

like image 751
dfrankow Avatar asked Jan 27 '23 12:01

dfrankow


1 Answers

DjangoModelPermissions only enforce permission rules for data modification (for POST , PUT , PATCH and DELETE requests), but does not enforce permission rules for data viewing.

To restrict data viewing, you can add a custom view permisson, and subclass DjangoModelPermissions to use that permission, as explained in the docs

EDIT:

With Django 2.1, view model permission is added. So this will probably be supported by DjangoModelPermissions in the future releases, but until then, you can try subclassing DjangoModelPermissions like this to add check for view permissions:

class DjangoModelPermissionsWithRead(DjangoModelPermissions):
    perms_map = {
        'GET': ['%(app_label)s.view_%(model_name)s'],
        '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'],
    }

EDIT 2: There is a feature request filed to support this.

like image 108
Ozgur Akcali Avatar answered Jan 31 '23 08:01

Ozgur Akcali