[FIX] base_user_role: default user multi-company

When creating user, default roles are using `base.default_user`, which
in multi-company case, can be from different company than user is being
created for. If thats the case, user creating another user, will get
access error, when trying to read default template user.

To work around that, we use sudo, to make sure, template user data can
be read regardless of a company.

Also improved the way base_user_role tests are run. Changed base test
class from TransactionCase to SavepointCase.

From how tests are ran perspective, both classes behave the same: each
test uses set up which is roll backed after.

But the difference is that SavepointCase case is much faster, because
it calls setUpClass once and saves this case for all tests (reusing
saved state).
This commit is contained in:
Andrius Laukavičius
2020-02-25 15:22:03 +02:00
parent c414dbd0cd
commit 115aba15df
4 changed files with 77 additions and 57 deletions

View File

@@ -21,8 +21,7 @@ class ResUsers(models.Model):
@api.model
def _default_role_lines(self):
default_user = self.env.ref(
"base.default_user", raise_if_not_found=False
)
'base.default_user', raise_if_not_found=False).sudo()
default_values = []
if default_user:
for role_line in default_user.role_line_ids:

View File

@@ -3,5 +3,6 @@
* Jean-Charles Drubay <jc@komit-consulting.com> (https://komit-consulting.com)
* Pierrick Brun <pierrick.brun@akretion.com>
* Kevin Khao <kevin.khao@akretion.com>
* Andrius Laukavičius <andrius@focusate.eu> (http://focusate.eu)
Do not contact contributors directly about support or help with technical issues.

View File

@@ -3,60 +3,53 @@
import datetime
from odoo import fields
from odoo.tests.common import TransactionCase
from odoo.tests.common import SavepointCase
class TestUserRole(TransactionCase):
def setUp(self):
super(TestUserRole, self).setUp()
self.user_model = self.env["res.users"]
self.role_model = self.env["res.users.role"]
class TestUserRole(SavepointCase):
self.default_user = self.env.ref("base.default_user")
self.user_id = self.user_model.create(
{"name": "USER TEST (ROLES)", "login": "user_test_roles"}
)
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.user_model = cls.env['res.users']
cls.role_model = cls.env['res.users.role']
cls.user_admin = cls.env.ref('base.user_admin')
cls.default_user = cls.env.ref('base.default_user')
cls.user_id = cls.user_model.create(
{'name': "USER TEST (ROLES)", 'login': 'user_test_roles'})
# ROLE_1
self.group_user_id = self.env.ref("base.group_user")
self.group_no_one_id = self.env.ref("base.group_no_one")
cls.group_user_id = cls.env.ref('base.group_user')
cls.group_no_one_id = cls.env.ref('base.group_no_one')
vals = {
"name": "ROLE_1",
"implied_ids": [
(6, 0, [self.group_user_id.id, self.group_no_one_id.id])
],
'name': "ROLE_1",
'implied_ids': [
(6, 0, [cls.group_user_id.id, cls.group_no_one_id.id])],
}
self.role1_id = self.role_model.create(vals)
cls.role1_id = cls.role_model.create(vals)
# ROLE_2
# Must have group_user in order to have sufficient groups. Check:
# github.com/odoo/odoo/commit/c3717f3018ce0571aa41f70da4262cc946d883b4
self.group_multi_currency_id = self.env.ref(
"base.group_multi_currency"
)
self.group_settings_id = self.env.ref("base.group_system")
cls.group_multi_currency_id = cls.env.ref(
'base.group_multi_currency')
cls.group_settings_id = cls.env.ref('base.group_system')
vals = {
"name": "ROLE_2",
"implied_ids": [
(
6,
0,
[
self.group_user_id.id,
self.group_multi_currency_id.id,
self.group_settings_id.id,
],
)
],
'name': "ROLE_2",
'implied_ids': [
(6, 0, [cls.group_user_id.id,
cls.group_multi_currency_id.id,
cls.group_settings_id.id])],
}
self.role2_id = self.role_model.create(vals)
self.company1 = self.env.ref("base.main_company")
self.company2 = self.env["res.company"].create({"name": "company2"})
self.user_id.write(
cls.role2_id = cls.role_model.create(vals)
cls.company1 = cls.env.ref("base.main_company")
cls.company2 = cls.env["res.company"].create({"name": "company2"})
cls.user_id.write(
{
"company_ids": [
(4, self.company1.id, 0),
(4, self.company2.id, 0),
(4, cls.company1.id, 0),
(4, cls.company2.id, 0),
]
}
)
@@ -197,20 +190,47 @@ class TestUserRole(TransactionCase):
self.assertFalse(role2_groups <= self.user_id.groups_id)
def test_default_user_roles(self):
self.default_user.write(
{
"role_line_ids": [
(0, 0, {"role_id": self.role1_id.id}),
(0, 0, {"role_id": self.role2_id.id}),
]
}
)
user = self.user_model.create(
{
"name": "USER TEST (DEFAULT ROLES)",
"login": "user_test_default_roles",
}
)
self.default_user.write({
'role_line_ids': [
(0, 0, {
'role_id': self.role1_id.id,
}),
(0, 0, {
'role_id': self.role2_id.id,
})
]
})
# Using normal user instead of superuser, to make sure access
# rights are not preventing from creating user.
user = self.user_model.sudo(self.user_admin).create({
'name': "USER TEST (DEFAULT ROLES)",
'login': 'user_test_default_roles'
})
roles = self.role_model.browse([self.role1_id.id, self.role2_id.id])
self.assertEqual(user.role_ids, roles)
def test_default_user_roles_multicompany(self):
"""Get default roles when template user is from other company."""
company_2 = self.env['res.company'].create({'name': 'New Company'})
company_2_id = company_2.id
self.user_admin.write({
'company_ids': [(4, company_2_id)],
'company_id': company_2_id
})
self.default_user.write({
'role_line_ids': [
(0, 0, {
'role_id': self.role1_id.id,
}),
(0, 0, {
'role_id': self.role2_id.id,
})
]
})
user = self.user_model.sudo(self.user_admin).create({
'name': "USER TEST (DEFAULT ROLES)",
'login': 'user_test_default_roles'
})
roles = self.role_model.browse([self.role1_id.id, self.role2_id.id])
self.assertEqual(user.role_ids, roles)