From e04239de55204b5380158d100a18d42521c4670c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez?= Date: Mon, 23 Jul 2012 15:59:13 +0000 Subject: [PATCH] Added request object to xmlrpc methods that needs credentials --- server/src/uds/xmlrpc/auths/AdminAuth.py | 15 +++++--- server/src/uds/xmlrpc/views.py | 44 +++++++++++++++++++++--- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/server/src/uds/xmlrpc/auths/AdminAuth.py b/server/src/uds/xmlrpc/auths/AdminAuth.py index 95922f720..b9eae3344 100644 --- a/server/src/uds/xmlrpc/auths/AdminAuth.py +++ b/server/src/uds/xmlrpc/auths/AdminAuth.py @@ -51,7 +51,8 @@ class Credentials(object): ''' Represents a valid credential from a user connected to administration. ''' - def __init__(self, session, credential_key): + def __init__(self, request, session, credential_key): + self.request = request self.idAuth = session['idAuth'] self.isAdmin = session['isAdmin'] self.user = session['username'] @@ -100,8 +101,12 @@ def needs_credentials(xmlrpc_func): ''' @wraps(xmlrpc_func) def _wrapped_xmlrcp_func(credentials, *args, **kwargs): + # We expect that request is passed in as last argument ALWAYS (look at views) + args = list(args) + request = args.pop() # Last argumment is request + args = tuple(args) logger.debug('Checkin credentials {0} for function {1}'.format(credentials, xmlrpc_func.__name__)) - cred = validateCredentials(credentials) + cred = validateCredentials(request, credentials) if cred is not None: logger.debug('Credentials valid, executing') return xmlrpc_func(cred, *args, **kwargs) @@ -109,7 +114,7 @@ def needs_credentials(xmlrpc_func): return _wrapped_xmlrcp_func -def validateCredentials(credentials): +def validateCredentials(request, credentials): ''' Validates the credentials of an user :param credentials: @@ -124,7 +129,7 @@ def validateCredentials(credentials): # Updates the expire key, this is the slow part as we can see at debug log, better if we can only update the expire_key this takes 80 ms!!! session.save() logger.debug('Session updated') - return Credentials(session, credentials ) + return Credentials(request, session, credentials ) def invalidateCredentials(credentials): @@ -145,7 +150,7 @@ def getAdminAuths(locale): # Xmlrpc functions -def login(username, password, idAuth, locale): +def login(username, password, idAuth, locale, request): ''' Validates the user/password credentials, assign to it the specified locale for this session and returns a credentials response ''' diff --git a/server/src/uds/xmlrpc/views.py b/server/src/uds/xmlrpc/views.py index 43a4562a3..2a01916b5 100644 --- a/server/src/uds/xmlrpc/views.py +++ b/server/src/uds/xmlrpc/views.py @@ -57,16 +57,50 @@ import logging logger = logging.getLogger(__name__) -dispatcher = SimpleXMLRPCDispatcher(allow_none=False, encoding=None) +class XMLRPCDispatcher(SimpleXMLRPCDispatcher): + ''' + Own dispatchers, to allow the pass of the request to the methods. + + Request will be, in most cases, removed from params at @needs_credentials decorator + This means that all xmlrpc methods that needs_credentials, will have the request at + the Credentials object. + + If no request is needed, normal method invocation will be done + ''' + + def __init__(self): + SimpleXMLRPCDispatcher.__init__(self, allow_none=False, encoding=None) + + + def dispatch(self, request, **kwargs): + import xmlrpclib + xml = request.raw_post_data + try: + params, method = xmlrpclib.loads(xml) + try: + response = self._dispatch(method, params + (request,)) + except TypeError: + response = self._dispatch(method, params) + + response = (response,) + response = xmlrpclib.dumps( response, methodresponse=1) + except xmlrpclib.Fault as fault: + response = xmlrpclib.dumps(fault) + except Exception as e: + response = xmlrpclib.dumps( + xmlrpclib.Fault(1, "Exception caught!: {0}".format(e)) + ) + + return HttpResponse(response, content_type = 'text/xml') + + +dispatcher = XMLRPCDispatcher() # csrf_exempt is needed because we don't expect xmlrcp to be called from a web form @csrf_exempt def xmlrpc(request): if len(request.POST): - response = HttpResponse(mimetype="text/xml") - data = dispatcher._marshaled_dispatch(request.raw_post_data) - #logger.debug(data) - response.write(data) + response = dispatcher.dispatch(request) else: logger.error('XMLRPC invocation with GET method {0}'.format(request.path)) response = HttpResponse()