A visitor could visit a web page having a lang in its context that is not installed in the databased he is connected to. The problem is that visitors are not logged-in thus it is not possible to determine their lang via their `res.users` preferences. The lang used instead is the lang set in the `Accept-Language` header of the incoming request, that header is set by various browsers in accordance to the user system preferences or browser settings. The browser lang (`Request.best`) is only parsed according to the `babel` database, it is a lang syntactically speaking but not necessary a lang that is installed in the database. At the moment the browser lang is set in the context (inside of `Request._get_dbname_and_session`), it is not possible to verify it is installed in the database as no connection to any database as been established yet. Instead the lang is validated inside of `ir.http._pre_dispatch` which is the method responsible to prepare/fix various stuff on the request/session/context. In regard to93b684d3c7, we prefer to fallback on English, hence the modification in `get_lang`. closes odoo/odoo#116683 Reference-to:93b684d3c7([FIX] base: lang should fallback on english instead of arab) X-original-commit: 743e97667e44cdaab6db334d807cf3d409cea621 Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
134 lines
5.1 KiB
Python
134 lines
5.1 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import json
|
|
from urllib.parse import urlparse
|
|
from unittest.mock import patch
|
|
|
|
import odoo
|
|
from odoo.tests.common import get_db_name
|
|
from odoo.tools import mute_logger
|
|
from .test_common import TestHttpBase
|
|
|
|
|
|
GEOIP_ODOO_FARM_2 = {
|
|
'city': 'Ramillies',
|
|
'country_code': 'BE',
|
|
'country_name': 'Belgium',
|
|
'latitude': 50.6314,
|
|
'longitude': 4.8573,
|
|
'region': 'WAL',
|
|
'time_zone': 'Europe/Brussels'
|
|
}
|
|
|
|
|
|
class TestHttpSession(TestHttpBase):
|
|
|
|
@mute_logger('odoo.http') # greeting_none called ignoring args {'debug'}
|
|
def test_session0_debug_mode(self):
|
|
session = self.authenticate(None, None)
|
|
self.assertEqual(session.debug, '')
|
|
self.db_url_open('/test_http/greeting').raise_for_status()
|
|
self.assertEqual(session.debug, '')
|
|
self.db_url_open('/test_http/greeting?debug=1').raise_for_status()
|
|
self.assertEqual(session.debug, '1')
|
|
self.db_url_open('/test_http/greeting').raise_for_status()
|
|
self.assertEqual(session.debug, '1')
|
|
self.db_url_open('/test_http/greeting?debug=').raise_for_status()
|
|
self.assertEqual(session.debug, '')
|
|
|
|
def test_session1_default_session(self):
|
|
# The default session should not be saved on the filestore.
|
|
with patch.object(odoo.http.root.session_store, 'save') as mock_save:
|
|
res = self.db_url_open('/test_http/geoip')
|
|
res.raise_for_status()
|
|
try:
|
|
mock_save.assert_not_called()
|
|
except AssertionError as exc:
|
|
msg = f'save() was called with args: {mock_save.call_args}'
|
|
raise AssertionError(msg) from exc
|
|
|
|
def test_session3_logout_15_0_geoip(self):
|
|
session = self.authenticate(None, None)
|
|
session['db'] = 'idontexist'
|
|
session['geoip'] = {} # Until saas-15.2 geoip was directly stored in the session
|
|
odoo.http.root.session_store.save(session)
|
|
|
|
with self.assertLogs('odoo.http', level='WARNING') as (_, warnings):
|
|
res = self.multidb_url_open('/test_http/ensure_db', dblist=['db1', 'db2'])
|
|
|
|
self.assertEqual(warnings, [
|
|
"WARNING:odoo.http:Logged into database 'idontexist', but dbfilter rejects it; logging session out.",
|
|
])
|
|
self.assertFalse(session['db'])
|
|
self.assertEqual(res.status_code, 303)
|
|
self.assertEqual(urlparse(res.headers['Location']).path, '/web/database/selector')
|
|
|
|
def test_session4_web_authenticate_multidb(self):
|
|
self.db_list = [get_db_name(), 'another_database']
|
|
|
|
payload = json.dumps({
|
|
'jsonrpc': '2.0',
|
|
'id': None,
|
|
'method': 'call',
|
|
'params': {
|
|
'db': get_db_name(),
|
|
'login': 'admin',
|
|
'password': 'admin',
|
|
}
|
|
})
|
|
|
|
res = self.multidb_url_open(
|
|
'/web/session/authenticate', data=payload, headers={
|
|
'Content-Type': 'application/json',
|
|
}
|
|
)
|
|
res.raise_for_status()
|
|
self.assertEqual(res.status_code, 200)
|
|
|
|
res = self.multidb_url_open('/test_http/greeting-user')
|
|
res.raise_for_status()
|
|
self.assertEqual(res.status_code, 200, "Should not be redirected to /web/login")
|
|
|
|
def test_session5_default_lang(self):
|
|
self.env['res.lang']._activate_lang('en_US') # default lang
|
|
lang_fr = self.env['res.lang']._activate_lang('fr_FR')
|
|
|
|
with self.subTest(case='no preferred lang'):
|
|
res = self.url_open('/test_http/echo-http-context-lang')
|
|
self.assertEqual(res.text, 'en_US')
|
|
|
|
with self.subTest(case='fr preferred and fr_FR enabled'):
|
|
res = self.url_open('/test_http/echo-http-context-lang', headers={
|
|
'Accept-Language': 'fr',
|
|
})
|
|
self.assertEqual(res.text, 'fr_FR')
|
|
|
|
with self.subTest(case='fr preferred but fr_FR disabled'):
|
|
lang_fr.active = False
|
|
res = self.url_open('/test_http/echo-http-context-lang', headers={
|
|
'Accept-Language': 'fr',
|
|
})
|
|
self.assertEqual(res.text, 'en_US')
|
|
|
|
def test_session6_saved_lang(self):
|
|
session = self.authenticate('demo', 'demo')
|
|
self.env['res.lang']._activate_lang('en_US') # default lang
|
|
lang_fr = self.env['res.lang']._activate_lang('fr_FR')
|
|
|
|
with self.subTest(case='no saved lang'):
|
|
res = self.url_open('/test_http/echo-http-context-lang')
|
|
self.assertEqual(res.text, 'en_US')
|
|
|
|
with self.subTest(case='fr saved and fr_FR enabled'):
|
|
session.context['lang'] = 'fr_FR'
|
|
odoo.http.root.session_store.save(session)
|
|
res = self.url_open('/test_http/echo-http-context-lang')
|
|
self.assertEqual(res.text, 'fr_FR')
|
|
|
|
with self.subTest(case='fr saved but fr_FR disabled'):
|
|
session['lang'] = 'fr_FR'
|
|
odoo.http.root.session_store.save(session)
|
|
lang_fr.active = False
|
|
res = self.url_open('/test_http/echo-http-context-lang')
|
|
self.assertEqual(res.text, 'en_US')
|