0

I'm using Django 2.2 with djangorestframework-3.9.2 and djangorestframework_simplejwt-4.1.3. Using the admin interface I've defined some users as super users, and some with limited permissions to only view a few endpoints. However, when I log in with the limited user, the user can view everything, and it can even edit and delete entries everywhere. The user is required to log in to access the api, but once authenticated the individual permissions don't seem to work.

In my settings I have the following:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
        'rest_framework.permissions.DjangoModelPermissions',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
    ),
}

Is there anything else I explicitly have to set to block access to views? An example of how my views are defined follows:

class CustomersViewSet(viewsets.ModelViewSet):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

along with the serializer and model:

class CustomerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Customer
        fields = '__all__'


class Customer(models.Model):
    identifier = models.CharField(max_length=255, unique=True)
    entryDate = models.DateTimeField(default=timezone.now, blank=True)
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        null=True,
        blank=True
    )

    def save(self, *args, **kwargs):
        user = get_request().user
        self.user = user
        super(Customer, self).save(*args, **kwargs)

    def __str__(self):
        return self.identifier

Finally, the views are added in urls.py:

router.register('api/customers', CustomersViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls)),
    path('api/', include('rest_framework.urls', namespace='rest_framework')),
]
Simen Russnes
  • 2,002
  • 2
  • 26
  • 56

1 Answers1

0

The issue is that you have configured the following global permissions:

'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated',
    'rest_framework.permissions.DjangoModelPermissions',
)

In addition, your CustomersViewSet class does not specify any more restrictive permission classes (i.e. permission_classes not specified). Using rest_framework.permissions.IsAuthenticated as a global (and default) permission class then means that any API/view (including CustomersViewSet) are available and visible to any user who is authenticated (i.e. logged in) -- unless otherwise specified in the view class definition.

Perhaps the best option would be to write custom permission classes that, for each view, check to which group the user requesting the view belongs. You can find an excellent answer and example on how to write custom permission classes and how to attach them to a view here. You can find another example on how to implement this and perhaps closer to your question here.

m_____z
  • 1,521
  • 13
  • 22
  • Those answers show how to handle permissions on a more view to view basis, which I definitely want, however for simplicity I would also like to make use of the per model default permissions that I can assign in the django admin interface. I would imagine that including the DjangoModelPermissions as the only DEFAULT_PERMISSION_CLASSES, but with that setting all endpoint permissions are allowed for a user without any explicitly set permissions. – Simen Russnes Jan 15 '20 at 14:29