alorence / django-modern-rpc

Simple XML-RPC and JSON-RPC server for modern Django
http://django-modern-rpc.rtfd.io
MIT License
98 stars 17 forks source link

set_authentication_predicate bug #8

Closed aplicacionamedida closed 7 years ago

aplicacionamedida commented 7 years ago

If a user wants to use set_authentication_predicate as decorator, as explained in the tutorial:

https://django-modern-rpc.readthedocs.io/en/latest/advanced/authentication.html#basics

then that function should be like this:

def set_authentication_predicate(predicate, params=None):
    """
    Assign a new authentication predicate to an RPC method.
    This is the most generic decorator used to implement authentication.
    Predicate is a standard function with the following signature:
    .. code:: python
       def my_predicate(request, *params):
           # Inspect request and extract required information
           if <condition>:
               # The condition to execute the method are met
               return True
           return False
    :param predicate:
    :param params:
    :return:
    """

    def decorator(rpc_method):
        if hasattr(rpc_method, 'modernrpc_auth_predicates'):
            rpc_method.modernrpc_auth_predicates.append(predicate)
            rpc_method.modernrpc_auth_predicates_params.append(params)

        else:
            rpc_method.modernrpc_auth_predicates = [predicate]
            rpc_method.modernrpc_auth_predicates_params = [params]

        return rpc_method

    return  decorator
alorence commented 7 years ago

Hi miguel.

Thank you very much for the report. You're probably right, until now, set_auth_predicate has not been used to directky decorate rpc methods. It has only been used as wrapper to set http basic auth predicates.

I'm afk for the next few days, but I will fix this issue as soon as i'm back to work, on the beginning of the next week. In the meantime, if you want to make a pull request, i will be happy to merge it when i'll be back.

I will also push a new version whenbthis issue will be fixed.

aplicacionamedida commented 7 years ago

Hi Antoine, several parts are affected with this issue:

With my possible proposal also this method requires modification (the change is in the last line):

    def check_permissions(self, request):
        """Call the predicate(s) associated with the RPC method, to check if the current request
        can actually call the method.
        Return a boolean indicating if the method should be executed (True) or not (False)"""

        if not self.predicates:
            return True

        # All registered authentication predicates must return True
        return all(
            predicate(request, *self.predicates_params[i]) 
               if self.predicates_params[i] else predicate(request)
               for i, predicate in enumerate(self.predicates)
        )
aplicacionamedida commented 7 years ago

I am using this provisional workaround:

from modernrpc.auth import set_authentication_predicate as _set_authentication_predicate

def set_authentication_predicate(predicate, *params):
    def decorator(rpc_method):
        _set_authentication_predicate(rpc_method, predicate, params)
        return rpc_method

    return  decorator
alorence commented 7 years ago

Release 0.8.0 addressing this issue has just been published. Thanks again for your report !