caxap / rest_condition

Complex permissions flow for django-rest-framework (http://django-rest-framework.org).
MIT License
280 stars 29 forks source link

Add a custom Boolean type in order to be able to provide custom descriptive message along the error code #6

Open barseghyanartur opened 8 years ago

barseghyanartur commented 8 years ago

Add a custom Boolean type in order to be able to provide custom descriptive message along the error status.

In that case, the following would be possible.

from rest_framework.permissions import BasePermission
from rest_framework.viewsets import GenericViewSet, ModelViewSet, ViewSet
from rest_condition.mixins import UpdatedPermissionChecksMixin
from rest_condition.types import Boolean

class MyPermission1(BasePermission):
    """
    """
    def has_permission(self, request, view):
        if some_condition: # In some conditions, provide a custom error message
            return Boolean(False, "My custom message why")

class MyPermission2(BasePermission):
    """
    """
    # Some code here

class MyModelViewSet(UpdatedPermissionChecksMixin, ModelViewSet):
    """
    """
    permission_classes = [
        Or (
           MyPermission1,
           MyPermission2
        )
    ]

It would also work with GenericViewSet or ViewSet:

class MyGenericViewSet(UpdatedPermissionChecksMixin, GenericViewSet):
    """
    """
    # Some code here

class MyViewSet(UpdatedPermissionChecksMixin, ViewSet):
    """
    """
    # Some code here
caxap commented 7 years ago

I think it is very specific case and this logic should be implemented at application level.

barseghyanartur commented 7 years ago

@caxap:

That's what we did. Still very useful. If you're not interested, feel free to close this. I have no objections.

virtualbrown commented 6 years ago

DRF has a built-in way of providing custom error messages. However, these error messages are currently ignored by 'rest_condition' classes.

In DRF, you can specify a message class level attribute that then gets used as the error message if the permission check fails.


http://www.django-rest-framework.org/api-guide/permissions/#custom-permissions

from rest_framework import permissions

class CustomerAccessPermission(permissions.BasePermission): message = 'Adding customers not allowed.'

def has_permission(self, request, view):
     ...

It seems evaluate_permissions(....) in permissions.py could be enhanced to read the message attribute from the condition instance and set its own message attribute to that.

e.g. permissions.py : evaluate_permissions(....)

...

if reduced_result is not _NONE:

        # read the error message from the custom permissions class and set it here so DRF
        # can pick it up.
        if hasattr(condition.__class__, 'message'):
            Condition.message = condition.__class__.message

        return not reduced_result if self.negated else reduced_result