[FIX] website: match get/post in is_multilang_url

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 /<lang>/get.

Closes #37223

closes odoo/odoo#40519

X-original-commit: c7650106f8588083be12812600a6c94ba703fd6f
Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
This commit is contained in:
Jeremy Kersten
2019-11-26 14:35:46 +00:00
parent ef0488ef91
commit dc77f67cad
5 changed files with 78 additions and 10 deletions
+16 -10
View File
@@ -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
+16
View File
@@ -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')
+1
View File
@@ -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
@@ -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'))
+19
View File
@@ -13,4 +13,23 @@
<script type="text/javascript" src="/test_website/static/tests/tours/json_auth.js"></script>
</xpath>
</template>
<record id="multi_url" model="website.page">
<field name="name">Multi URL test</field>
<field name="url">/multi_url</field>
<field name="website_published">False</field>
<field name="type">qweb</field>
<field name="key">test_website.multi_url</field>
<field name="website_published">True</field>
<field name="arch" type="xml">
<t t-name='multi_url'>
<div>
<a id='get' href="/get">get</a>
<form id='post' action="/post">post</form>>
<a id='get_post' href="/get_post">get_post</a>
<a id='get_post_nomultilang' href="/get_post_nomultilang">get_post_nomultilang</a>
</div>
</t>
</field>
</record>
</odoo>