diff --git a/addons/web/http.py b/addons/web/http.py index b42a7d7d0eb..83a3ac4fa42 100644 --- a/addons/web/http.py +++ b/addons/web/http.py @@ -34,8 +34,6 @@ import urllib2 import openerp -import session - import inspect import functools @@ -119,7 +117,7 @@ class WebRequest(object): self.session_id = uuid.uuid4().hex self.session = self.httpsession.get(self.session_id) if not self.session: - self.session = session.OpenERPSession() + self.session = OpenERPSession() self.httpsession[self.session_id] = self.session with set_request(self): @@ -157,13 +155,13 @@ class WebRequest(object): elif self.auth_method == "noauth": self.db = (self.session._db or openerp.addons.web.controllers.main.db_monodb()).lower() if not self.db: - raise session.SessionExpiredException("No valid database for request %s" % self.httprequest) + raise SessionExpiredException("No valid database for request %s" % self.httprequest) self.uid = None else: # auth try: self.session.check_security() - except session.SessionExpiredException, e: - raise session.SessionExpiredException("Session expired for request %s" % self.httprequest) + except SessionExpiredException, e: + raise SessionExpiredException("Session expired for request %s" % self.httprequest) self.db = self.session._db self.uid = self.session._uid @@ -337,7 +335,7 @@ class JsonRequest(WebRequest): # _logger.debug("--> %s.%s\n%s", func.im_class.__name__, func.__name__, pprint.pformat(self.jsonrequest)) response['id'] = self.jsonrequest.get('id') response["result"] = self._call_function(**self.params) - except session.AuthenticationError, e: + except AuthenticationError, e: _logger.exception("Exception during JSON request handling.") se = serialize_exception(e) error = { @@ -566,6 +564,225 @@ class Controller(object): else: return getattr(self, name) +############################# +# OpenERP Sessions # +############################# + +class AuthenticationError(Exception): + pass + +class SessionExpiredException(Exception): + pass + +class Service(object): + """ + .. deprecated:: 8.0 + Use ``openerp.netsvc.dispatch_rpc()`` instead. + """ + def __init__(self, session, service_name): + self.session = session + self.service_name = service_name + + def __getattr__(self, method): + def proxy_method(*args): + result = openerp.netsvc.dispatch_rpc(self.service_name, method, args) + return result + return proxy_method + +class Model(object): + """ + .. deprecated:: 8.0 + Use the resistry and cursor in ``openerp.addons.web.http.request`` instead. + """ + def __init__(self, session, model): + self.session = session + self.model = model + self.proxy = self.session.proxy('object') + + def __getattr__(self, method): + self.session.assert_valid() + def proxy(*args, **kw): + # Can't provide any retro-compatibility for this case, so we check it and raise an Exception + # to tell the programmer to adapt his code + if not http.request.db or not http.request.uid or self.session._db != http.request.db \ + or self.session._uid != http.request.uid: + raise Exception("Trying to use Model with badly configured database or user.") + + mod = http.request.registry.get(self.model) + meth = getattr(mod, method) + cr = http.request.cr + result = meth(cr, http.request.uid, *args, **kw) + # reorder read + if method == "read": + if isinstance(result, list) and len(result) > 0 and "id" in result[0]: + index = {} + for r in result: + index[r['id']] = r + result = [index[x] for x in args[0] if x in index] + return result + return proxy + +class OpenERPSession(object): + """ + An OpenERP RPC session, a given user can own multiple such sessions + in a web session. + + .. attribute:: context + + The session context, a ``dict``. Can be reloaded by calling + :meth:`openerpweb.openerpweb.OpenERPSession.get_context` + + .. attribute:: domains_store + + A ``dict`` matching domain keys to evaluable (but non-literal) domains. + + Used to store references to non-literal domains which need to be + round-tripped to the client browser. + """ + def __init__(self): + self._creation_time = time.time() + self._db = False + self._uid = False + self._login = False + self._password = False + self._suicide = False + self.context = {} + self.jsonp_requests = {} # FIXME use a LRU + + def authenticate(self, db, login, password, env=None): + """ + Authenticate the current user with the given db, login and password. If successful, store + the authentication parameters in the current session and request. + """ + uid = openerp.netsvc.dispatch_rpc('common', 'authenticate', [db, login, password, env]) + self._db = db + self._uid = uid + self._login = login + self._password = password + http.request.db = db + http.request.uid = uid + + if uid: self.get_context() + return uid + + def check_security(self): + """ + Chech the current authentication parameters to know if those are still valid. This method + should be called at each request. If the authentication fails, a ``SessionExpiredException`` + is raised. + """ + if not self._db or not self._uid: + raise SessionExpiredException("Session expired") + import openerp.service.security as security + security.check(self._db, self._uid, self._password) + + def get_context(self): + """ + Re-initializes the current user's session context (based on + his preferences) by calling res.users.get_context() with the old + context. + + :returns: the new context + """ + assert self._uid, "The user needs to be logged-in to initialize his context" + self.context = http.request.registry.get('res.users').context_get(http.request.cr, http.request.uid) or {} + self.context['uid'] = self._uid + self._fix_lang(self.context) + return self.context + + def _fix_lang(self, context): + """ OpenERP provides languages which may not make sense and/or may not + be understood by the web client's libraries. + + Fix those here. + + :param dict context: context to fix + """ + lang = context['lang'] + + # inane OpenERP locale + if lang == 'ar_AR': + lang = 'ar' + + # lang to lang_REGION (datejs only handles lang_REGION, no bare langs) + if lang in babel.core.LOCALE_ALIASES: + lang = babel.core.LOCALE_ALIASES[lang] + + context['lang'] = lang or 'en_US' + + def send(self, service_name, method, *args): + """ + .. deprecated:: 8.0 + Use ``openerp.netsvc.dispatch_rpc()`` instead. + """ + return openerp.netsvc.dispatch_rpc(service_name, method, args) + + def proxy(self, service): + """ + .. deprecated:: 8.0 + Use ``openerp.netsvc.dispatch_rpc()`` instead. + """ + return Service(self, service) + + def assert_valid(self, force=False): + """ + .. deprecated:: 8.0 + Use ``check_security()`` instead. + + Ensures this session is valid (logged into the openerp server) + """ + if self._uid and not force: + return + # TODO use authenticate instead of login + self._uid = self.proxy("common").login(self._db, self._login, self._password) + if not self._uid: + raise AuthenticationError("Authentication failure") + + def ensure_valid(self): + """ + .. deprecated:: 8.0 + Use ``check_security()`` instead. + """ + if self._uid: + try: + self.assert_valid(True) + except Exception: + self._uid = None + + def execute(self, model, func, *l, **d): + """ + .. deprecated:: 8.0 + Use the resistry and cursor in ``openerp.addons.web.http.request`` instead. + """ + model = self.model(model) + r = getattr(model, func)(*l, **d) + return r + + def exec_workflow(self, model, id, signal): + """ + .. deprecated:: 8.0 + Use the resistry and cursor in ``openerp.addons.web.http.request`` instead. + """ + self.assert_valid() + r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id) + return r + + def model(self, model): + """ + .. deprecated:: 8.0 + Use the resistry and cursor in ``openerp.addons.web.http.request`` instead. + + Get an RPC proxy for the object ``model``, bound to this session. + + :param model: an OpenERP model name + :type model: str + :rtype: a model object + """ + if self._db == False: + raise SessionExpiredException("Session expired") + + return Model(self, model) + #---------------------------------------------------------- # Session context manager #---------------------------------------------------------- @@ -584,7 +801,7 @@ def session_context(request, session_store, session_lock, sid): # session id, and are generally noise removed_sessions = set() for key, value in request.session.items(): - if not isinstance(value, session.OpenERPSession): + if not isinstance(value, OpenERPSession): continue if getattr(value, '_suicide', False) or ( not value._uid @@ -612,7 +829,7 @@ def session_context(request, session_store, session_lock, sid): in_store = session_store.get(sid) for k, v in request.session.iteritems(): stored = in_store.get(k) - if stored and isinstance(v, session.OpenERPSession): + if stored and isinstance(v, OpenERPSession): if hasattr(v, 'contexts_store'): del v.contexts_store if hasattr(v, 'domains_store'): diff --git a/addons/web/session.py b/addons/web/session.py deleted file mode 100644 index 948cd4c4ad0..00000000000 --- a/addons/web/session.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/python -import datetime -import babel -import dateutil.relativedelta -import logging -import time -import traceback -import sys - -import openerp -import http - -_logger = logging.getLogger(__name__) - -#---------------------------------------------------------- -# OpenERPSession RPC openerp backend access -#---------------------------------------------------------- -class AuthenticationError(Exception): - pass - -class SessionExpiredException(Exception): - pass - -class Service(object): - """ - .. deprecated:: 8.0 - Use ``openerp.netsvc.dispatch_rpc()`` instead. - """ - def __init__(self, session, service_name): - self.session = session - self.service_name = service_name - - def __getattr__(self, method): - def proxy_method(*args): - result = openerp.netsvc.dispatch_rpc(self.service_name, method, args) - return result - return proxy_method - -class Model(object): - """ - .. deprecated:: 8.0 - Use the resistry and cursor in ``openerp.addons.web.http.request`` instead. - """ - def __init__(self, session, model): - self.session = session - self.model = model - self.proxy = self.session.proxy('object') - - def __getattr__(self, method): - self.session.assert_valid() - def proxy(*args, **kw): - # Can't provide any retro-compatibility for this case, so we check it and raise an Exception - # to tell the programmer to adapt his code - if not http.request.db or not http.request.uid or self.session._db != http.request.db \ - or self.session._uid != http.request.uid: - raise Exception("Trying to use Model with badly configured database or user.") - - mod = http.request.registry.get(self.model) - meth = getattr(mod, method) - cr = http.request.cr - result = meth(cr, http.request.uid, *args, **kw) - # reorder read - if method == "read": - if isinstance(result, list) and len(result) > 0 and "id" in result[0]: - index = {} - for r in result: - index[r['id']] = r - result = [index[x] for x in args[0] if x in index] - return result - return proxy - -class OpenERPSession(object): - """ - An OpenERP RPC session, a given user can own multiple such sessions - in a web session. - - .. attribute:: context - - The session context, a ``dict``. Can be reloaded by calling - :meth:`openerpweb.openerpweb.OpenERPSession.get_context` - - .. attribute:: domains_store - - A ``dict`` matching domain keys to evaluable (but non-literal) domains. - - Used to store references to non-literal domains which need to be - round-tripped to the client browser. - """ - def __init__(self): - self._creation_time = time.time() - self._db = False - self._uid = False - self._login = False - self._password = False - self._suicide = False - self.context = {} - self.jsonp_requests = {} # FIXME use a LRU - - def authenticate(self, db, login, password, env=None): - """ - Authenticate the current user with the given db, login and password. If successful, store - the authentication parameters in the current session and request. - """ - uid = openerp.netsvc.dispatch_rpc('common', 'authenticate', [db, login, password, env]) - self._db = db - self._uid = uid - self._login = login - self._password = password - http.request.db = db - http.request.uid = uid - - if uid: self.get_context() - return uid - - def check_security(self): - """ - Chech the current authentication parameters to know if those are still valid. This method - should be called at each request. If the authentication fails, a ``SessionExpiredException`` - is raised. - """ - if not self._db or not self._uid: - raise SessionExpiredException("Session expired") - import openerp.service.security as security - security.check(self._db, self._uid, self._password) - - def get_context(self): - """ - Re-initializes the current user's session context (based on - his preferences) by calling res.users.get_context() with the old - context. - - :returns: the new context - """ - assert self._uid, "The user needs to be logged-in to initialize his context" - self.context = http.request.registry.get('res.users').context_get(http.request.cr, http.request.uid) or {} - self.context['uid'] = self._uid - self._fix_lang(self.context) - return self.context - - def _fix_lang(self, context): - """ OpenERP provides languages which may not make sense and/or may not - be understood by the web client's libraries. - - Fix those here. - - :param dict context: context to fix - """ - lang = context['lang'] - - # inane OpenERP locale - if lang == 'ar_AR': - lang = 'ar' - - # lang to lang_REGION (datejs only handles lang_REGION, no bare langs) - if lang in babel.core.LOCALE_ALIASES: - lang = babel.core.LOCALE_ALIASES[lang] - - context['lang'] = lang or 'en_US' - - def send(self, service_name, method, *args): - """ - .. deprecated:: 8.0 - Use ``openerp.netsvc.dispatch_rpc()`` instead. - """ - return openerp.netsvc.dispatch_rpc(service_name, method, args) - - def proxy(self, service): - """ - .. deprecated:: 8.0 - Use ``openerp.netsvc.dispatch_rpc()`` instead. - """ - return Service(self, service) - - def assert_valid(self, force=False): - """ - .. deprecated:: 8.0 - Use ``check_security()`` instead. - - Ensures this session is valid (logged into the openerp server) - """ - if self._uid and not force: - return - # TODO use authenticate instead of login - self._uid = self.proxy("common").login(self._db, self._login, self._password) - if not self._uid: - raise AuthenticationError("Authentication failure") - - def ensure_valid(self): - """ - .. deprecated:: 8.0 - Use ``check_security()`` instead. - """ - if self._uid: - try: - self.assert_valid(True) - except Exception: - self._uid = None - - def execute(self, model, func, *l, **d): - """ - .. deprecated:: 8.0 - Use the resistry and cursor in ``openerp.addons.web.http.request`` instead. - """ - model = self.model(model) - r = getattr(model, func)(*l, **d) - return r - - def exec_workflow(self, model, id, signal): - """ - .. deprecated:: 8.0 - Use the resistry and cursor in ``openerp.addons.web.http.request`` instead. - """ - self.assert_valid() - r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id) - return r - - def model(self, model): - """ - .. deprecated:: 8.0 - Use the resistry and cursor in ``openerp.addons.web.http.request`` instead. - - Get an RPC proxy for the object ``model``, bound to this session. - - :param model: an OpenERP model name - :type model: str - :rtype: a model object - """ - if self._db == False: - raise SessionExpiredException("Session expired") - - return Model(self, model) - -# vim:et:ts=4:sw=4: