From dc77f67cad95d0b0bd316cbdfc36a380f2daf73d Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Fri, 15 Nov 2019 08:19:43 +0000 Subject: [PATCH] [FIX] website: match get/post in is_multilang_url MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Old heuristic is not more True: Force to check method to POST. Odoo uses methods : ['POST'] and ['GET', 'POST'] We have some controller that only allow 'GET' method, so we need to check GET also when we try to know if an url is multilang or not. This commit fix case where a controller '/test' only allow GET and you were in another language that the default, in this case, the rendered url in qweb was /get instead of //get. Closes #37223 closes odoo/odoo#40519 X-original-commit: c7650106f8588083be12812600a6c94ba703fd6f Signed-off-by: Jérémy Kersten (jke) --- addons/http_routing/models/ir_http.py | 26 ++++++++++++------- addons/test_website/controllers/main.py | 16 ++++++++++++ addons/test_website/tests/__init__.py | 1 + .../test_website/tests/test_is_multilang.py | 26 +++++++++++++++++++ addons/test_website/views/templates.xml | 19 ++++++++++++++ 5 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 addons/test_website/tests/test_is_multilang.py diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py index 988a50000cc..983761c8b8f 100644 --- a/addons/http_routing/models/ir_http.py +++ b/addons/http_routing/models/ir_http.py @@ -222,23 +222,29 @@ def is_multilang_url(local_url, lang_url_codes=None): if spath[1] in lang_url_codes: spath.pop(1) local_url = '/'.join(spath) - try: - # Try to match an endpoint in werkzeug's routing table - url = local_url.partition('#')[0].split('?') - path = url[0] - query_string = url[1] if len(url) > 1 else None - router = request.httprequest.app.get_db_router(request.db).bind('') - # Force to check method to POST. Odoo uses methods : ['POST'] and ['GET', 'POST'] - func = router.match(path, method='POST', query_args=query_string)[0] - return (func.routing.get('website', False) and + + url = local_url.partition('#')[0].split('?') + path = url[0] + query_string = url[1] if len(url) > 1 else None + router = request.httprequest.app.get_db_router(request.db).bind('') + + def is_multilang_func(func): + return (func and func.routing.get('website', False) and func.routing.get('multilang', func.routing['type'] == 'http')) + # Try to match an endpoint in werkzeug's routing table + try: + func = router.match(path, method='POST', query_args=query_string)[0] + return is_multilang_func(func) + except werkzeug.exceptions.MethodNotAllowed: + func = router.match(path, method='GET', query_args=query_string)[0] + return is_multilang_func(func) except werkzeug.exceptions.NotFound: # Consider /static/ files as non-multilang static_index = path.find('/static/', 1) if static_index != -1 and static_index == path.find('/', 1): return False return True - except Exception as e: + except Exception: return False diff --git a/addons/test_website/controllers/main.py b/addons/test_website/controllers/main.py index b95dfddd2a1..1973e363653 100644 --- a/addons/test_website/controllers/main.py +++ b/addons/test_website/controllers/main.py @@ -103,3 +103,19 @@ class WebsiteTest(Home): @http.route('/test_access_denied_http', type='http', auth='public', website=True, sitemap=False) def test_denied_error_http(self, **kwargs): raise AccessDenied("This is an access denied http test") + + @http.route(['/get'], type='http', auth="public", methods=['GET'], website=True, sitemap=False) + def get_method(self, **kw): + return request.make_response('get') + + @http.route(['/post'], type='http', auth="public", methods=['POST'], website=True, sitemap=False) + def post_method(self, **kw): + return request.make_response('post') + + @http.route(['/get_post'], type='http', auth="public", methods=['GET', 'POST'], website=True, sitemap=False) + def get_post_method(self, **kw): + return request.make_response('get_post') + + @http.route(['/get_post_nomultilang'], type='http', auth="public", methods=['GET', 'POST'], website=True, multilang=False, sitemap=False) + def get_post_method_no_multilang(self, **kw): + return request.make_response('get_post_nomultilang') diff --git a/addons/test_website/tests/__init__.py b/addons/test_website/tests/__init__.py index 4fab1ec9b68..b7044f07875 100644 --- a/addons/test_website/tests/__init__.py +++ b/addons/test_website/tests/__init__.py @@ -2,6 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from . import test_controller_args +from . import test_is_multilang from . import test_reset_views from . import test_error from . import test_views_during_module_operation diff --git a/addons/test_website/tests/test_is_multilang.py b/addons/test_website/tests/test_is_multilang.py new file mode 100644 index 00000000000..69259f32054 --- /dev/null +++ b/addons/test_website/tests/test_is_multilang.py @@ -0,0 +1,26 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. +import odoo.tests +import lxml + + +@odoo.tests.common.tagged('post_install', '-at_install') +class TestIsMultiLang(odoo.tests.HttpCase): + + def test_01_is_multilang_url(self): + website = self.env['website'].search([], limit=1) + fr = self.env.ref('base.lang_fr').sudo() + en = self.env.ref('base.lang_en').sudo() + + fr.active = True + fr_prefix = "/" + fr.iso_code + + website.default_lang_id = en + website.language_ids = en + fr + + for data in [None, {'post': True}]: # GET / POST + body = lxml.html.fromstring(self.url_open('/fr/multi_url', data=data).content) + + self.assertEqual(fr_prefix + '/get', body.find('./a[@id="get"]').get('href')) + self.assertEqual(fr_prefix + '/post', body.find('./form[@id="post"]').get('action')) + self.assertEqual(fr_prefix + '/get_post', body.find('./a[@id="get_post"]').get('href')) + self.assertEqual('/get_post_nomultilang', body.find('./a[@id="get_post_nomultilang"]').get('href')) diff --git a/addons/test_website/views/templates.xml b/addons/test_website/views/templates.xml index 23e71565a55..9d12bd612a6 100644 --- a/addons/test_website/views/templates.xml +++ b/addons/test_website/views/templates.xml @@ -13,4 +13,23 @@ + + + Multi URL test + /multi_url + False + qweb + test_website.multi_url + True + + + + + +