def __init__(self): SimpleXMLRPCDispatcher.__init__(self, allow_none=False, encoding=None) XMLRPCDocGenerator.__init__(self) def _dumps(obj, *args, **kwargs): kwargs['allow_none'] = self.allow_none kwargs['encoding'] = self.encoding return xmlrpc_client.dumps(obj, *args, **kwargs) self.dumps = _dumps # map of name => (auth, func) self.func_map = {} self.threadlocal = ThreadLocalRequestMiddleware()
def __init__(self): SimpleXMLRPCDispatcher.__init__(self, allow_none=False, encoding=None) XMLRPCDocGenerator.__init__(self) def _dumps(obj, *args, **kwargs): kwargs['allow_none'] = self.allow_none kwargs['encoding'] = self.encoding return xmlrpc_client.dumps(obj, *args, **kwargs) self.dumps = _dumps # map of name => (auth, func) self.func_map = {} self.threadlocal = ThreadLocalRequestMiddleware()
class PatchworkXMLRPCDispatcher(SimpleXMLRPCDispatcher, XMLRPCDocGenerator): server_name = 'Patchwork XML-RPC API' server_title = 'Patchwork XML-RPC API v1 Documentation' def __init__(self): SimpleXMLRPCDispatcher.__init__(self, allow_none=False, encoding=None) XMLRPCDocGenerator.__init__(self) def _dumps(obj, *args, **kwargs): kwargs['allow_none'] = self.allow_none kwargs['encoding'] = self.encoding return xmlrpc_client.dumps(obj, *args, **kwargs) self.dumps = _dumps # map of name => (auth, func) self.func_map = {} self.threadlocal = ThreadLocalRequestMiddleware() def register_function(self, fn, auth_required): self.funcs[fn.__name__] = fn # needed by superclass methods self.func_map[fn.__name__] = (auth_required, fn) def _user_for_request(self, request): auth_header = None if 'HTTP_AUTHORIZATION' in request.META: auth_header = request.META.get('HTTP_AUTHORIZATION') elif 'Authorization' in request.META: auth_header = request.META.get('Authorization') if auth_header is None or auth_header == '': raise Exception('No authentication credentials given') header = auth_header.strip() if not header.startswith('Basic '): raise Exception('Authentication scheme not supported') header = header[len('Basic '):].strip() try: decoded = base64.decodestring(header) username, password = decoded.split(':', 1) except: raise Exception('Invalid authentication credentials') return authenticate(username=username, password=password) def _dispatch(self, request, method, params): if method not in list(self.func_map.keys()): raise Exception('method "%s" is not supported' % method) auth_required, fn = self.func_map[method] if auth_required: user = self._user_for_request(request) if not user: raise Exception('Invalid username/password') request.user = user self.threadlocal.process_request(request) params = (user,) + params return fn(*params) def _marshaled_dispatch(self, request): try: params, method = six.moves.xmlrpc_client.loads(request.body) response = self._dispatch(request, method, params) # wrap response in a singleton tuple response = (response,) response = self.dumps(response, methodresponse=1) except six.moves.xmlrpc_client.Fault as fault: response = self.dumps(fault) except: # report exception back to server response = self.dumps( six.moves.xmlrpc_client.Fault(1, '%s:%s' % (sys.exc_info()[0], sys.exc_info()[1])), ) return response