mirror of
https://github.com/OCA/server-backend.git
synced 2025-02-18 09:52:42 +02:00
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).
101 lines
3.4 KiB
Python
101 lines
3.4 KiB
Python
# Copyright 2014 ABF OSIELL <http://osiell.com>
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
from odoo import api, fields, models
|
|
|
|
|
|
class ResUsers(models.Model):
|
|
_inherit = "res.users"
|
|
|
|
role_line_ids = fields.One2many(
|
|
comodel_name="res.users.role.line",
|
|
inverse_name="user_id",
|
|
string="Role lines",
|
|
default=lambda self: self._default_role_lines(),
|
|
)
|
|
role_ids = fields.One2many(
|
|
comodel_name="res.users.role",
|
|
string="Roles",
|
|
compute="_compute_role_ids",
|
|
)
|
|
|
|
@api.model
|
|
def _default_role_lines(self):
|
|
default_user = self.env.ref(
|
|
'base.default_user', raise_if_not_found=False).sudo()
|
|
default_values = []
|
|
if default_user:
|
|
for role_line in default_user.role_line_ids:
|
|
default_values.append(
|
|
{
|
|
"role_id": role_line.role_id.id,
|
|
"date_from": role_line.date_from,
|
|
"date_to": role_line.date_to,
|
|
"is_enabled": role_line.is_enabled,
|
|
}
|
|
)
|
|
return default_values
|
|
|
|
@api.multi
|
|
@api.depends("role_line_ids.role_id")
|
|
def _compute_role_ids(self):
|
|
for user in self:
|
|
user.role_ids = user.role_line_ids.mapped("role_id")
|
|
|
|
@api.model
|
|
def create(self, vals):
|
|
new_record = super(ResUsers, self).create(vals)
|
|
new_record.set_groups_from_roles()
|
|
return new_record
|
|
|
|
@api.multi
|
|
def write(self, vals):
|
|
res = super(ResUsers, self).write(vals)
|
|
self.sudo().set_groups_from_roles()
|
|
return res
|
|
|
|
def _get_applicable_roles(self):
|
|
return self.role_line_ids.filtered(
|
|
lambda rec: rec.is_enabled
|
|
and (
|
|
not rec.company_id or rec.company_id == rec.user_id.company_id
|
|
)
|
|
)
|
|
|
|
@api.multi
|
|
def set_groups_from_roles(self, force=False):
|
|
"""Set (replace) the groups following the roles defined on users.
|
|
If no role is defined on the user, its groups are let untouched unless
|
|
the `force` parameter is `True`.
|
|
"""
|
|
role_groups = {}
|
|
# We obtain all the groups associated to each role first, so that
|
|
# it is faster to compare later with each user's groups.
|
|
for role in self.mapped("role_line_ids.role_id"):
|
|
role_groups[role] = list(
|
|
set(
|
|
role.group_id.ids
|
|
+ role.implied_ids.ids
|
|
+ role.trans_implied_ids.ids
|
|
)
|
|
)
|
|
for user in self:
|
|
if not user.role_line_ids and not force:
|
|
continue
|
|
group_ids = []
|
|
for role_line in user._get_applicable_roles():
|
|
role = role_line.role_id
|
|
if role:
|
|
group_ids += role_groups[role]
|
|
group_ids = list(set(group_ids)) # Remove duplicates IDs
|
|
groups_to_add = list(set(group_ids) - set(user.groups_id.ids))
|
|
groups_to_remove = list(set(user.groups_id.ids) - set(group_ids))
|
|
to_add = [(4, gr) for gr in groups_to_add]
|
|
to_remove = [(3, gr) for gr in groups_to_remove]
|
|
groups = to_remove + to_add
|
|
if groups:
|
|
vals = {
|
|
"groups_id": groups,
|
|
}
|
|
super(ResUsers, user).write(vals)
|
|
return True
|