[IMP] http.py: do not inject context by default in JSON routes

Before this revision, when you pass `context` in the arguments
of a JSON routes, this one gets automatically injected
in the environment context.

This is not the case for regular HTTP routes.

It makes sense to propagate the context for the JSONRPC protocol,
JSON routes used by the backend, such as `call_kw`,
but it doesn't make sense to pass this context automatically
for any other kind of routes, such as front-end routes
or routes used by custom Javascript widgets.

This change brings a more unified behavior for routes
of types HTTP and JSON.
In addition, most developers were not aware of this "feautre",
that passing `context` in the arguments of a JSON route leaded
to the injection of this context in the environment context.
This is actually reflected by the diff size this changes required,
only a dozens of routes needed to be adapted, to manually
add the context in their route arguments and to inject it
in their environment context.

closes odoo/odoo#121726

X-original-commit: a7a5655631e6d5b05fd2ba3d0c80617aae6d9cfe
Related: odoo/enterprise#41229
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This commit is contained in:
Denis Ledoux
2023-05-22 11:43:04 +02:00
parent ea3008cc49
commit 58ea5e7b43
10 changed files with 48 additions and 20 deletions
+10 -2
View File
@@ -5,11 +5,15 @@ from odoo.http import request
class OnboardingController(http.Controller):
@http.route('/account/account_invoice_onboarding', auth='user', type='json')
def account_invoice_onboarding(self):
def account_invoice_onboarding(self, context=None):
""" Returns the `banner` for the account invoice onboarding panel.
It can be empty if the user has closed it or if he doesn't have
the permission to see it. """
# Forward `allowed_company_ids` in the context
# so `request.env.company` returns the company selected in the dropdown
if context:
request.update_context(**context)
company = request.env.company
if not request.env.is_admin() or \
company.account_invoice_onboarding_state == 'closed':
@@ -23,10 +27,14 @@ class OnboardingController(http.Controller):
}
@http.route('/account/account_dashboard_onboarding', auth='user', type='json')
def account_dashboard_onboarding(self):
def account_dashboard_onboarding(self, context=None):
""" Returns the `banner` for the account dashboard onboarding panel.
It can be empty if the user has closed it or if he doesn't have
the permission to see it. """
# Forward `allowed_company_ids` in the context
# so `request.env.company` returns the company selected in the dropdown
if context:
request.update_context(**context)
company = request.env.company
if not request.env.is_admin() or \
-1
View File
@@ -109,7 +109,6 @@ class TestTOTP(HttpCase):
"db": get_db_name(),
"login": "demo",
"password": "demo",
"context": {},
},
}
response = self.url_open("/web/session/authenticate", data=json.dumps(payload), headers=headers)
+15 -5
View File
@@ -10,7 +10,9 @@ from odoo.tools import float_round, float_repr
class LunchController(http.Controller):
@http.route('/lunch/infos', type='json', auth='user')
def infos(self, user_id=None):
def infos(self, user_id=None, context=None):
if context:
request.update_context(**context)
self._check_user_impersonification(user_id)
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
@@ -36,7 +38,9 @@ class LunchController(http.Controller):
return infos
@http.route('/lunch/trash', type='json', auth='user')
def trash(self, user_id=None):
def trash(self, user_id=None, context=None):
if context:
request.update_context(**context)
self._check_user_impersonification(user_id)
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
@@ -46,7 +50,9 @@ class LunchController(http.Controller):
lines.unlink()
@http.route('/lunch/pay', type='json', auth='user')
def pay(self, user_id=None):
def pay(self, user_id=None, context=None):
if context:
request.update_context(**context)
self._check_user_impersonification(user_id)
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
@@ -64,7 +70,9 @@ class LunchController(http.Controller):
return {'message': request.env['ir.qweb']._render('lunch.lunch_payment_dialog', {})}
@http.route('/lunch/user_location_set', type='json', auth='user')
def set_user_location(self, location_id=None, user_id=None):
def set_user_location(self, location_id=None, user_id=None, context=None):
if context:
request.update_context(**context)
self._check_user_impersonification(user_id)
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
@@ -72,7 +80,9 @@ class LunchController(http.Controller):
return True
@http.route('/lunch/user_location_get', type='json', auth='user')
def get_user_location(self, user_id=None):
def get_user_location(self, user_id=None, context=None):
if context:
request.update_context(**context)
self._check_user_impersonification(user_id)
user = request.env['res.users'].browse(user_id) if user_id else request.env.user
+3 -1
View File
@@ -61,7 +61,9 @@ class ThreadController(http.Controller):
return {"attachment_ids", "body", "message_type", "partner_ids", "subtype_xmlid", "parent_id"}
@http.route("/mail/message/post", methods=["POST"], type="json", auth="public")
def mail_message_post(self, thread_model, thread_id, post_data):
def mail_message_post(self, thread_model, thread_id, post_data, context=None):
if context:
request.update_context(**context)
thread = request.env[thread_model]._get_from_request_or_raise(request, int(thread_id))
if "body" in post_data:
post_data["body"] = Markup(post_data["body"]) # contains HTML such as @mentions
+3 -1
View File
@@ -9,10 +9,12 @@ from odoo.http import request
class OnboardingController(http.Controller):
@http.route('/onboarding/<string:route_name>', auth='user', type='json')
def get_onboarding_data(self, route_name=None):
def get_onboarding_data(self, route_name=None, context=None):
if not request.env.user.has_group('base.group_system'):
return {}
if context:
request.update_context(**context)
onboarding = request.env['onboarding.onboarding'].search([('route_name', '=', route_name)])
if onboarding:
try:
+5 -1
View File
@@ -6,11 +6,15 @@ from odoo.http import request, route, Controller
class OnboardingController(Controller):
@route('/sales/sale_quotation_onboarding_panel', auth='user', type='json')
def sale_quotation_onboarding(self):
def sale_quotation_onboarding(self, context=None):
""" Returns the `banner` for the sale onboarding panel.
It can be empty if the user has closed it or if he doesn't have
the permission to see it. """
# Forward `allowed_company_ids` in the context
# so `request.env.company` returns the company selected in the dropdown
if context:
request.update_context(**context)
company = request.env.company
if not request.env.is_admin() or \
company.sale_quotation_onboarding_state == 'closed':
+3 -1
View File
@@ -39,7 +39,9 @@ class Action(Controller):
return value
@route('/web/action/run', type='json', auth="user")
def run(self, action_id):
def run(self, action_id, context=None):
if context:
request.update_context(**context)
action = request.env['ir.actions.server'].browse([action_id])
result = action.run()
return clean_action(result, env=action.env) if result else False
+6 -2
View File
@@ -16,7 +16,9 @@ _logger = logging.getLogger(__name__)
class DataSet(http.Controller):
@http.route('/web/dataset/search_read', type='json', auth="user")
def search_read(self, model, fields=False, offset=0, limit=False, domain=None, sort=None):
def search_read(self, model, fields=False, offset=0, limit=False, domain=None, sort=None, context=None):
if context:
request.update_context(**context)
return request.env[model].web_search_read(domain, fields, offset=offset, limit=limit, order=sort)
def _call_kw(self, model, method, args, kwargs):
@@ -35,7 +37,7 @@ class DataSet(http.Controller):
return False
@http.route('/web/dataset/resequence', type='json', auth="user")
def resequence(self, model, ids, field='sequence', offset=0):
def resequence(self, model, ids, field='sequence', offset=0, context=None):
""" Re-sequences a number of records in the model, by their ids
The re-sequencing starts at the first model of ``ids``, the sequence
@@ -49,6 +51,8 @@ class DataSet(http.Controller):
starting the resequencing from an arbitrary number,
defaults to ``0``
"""
if context:
request.update_context(**context)
m = request.env[model]
if not m.fields_get([field]):
return False
@@ -171,5 +171,5 @@ class TestHttpEchoReplyJsonWithDB(TestHttpBase):
res = self.db_url_open("/test_http/echo-json-context", data=payload, headers=CT_JSON)
self.assertEqual(res.status_code, 200)
self.assertEqual(res.text, '{"jsonrpc": "2.0", "id": 0, "result": '
f'{{"lang": "en_US", "tz": false, "uid": {self.jackoneill.id}, "name": "Thor"}}'
f'{{"lang": "en_US", "tz": false, "uid": {self.jackoneill.id}}}'
'}')
+2 -5
View File
@@ -1897,13 +1897,13 @@ class JsonRPCDispatcher(Dispatcher):
Successful request::
--> {"jsonrpc": "2.0", "method": "call", "params": {"context": {}, "arg1": "val1" }, "id": null}
--> {"jsonrpc": "2.0", "method": "call", "params": {"arg1": "val1" }, "id": null}
<-- {"jsonrpc": "2.0", "result": { "res1": "val1" }, "id": null}
Request producing a error::
--> {"jsonrpc": "2.0", "method": "call", "params": {"context": {}, "arg1": "val1" }, "id": null}
--> {"jsonrpc": "2.0", "method": "call", "params": {"arg1": "val1" }, "id": null}
<-- {"jsonrpc": "2.0", "error": {"code": 1, "message": "End user error message.", "data": {"code": "codestring", "debug": "traceback" } }, "id": null}
@@ -1914,9 +1914,6 @@ class JsonRPCDispatcher(Dispatcher):
raise BadRequest("Invalid JSON data") from exc
self.request.params = dict(self.jsonrequest.get('params', {}), **args)
ctx = self.request.params.pop('context', None)
if ctx is not None and self.request.db:
self.request.update_context(**ctx)
if self.request.db:
result = self.request.registry['ir.http']._dispatch(endpoint)