diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 0aafa6d4d2c..89c039b20c0 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -535,11 +535,15 @@ html_template = """ class Home(http.Controller): @http.route('/', type='http', auth="none") - def index(self, s_action=None, db=None, **kw): - db, redir = db_monodb_redirect() - if redir: - return redirect_with_hash(redir) - + def index(self, s_action=None, **kw): + if 'db' in kw: + ndb = kw['db'] + lst = http.db_list(True) + if ndb in lst and ndb != request.session.db: + request.session.logout() + request.session.db = ndb + + db = request.session.db debug = "debug" in kw js = "\n ".join('' % i for i in manifest_list('js', db=db, debug=debug)) @@ -821,7 +825,7 @@ class Session(http.Controller): @http.route('/web/session/get_session_info', type='json', auth="none") def get_session_info(self): request.uid = request.session.uid - request.db = request.session.db + request.disable_db = False return self.session_info() @http.route('/web/session/authenticate', type='json', auth="none") diff --git a/addons/web/http.py b/addons/web/http.py index 5eddfadcf48..ff080787739 100644 --- a/addons/web/http.py +++ b/addons/web/http.py @@ -101,15 +101,13 @@ class WebRequest(object): self.httpsession = httprequest.session self.session = httprequest.session self.session_id = httprequest.session.sid - self.db = None + self.disable_db = False self.uid = None self.func = None self.auth_method = None self._cr_cm = None self._cr = None self.func_request_type = None - with set_request(self): - self.db = self.session.db or db_monodb() # set db/uid trackers - they're cleaned up at the WSGI # dispatching phase in openerp.service.wsgi_server.application if self.db: @@ -127,17 +125,16 @@ class WebRequest(object): self.session.logout() raise SessionExpiredException("Session expired for request %s" % self.httprequest) if self.auth_method == "none": - self.db = None + self.disable_db = True self.uid = None elif self.auth_method == "admin": - self.db = self.session.db or db_monodb() + self.disable_db = False if not self.db: raise SessionExpiredException("No valid database for request %s" % self.httprequest) self.uid = openerp.SUPERUSER_ID else: # auth - self.db = self.session.db + self.disable_db = False self.uid = self.session.uid - @property def registry(self): """ @@ -146,6 +143,14 @@ class WebRequest(object): """ return openerp.modules.registry.RegistryManager.get(self.db) if self.db else None + @property + def db(self): + """ + The registry to the database linked to this request. Can be ``None`` if the current request uses the + ``none'' authentication. + """ + return self.session.db if not self.disable_db else None + @property def cr(self): """ @@ -179,7 +184,7 @@ class WebRequest(object): return self.func(*args, **kwargs) finally: # just to be sure no one tries to re-use the request - self.db = None + self.disable_db = True self.uid = None def route(route, type="http", auth="user"): @@ -611,8 +616,8 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): self.uid = uid self.login = login self.password = password - request.db = db request.uid = uid + request.disable_db = False if uid: self.get_context() return uid @@ -885,6 +890,8 @@ class Root(object): else: httprequest.session = self.session_store.get(sid) + self._find_db(httprequest) + if not "lang" in httprequest.session.context: lang = httprequest.accept_languages.best or "en_US" lang = babel.core.LOCALE_ALIASES.get(lang, lang).replace('-', '_') @@ -921,6 +928,12 @@ class Root(object): except werkzeug.exceptions.HTTPException, e: return e(environ, start_response) + def _find_db(self, httprequest): + db = db_monodb(httprequest) + if db != httprequest.session.db: + httprequest.session.logout() + httprequest.session.db = db + def _build_request(self, httprequest): if httprequest.args.get('jsonp'): return JsonRequest(httprequest) @@ -1035,43 +1048,39 @@ class Root(object): root = None -def db_list(force=False): - proxy = request.session.proxy("db") - dbs = proxy.list(force) - h = request.httprequest.environ['HTTP_HOST'].split(':')[0] +def db_list(force=False, httprequest=None): + httprequest = httprequest or request.httprequest + dbs = openerp.netsvc.dispatch_rpc("db", "list", [force]) + h = httprequest.environ['HTTP_HOST'].split(':')[0] d = h.split('.')[0] r = openerp.tools.config['dbfilter'].replace('%h', h).replace('%d', d) dbs = [i for i in dbs if re.match(r, i)] return dbs -def db_redirect(match_first_only_if_unique): +def db_redirect(match_first_only_if_unique, httprequest=None): + httprequest = httprequest or request.httprequest db = None redirect = None - dbs = db_list(True) + dbs = db_list(True, httprequest) - # 1 try the db in the url - db_url = request.httprequest.args.get('db') - if db_url in dbs: - return (db_url, None) + # 1 try the db in the session + db_session = httprequest.session.db + if db_session in dbs: + return (db_session, None) - # 2 use the database from the cookie if it's listable and still listed - cookie_db = request.httprequest.cookies.get('last_used_database') - if cookie_db in dbs: - db = cookie_db - - # 3 use the first db if user can list databases - if dbs and not db and (not match_first_only_if_unique or len(dbs) == 1): + # 2 use the first db if user can list databases + if dbs and (not match_first_only_if_unique or len(dbs) == 1): db = dbs[0] # redirect to the chosen db if multiple are available if db and len(dbs) > 1: - query = dict(urlparse.parse_qsl(request.httprequest.query_string, keep_blank_values=True)) + query = dict(urlparse.parse_qsl(httprequest.query_string, keep_blank_values=True)) query.update({'db': db}) - redirect = request.httprequest.path + '?' + urllib.urlencode(query) + redirect = httprequest.path + '?' + urllib.urlencode(query) return (db, redirect) -def db_monodb(): +def db_monodb(httprequest=None): """ Magic function to find the current database. @@ -1080,9 +1089,9 @@ def db_monodb(): * Magic * More magic - Return ``None`` if the magic is not magic enough. + Returns ``None`` if the magic is not magic enough. """ - return db_redirect(True)[0] + return db_redirect(True, httprequest=httprequest)[0] class CommonController(Controller): diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 1c976cb619e..036f57eee7a 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -705,20 +705,9 @@ instance.web.Login = instance.web.Widget.extend({ } return d; }, - remember_last_used_database: function(db) { - // This cookie will be used server side in order to avoid db reloading on first visit - var ttl = 24 * 60 * 60 * 365; - document.cookie = [ - 'last_used_database=' + db, - 'path=/', - 'max-age=' + ttl, - 'expires=' + new Date(new Date().getTime() + ttl * 1000).toGMTString() - ].join(';'); - }, database_selected: function(db) { var params = $.deparam.querystring(); params.db = db; - this.remember_last_used_database(db); this.$('.oe_login_dbpane').empty().text(_t('Loading...')); this.$('[name=login], [name=password]').prop('readonly', true); instance.web.redirect('/?' + $.param(params)); @@ -769,7 +758,6 @@ instance.web.Login = instance.web.Widget.extend({ self.hide_error(); self.$(".oe_login_pane").fadeOut("slow"); return this.session.session_authenticate(db, login, password).then(function() { - self.remember_last_used_database(db); if (self.has_local_storage && self.remember_credentials) { localStorage.setItem(db + '|last_login', login); if (self.session.debug) {