diff options
| author | Nicolas Lempereur <nle@odoo.com> | 2019-12-27 16:34:37 +0000 |
|---|---|---|
| committer | Nicolas Lempereur <nle@odoo.com> | 2020-01-15 16:19:03 +0000 |
| commit | b2392011900825bbc0d4d5e2456cd669595e2565 (patch) | |
| tree | dfdb7ffc2443b9fe22c5cedcdb4880f0745d05fe | |
| parent | 4a1dfb50b7cbcd08a46c6b37f4ad2b4c4bf37e6e (diff) | |
[FIX] *: avoid muting res.users().context_get return
Some code modify return of res.users().context_get, but this is a
cached method so this will unexpectedly affects totally unrelated code.
For example, changing the company with the company switcher could add
`allowed_company_ids` inside the cache, then it will be cached until the
server is restarted, even if we change company again inbetween.
Added test failed with:
"NotImplementedError: '__setitem__' not supported on frozendict"
on the line with `User = User.with_context(context)` where User already
contained `allowed_company_ids` in its context.
note:
in this forward-port, context_get is also changed to return frozendict
and prevent being able to have an unexpected issue by code that modify
context_get returns.
opw-2158340
closes #42465
closes odoo/odoo#42723
X-original-commit: 5d69885c1cd6921b3de00aae7e0ed6fff243ff95
Signed-off-by: Nicolas Lempereur (nle) <nle@odoo.com>
| -rw-r--r-- | odoo/addons/base/models/res_users.py | 6 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/tests/test_company_checks.py | 24 | ||||
| -rw-r--r-- | odoo/http.py | 2 | ||||
| -rw-r--r-- | odoo/tests/common.py | 2 |
4 files changed, 29 insertions, 5 deletions
diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py index 0eefb630525..718a62c12aa 100644 --- a/odoo/addons/base/models/res_users.py +++ b/odoo/addons/base/models/res_users.py @@ -21,7 +21,7 @@ from odoo.exceptions import AccessDenied, AccessError, UserError, ValidationErro from odoo.http import request from odoo.osv import expression from odoo.service.db import check_super -from odoo.tools import partition, collections, lazy_property +from odoo.tools import partition, collections, frozendict, lazy_property _logger = logging.getLogger(__name__) @@ -577,10 +577,10 @@ class Users(models.Model): # use read() to not read other fields: this must work while modifying # the schema of models res.users or res.partner values = user.read(list(name_to_key), load=False)[0] - return { + return frozendict({ key: values[name] for name, key in name_to_key.items() - } + }) @api.model def action_get(self): diff --git a/odoo/addons/test_new_api/tests/test_company_checks.py b/odoo/addons/test_new_api/tests/test_company_checks.py index 04b1df46846..5b391a3578f 100644 --- a/odoo/addons/test_new_api/tests/test_company_checks.py +++ b/odoo/addons/test_new_api/tests/test_company_checks.py @@ -2,6 +2,7 @@ from odoo.exceptions import UserError, AccessError from odoo.tests import common +from odoo.tools import frozendict class TestCompanyCheck(common.TransactionCase): @@ -192,3 +193,26 @@ class TestCompanyCheck(common.TransactionCase): with self.assertRaises(AccessError): form.address_id.name form.save() + + def test_company_sticky_with_context(self): + context = frozendict({'nothing_to_see_here': True}) + companies_1 = frozendict({'allowed_company_ids': [1]}) + companies_2 = frozendict({'allowed_company_ids': [2]}) + + User = self.env['res.users'].with_context(context) + self.assertEqual(User.env.context, context) + + User = User.with_context(**companies_1) + self.assertEqual(User.env.context, dict(context, **companies_1)) + + # 'allowed_company_ids' is replaced if present in keys + User = User.with_context(**companies_2) + self.assertEqual(User.env.context, dict(context, **companies_2)) + + # 'allowed_company_ids' is replaced if present in new context + User = User.with_context(companies_1) + self.assertEqual(User.env.context, companies_1) + + # 'allowed_company_ids' is sticky + User = User.with_context(context) + self.assertEqual(User.env.context, dict(context, **companies_1)) diff --git a/odoo/http.py b/odoo/http.py index 222a2eeabb4..9962f8a47b1 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -1062,7 +1062,7 @@ class OpenERPSession(werkzeug.contrib.sessions.Session): :returns: the new context """ assert self.uid, "The user needs to be logged-in to initialize his context" - self.context = request.env['res.users'].context_get() or {} + self.context = dict(request.env['res.users'].context_get() or {}) self.context['uid'] = self.uid self._fix_lang(self.context) return self.context diff --git a/odoo/tests/common.py b/odoo/tests/common.py index f6eec4d2a9a..3539e067d97 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -1133,7 +1133,7 @@ class HttpCase(TransactionCase): session.uid = uid session.login = user session.session_token = uid and security.compute_session_token(session, env) - session.context = env['res.users'].context_get() or {} + session.context = dict(env['res.users'].context_get() or {}) session.context['uid'] = uid session._fix_lang(session.context) |
