From 2ecc538d516ea30254b8152e8e48c912c0c86695 Mon Sep 17 00:00:00 2001 From: Jeremy Kersten Date: Mon, 11 Jan 2021 11:43:27 +0000 Subject: [PATCH] [FIX] website: handle RequestUID case in slug Before this commit, a 308 on a route with a modelconverter for a model that have a seo_name field will crash with an exception: Cannot iterate on RequestUID Another simplest solution was to use a with_user(SUPERUSER_ID) but in this case it bypass the security set and display the name of the record even if not yet published. How to reproduce: Create a 308 from /shop/ to /mag/ Unpublish product 10 Try to access /shop/product-10 You have an unmanaged '500 internal error" because slug_matching -> build -> to_url -> slug with a record with Requestuid as env._uid. X-original-commit: 4ac2cab96655a3c5e673b0a04be5599dba507850 --- addons/http_routing/models/ir_http.py | 2 +- addons/website/models/ir_http.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py index 96a795ae17c..56288781f9b 100644 --- a/addons/http_routing/models/ir_http.py +++ b/addons/http_routing/models/ir_http.py @@ -257,7 +257,7 @@ class ModelConverter(ir_http.ModelConverter): # limited support for negative IDs due to our slug pattern, assume abs() if not found if not env[self.model].browse(record_id).exists(): record_id = abs(record_id) - return env[self.model].browse(record_id) + return env[self.model].with_context(_converter_value=value).browse(record_id) class IrHttp(models.AbstractModel): diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index c3f712788f5..5866bd1dfd5 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -20,7 +20,6 @@ from odoo.exceptions import AccessError from odoo.http import request from odoo.tools.safe_eval import safe_eval from odoo.osv.expression import FALSE_DOMAIN - from odoo.addons.http_routing.models import ir_http from odoo.addons.http_routing.models.ir_http import _guess_mimetype from odoo.addons.portal.controllers.portal import _build_url_w_params @@ -77,7 +76,7 @@ class Http(models.AbstractModel): def _slug_matching(cls, adapter, endpoint, **kw): for arg in kw: if isinstance(kw[arg], models.BaseModel): - kw[arg] = kw[arg].with_user(request.uid) + kw[arg] = kw[arg].with_context(slug_matching=True) qs = request.httprequest.query_string.decode('utf-8') return adapter.build(endpoint, kw) + (qs and '?%s' % qs or '') @@ -438,6 +437,11 @@ class Http(models.AbstractModel): class ModelConverter(ir_http.ModelConverter): + def to_url(self, value): + if value.env.context.get('slug_matching'): + return value.env.context.get('_converter_value', str(value.id)) + return super().to_url(value) + def generate(self, uid, dom=None, args=None): Model = request.env[self.model].with_user(uid) # Allow to current_website_id directly in route domain