Files
odoo_source/addons/http_routing/models/ir_qweb.py
T
Julien Castiaux 3c174802f8 [FIX] http_routing: be loose on request.is_frontend
Steps to reproduce, on SaaS only, not reproductible in standard:

1. Start a new SaaS Trial on saas-16.3
2. Install helpdesk, setup an incoming mail server
3. Send an email, one that should create a new helpdesk ticket
4. Traceback, request has not 'is_frontend` attribute.

This commit doesn't solve the root issue, it only makes it possible to
use helpdesk again. Using getattr/hasattr to access request.is_frontend
SHOULD NOT be necessary since [HTTPocalypse] BUT there are some rogue
controllers that bypass the normal flow of execution and fail to meet
the expectations of the new http stack.

This commit only makes the code robust to a missing attribute in this
very case as this is a recurring problem (unusable helpdesk). The root
problem is unlikely to be located nor in http_routing, nor in helpdesk.

THIS SOLUTIONS OF USING `getattr`/`hasattr` TO ACCESS `is_frontend` MUST
NOT BE REPLICATED ELSEWHERE WITHOUT PRIOR CONSULTATION WITH PEOPLE IN
CHARGE.

[HTTPocalypse]: https://github.com/odoo/odoo#78857
See-also: https://github.com/odoo/odoo/pull/99667
See-also: https://github.com/odoo/internal/pull/1902
opw-3359740
opw-3365843

closes odoo/odoo#126386

X-original-commit: c808719619167a582dd28420ff2979b57102d2ab
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
2023-06-26 22:15:13 +02:00

53 lines
1.8 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import models
from odoo.http import request
from odoo.addons.http_routing.models.ir_http import slug, unslug_url, url_for
_logger = logging.getLogger(__name__)
BAD_REQUEST = """Missing request.is_frontend attribute.
The request.is_frontend attribute is missing, this means that although
http_routing is installed and that all incoming requests SHOULD be
going through ir.http._match (which sets that attribute),
there are some rogue requests which do not. This is likely due to a
@route(auth='none') controller which creates its own registry and attempts
to render a template (e.g. odoo/odoo#99667).
The following expectations MUST hold:
When:
* there is an incoming http request (request is truthy)
* there is a registry loaded (models are in use)
* http_routing is installed (dependency of both portal and website)
Then:
* request.is_frontend is set
Failure to meet this expectation can lead to downstream problems, e.g.
here inside of http_routing's ir.qweb. Solutions vary, the one used
inside of #99667 is to use the request.borrow_request context manager to
temporary hide the incoming http request.
"""
class IrQweb(models.AbstractModel):
_inherit = "ir.qweb"
def _prepare_environment(self, values):
irQweb = super()._prepare_environment(values)
values['slug'] = slug
values['unslug_url'] = unslug_url
if not irQweb.env.context.get('minimal_qcontext') and request:
if not hasattr(request, 'is_frontend'):
_logger.warning(BAD_REQUEST, stack_info=True)
elif request.is_frontend:
return irQweb._prepare_frontend_environment(values)
return irQweb
def _prepare_frontend_environment(self, values):
values['url_for'] = url_for
return self