示例#1
0
 def dumps(self, obj):
     try:
         encoder = import_string(settings.MODERNRPC_JSON_ENCODER)
         return json.dumps(obj, cls=encoder)
     except Exception as e:
         raise RPCInternalError(
             'Unable to serialize result as valid JSON: ' + str(e))
示例#2
0
    def process_request(self):

        encoding = self.request.encoding or 'utf-8'
        payload = self.loads(self.request.body.decode(encoding))

        if isinstance(payload, dict):

            # Store current request id, or None if request is a notification
            self.request_id = payload.get('id')
            return self.process_single_request(payload)

        elif isinstance(payload, (list, tuple)):

            batch_result = JSONRPCBatchResult()

            for single_payload in payload:
                try:
                    try:
                        request_id = single_payload.get('id')

                    except AttributeError:
                        request_id = None
                        raise RPCInvalidRequest(
                            'Single RPC call payload must be a struct')

                    result = self.process_single_request(single_payload)

                    # As stated in documentation:
                    # "A Response object SHOULD exist for each Request object, except that there SHOULD NOT be any
                    # Response objects for notifications."
                    if request_id:
                        batch_result.results.append(
                            self.json_success_response(result,
                                                       override_id=request_id))
                except AuthenticationFailed as e:
                    raise e

                except RPCException as e:
                    logger.warning(
                        'RPC Exception raised in a JSON-RPC batch handling: {}'
                        .format(e),
                        exc_info=settings.MODERNRPC_LOG_EXCEPTIONS)
                    batch_result.results.append(
                        self.json_error_response(e, override_id=request_id))

                except Exception as e:
                    logger.warning(
                        'Exception raised in a JSON-RPC batch handling: {}'.
                        format(e),
                        exc_info=settings.MODERNRPC_LOG_EXCEPTIONS)
                    rpc_exception = RPCInternalError(str(e))
                    batch_result.results.append(
                        self.json_error_response(rpc_exception,
                                                 override_id=request_id))

            return batch_result

        else:
            raise RPCInvalidRequest('Bad JSON-RPC payload: {}'.format(
                str(payload)))
示例#3
0
    def post(self, request, *args, **kwargs):
        """
        Handle a XML-RPC or JSON-RPC request.

        :param request: Incoming request
        :param args: Additional arguments
        :param kwargs: Additional named arguments
        :return: A HttpResponse containing XML-RPC or JSON-RPC response, depending on the incoming request
        """

        logger.debug('RPC request received...')

        for handler_cls in self.get_handler_classes():

            handler = handler_cls(request, self.entry_point)

            try:
                if not handler.can_handle():
                    continue

                logger.debug('Request will be handled by {}'.format(
                    handler_cls.__name__))

                result = handler.process_request()

                return handler.result_success(result)

            except AuthenticationFailed as e:
                # Customize HttpResponse instance used when AuthenticationFailed was raised
                logger.warning(e)
                return handler.result_error(e, HttpResponseForbidden)

            except RPCException as e:
                logger.warning('RPC exception: {}'.format(e),
                               exc_info=settings.MODERNRPC_LOG_EXCEPTIONS)
                return handler.result_error(e)

            except Exception as e:
                logger.error(
                    'Exception raised from a RPC method: "{}"'.format(e),
                    exc_info=settings.MODERNRPC_LOG_EXCEPTIONS)
                return handler.result_error(RPCInternalError(str(e)))

        logger.error('Unable to handle incoming request.')

        return HttpResponse(
            'Unable to handle your request. Please ensure you called the right entry point. If not, '
            'this could be a server error.')
示例#4
0
    def process_request(self):

        encoding = self.request.encoding or 'utf-8'
        payload = self.loads(self.request.body.decode(encoding))

        if isinstance(payload, dict):

            # Store current request id, or None if request is a notification
            self.request_id = payload.get('id')
            return self.process_single_request(payload)

        elif isinstance(payload, (list, tuple)):

            batch_result = JSONRPCBatchResult()

            for single_payload in payload:
                try:
                    try:
                        request_id = single_payload.get('id')

                    except AttributeError:
                        request_id = None
                        raise RPCInvalidRequest()

                    result = self.process_single_request(single_payload)

                    if request_id:
                        # As stated in documentation:
                        # "A Response object SHOULD exist for each Request object, except that there SHOULD NOT be any
                        # Response objects for notifications."
                        batch_result.results.append(
                            self.json_success_response(result,
                                                       override_id=request_id))

                except RPCException as e:
                    batch_result.results.append(
                        self.json_error_response(e, override_id=request_id))

                except Exception as e:
                    rpc_exception = RPCInternalError(str(e))
                    batch_result.results.append(
                        self.json_error_response(rpc_exception,
                                                 override_id=request_id))

            return batch_result

        else:
            raise RPCInvalidRequest()
示例#5
0
def login_custom(username, password, **kwargs):

    user = authenticate(username=username, password=password)

    request = kwargs.get(REQUEST_KEY)

    if user is None:
        raise RPCInternalError('Incorrect username or password.')

    login(request, user)

    if not request.session.exists(request.session.session_key):
        request.session.create()

    result = {"session": request.session.session_key}

    return result
示例#6
0
    def dumps(self, obj):

        try:
            # Marshaller has a specific handling of Fault instance. It is given without modification
            if isinstance(obj, xmlrpc_client.Fault):
                return self.marshaller.dumps(obj)

            # xmlrpc_client.Marshaller expects a list of objects to dumps.
            # It will output a '<params></params>' block and loops onto given objects to inject, for each one,
            # a '<param><value><type>X</type></value></param>' block.
            # This is not the return defined in XML-RPC standard, see http://xmlrpc.scripting.com/spec.html:
            # "The body of the response is a single XML structure, a <methodResponse>, which can contain
            # a single <params> which contains a single <param> which contains a single <value>."
            #
            # So, to make sure the return value always contain a single '<param><value><type>X</type></value></param>',
            # we dumps it as an array of a single value.
            return self.marshaller.dumps([obj])

        except Exception:
            raise RPCInternalError('Unable to serialize result as valid XML')