[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>
This commit is contained in:
@@ -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):
|
||||
|
||||
@@ -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))
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user