diff --git a/tryton/common/common.py b/tryton/common/common.py index c951d9262a..47bece76da 100644 --- a/tryton/common/common.py +++ b/tryton/common/common.py @@ -1081,14 +1081,6 @@ def process_exception(exception, *args, **kwargs): return False elif exception.faultCode == 'NotLogged': from tryton.gui.main import Main - if kwargs.get('session', rpc._SESSION) != rpc._SESSION: - if args: - try: - return rpc_execute(*args) - except TrytonServerError, exception: - return process_exception(exception, *args, - rpc_execute=rpc_execute) - return if not PLOCK.acquire(False): return False hostname = rpc._HOST @@ -1258,7 +1250,6 @@ class RPCProgress(object): def run(self, process_exception_p=True, callback=None): self.process_exception_p = process_exception_p self.callback = callback - self.session = rpc._SESSION if self.parent.window: watch = gtk.gdk.Cursor(gtk.gdk.WATCH) self.parent.window.set_cursor(watch) @@ -1279,7 +1270,7 @@ class RPCProgress(object): return RPCProgress('execute', args).run(self.process_exception_p) result = process_exception(self.exception, *self.args, - rpc_execute=rpc_execute, session=self.session) + rpc_execute=rpc_execute) if result is False: self.exception = RPCException(self.exception) else: diff --git a/tryton/jsonrpc.py b/tryton/jsonrpc.py index edbe882e76..a933f5f338 100644 --- a/tryton/jsonrpc.py +++ b/tryton/jsonrpc.py @@ -18,6 +18,7 @@ import threading import errno from functools import partial from contextlib import contextmanager +import string __all__ = ["ResponseError", "Fault", "ProtocolError", "Transport", "ServerProxy", "ServerPool"] @@ -140,11 +141,12 @@ class Transport(xmlrpclib.Transport, xmlrpclib.SafeTransport): accept_gzip_encoding = True encode_threshold = 1400 # common MTU - def __init__(self, fingerprints=None, ca_certs=None): + def __init__(self, fingerprints=None, ca_certs=None, session=None): xmlrpclib.Transport.__init__(self) self._connection = (None, None) self.__fingerprints = fingerprints self.__ca_certs = ca_certs + self.session = session def getparser(self): target = JSONUnmarshaller() @@ -156,6 +158,12 @@ class Transport(xmlrpclib.Transport, xmlrpclib.SafeTransport): self, host) if extra_headers is None: extra_headers = [] + if self.session: + auth = base64.encodestring(self.session) + auth = string.join(string.split(auth), "") # get rid of whitespace + extra_headers.append( + ('Authorization', 'Session ' + auth), + ) extra_headers.append(('Connection', 'keep-alive')) return host, extra_headers, x509 @@ -249,10 +257,13 @@ class ServerProxy(xmlrpclib.ServerProxy): __id = 0 def __init__(self, host, port, database='', verbose=0, - fingerprints=None, ca_certs=None): + fingerprints=None, ca_certs=None, session=None): self.__host = '%s:%s' % (host, port) - self.__handler = '/' + database - self.__transport = Transport(fingerprints, ca_certs) + if database: + self.__handler = '/%s/' % database + else: + self.__handler = '/' + self.__transport = Transport(fingerprints, ca_certs, session) self.__verbose = verbose def __request(self, methodname, params): @@ -310,6 +321,7 @@ class ServerPool(object): self._lock = threading.Lock() self._pool = [] self._used = {} + self.session = None def getconn(self): with self._lock: diff --git a/tryton/rpc.py b/tryton/rpc.py index d5f476ad2e..82aed021f7 100644 --- a/tryton/rpc.py +++ b/tryton/rpc.py @@ -15,7 +15,6 @@ from tryton.config import CONFIG CONNECTION = None _USER = None _USERNAME = '' -_SESSION = '' _HOST = '' _PORT = None _DATABASE = '' @@ -37,8 +36,8 @@ ServerPool = partial(ServerPool, fingerprints=_FINGERPRINTS, def db_list(host, port): try: connection = ServerProxy(host, port) - logging.getLogger(__name__).info('common.db.list(None, None)') - result = connection.common.db.list(None, None) + logging.getLogger(__name__).info('common.db.list()') + result = connection.common.db.list() logging.getLogger(__name__).debug(repr(result)) return result except Fault, exception: @@ -50,11 +49,10 @@ def db_list(host, port): return None -def db_exec(host, port, method, *args): - connection = ServerProxy(host, port) - logging.getLogger(__name__).info('common.db.%s(None, None, %s)' % - (method, args)) - result = getattr(connection.common.db, method)(None, None, *args) +def db_exec(host, port, method, database='', *args): + connection = ServerProxy(host, port, database=database) + logging.getLogger(__name__).info('common.db.%s(%s)' % (method, args)) + result = getattr(connection.common.db, method)(*args) logging.getLogger(__name__).debug(repr(result)) return result @@ -64,7 +62,7 @@ def server_version(host, port): connection = ServerProxy(host, port) logging.getLogger(__name__).info( 'common.server.version(None, None)') - result = connection.common.server.version(None, None) + result = connection.common.server.version() logging.getLogger(__name__).debug(repr(result)) return result except (Fault, socket.error): @@ -72,7 +70,7 @@ def server_version(host, port): def login(username, password, host, port, database): - global CONNECTION, _USER, _USERNAME, _SESSION, _HOST, _PORT, _DATABASE + global CONNECTION, _USER, _USERNAME, _HOST, _PORT, _DATABASE global _VIEW_CACHE, _TOOLBAR_CACHE, _KEYWORD_CACHE _VIEW_CACHE = {} _TOOLBAR_CACHE = {} @@ -88,15 +86,14 @@ def login(username, password, host, port, database): logging.getLogger(__name__).debug(repr(result)) except socket.error: _USER = None - _SESSION = '' return -1 if not result: _USER = None - _SESSION = '' return -2 _USER = result[0] _USERNAME = username - _SESSION = result[1] + session = ':'.join(map(str, [username] + result)) + CONNECTION = ServerPool(host, port, database, session=session) _HOST = host _PORT = port _DATABASE = database @@ -105,23 +102,21 @@ def login(username, password, host, port, database): def logout(): - global CONNECTION, _USER, _USERNAME, _SESSION, _HOST, _PORT, _DATABASE + global CONNECTION, _USER, _USERNAME, _HOST, _PORT, _DATABASE global _VIEW_CACHE, _TOOLBAR_CACHE, _KEYWORD_CACHE if IPCServer.instance: IPCServer.instance.stop() if CONNECTION is not None: try: - logging.getLogger(__name__).info('common.db.logout(%s, %s)' % - (_USER, _SESSION)) + logging.getLogger(__name__).info('common.db.logout()') with CONNECTION() as conn: - conn.common.db.logout(_USER, _SESSION) + conn.common.db.logout() except (Fault, socket.error, httplib.CannotSendRequest): pass CONNECTION.close() CONNECTION = None _USER = None _USERNAME = '' - _SESSION = '' _HOST = '' _PORT = None _DATABASE = '' @@ -131,7 +126,7 @@ def logout(): def _execute(blocking, *args): - global CONNECTION, _USER, _SESSION + global CONNECTION, _USER if CONNECTION is None: raise TrytonServerError('NotLogged') key = False @@ -152,7 +147,7 @@ def _execute(blocking, *args): return _KEYWORD_CACHE[key] try: name = '.'.join(args[:3]) - args = (_USER, _SESSION) + args[3:] + args = args[3:] logging.getLogger(__name__).info('%s%s' % (name, args)) with CONNECTION() as conn: result = getattr(conn, name)(*args)