Public release from ruodoo-project: 19.0 - 2026-05-31 21:19:12 UTC
This commit is contained in:
3
access_restricted/models/__init__.py
Normal file
3
access_restricted/models/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from . import res_config_settings
|
||||
from . import res_users
|
||||
from . import test_config_settings
|
||||
71
access_restricted/models/res_config_settings.py
Normal file
71
access_restricted/models/res_config_settings.py
Normal file
@ -0,0 +1,71 @@
|
||||
from odoo import SUPERUSER_ID, api, models
|
||||
from odoo.tools import ustr
|
||||
from odoo.tools.translate import _
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
@api.model
|
||||
def _get_classified_fields(self, fnames=None):
|
||||
uid = self.env.uid
|
||||
classified = super()._get_classified_fields(fnames)
|
||||
config = self.env.context.get("config")
|
||||
is_execute_stage = config and isinstance(config, models.Model)
|
||||
|
||||
if uid == SUPERUSER_ID or is_execute_stage:
|
||||
return classified
|
||||
|
||||
group = []
|
||||
user = self.env.user
|
||||
|
||||
for name, groups, implied_group in classified["group"]:
|
||||
if (
|
||||
implied_group in user.group_ids
|
||||
or user.has_group(
|
||||
"access_restricted.group_allow_add_implied_from_settings"
|
||||
)
|
||||
):
|
||||
group.append((name, groups, implied_group))
|
||||
|
||||
classified["group"] = group
|
||||
return classified
|
||||
|
||||
@api.model
|
||||
def fields_get(self, allfields=None, **kwargs):
|
||||
uid = self.env.uid
|
||||
fields = super().fields_get(allfields, **kwargs)
|
||||
|
||||
if uid == SUPERUSER_ID:
|
||||
return fields
|
||||
|
||||
user = self.env.user
|
||||
|
||||
for name in fields:
|
||||
if not name.startswith("group_"):
|
||||
continue
|
||||
|
||||
f = self._fields[name]
|
||||
|
||||
if (
|
||||
f.implied_group in user.group_ids
|
||||
or user.has_group(
|
||||
"access_restricted.group_allow_add_implied_from_settings"
|
||||
)
|
||||
):
|
||||
continue
|
||||
|
||||
fields[name].update(
|
||||
readonly=True,
|
||||
help=ustr(fields[name].get("help", ""))
|
||||
+ _(
|
||||
"\n\nYou don't have access to change this settings, because your administration rights are restricted"
|
||||
),
|
||||
)
|
||||
|
||||
return fields
|
||||
|
||||
def execute(self):
|
||||
return super(
|
||||
ResConfigSettings, self.with_context({"config": self})
|
||||
).execute()
|
||||
112
access_restricted/models/res_users.py
Normal file
112
access_restricted/models/res_users.py
Normal file
@ -0,0 +1,112 @@
|
||||
from odoo import SUPERUSER_ID, _, api, models
|
||||
from odoo.exceptions import AccessError
|
||||
|
||||
IR_CONFIG_NAME = "access_restricted.fields_view_get_uid"
|
||||
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = "res.users"
|
||||
|
||||
@api.model
|
||||
def get_views(self, views, options=None):
|
||||
last_uid = self.env["ir.config_parameter"].sudo().get_param(IR_CONFIG_NAME)
|
||||
if int(last_uid) != self.env.uid:
|
||||
self.env["res.groups"]._update_user_groups_view()
|
||||
return super().get_views(views, options)
|
||||
|
||||
def write(self, vals):
|
||||
if 'groups_id' in vals:
|
||||
self.env["ir.config_parameter"].sudo().set_param(IR_CONFIG_NAME, "0")
|
||||
return super().write(vals)
|
||||
|
||||
|
||||
class ResGroups(models.Model):
|
||||
_inherit = "res.groups"
|
||||
|
||||
@api.model
|
||||
def _update_user_groups_view(self):
|
||||
real_uid = self.env.uid
|
||||
self.env["ir.config_parameter"].sudo().set_param(IR_CONFIG_NAME, real_uid)
|
||||
self.env.flush_all()
|
||||
|
||||
@api.model
|
||||
def get_application_groups(self, domain=None):
|
||||
if domain is None:
|
||||
domain = []
|
||||
domain.append(("share", "=", False))
|
||||
|
||||
real_uid = int(
|
||||
self.env["ir.config_parameter"].sudo().get_param(IR_CONFIG_NAME, "0")
|
||||
)
|
||||
if real_uid and real_uid != SUPERUSER_ID:
|
||||
group_no_one_id = self.env.ref("base.group_no_one").id
|
||||
domain = domain + [
|
||||
"|",
|
||||
("user_ids", "in", [real_uid]),
|
||||
("id", "=", group_no_one_id),
|
||||
]
|
||||
return self.sudo().search(domain)
|
||||
|
||||
def write(self, vals):
|
||||
config = self.env.context.get("config")
|
||||
|
||||
# `isinstance` check is a non-xmplrpc proof.
|
||||
if config and isinstance(config, models.Model):
|
||||
implied_ids = vals.get("implied_ids")
|
||||
classified_group = config._get_classified_fields()["group"]
|
||||
# when `res.config.settings`'s `execute` method writes the `users` field to group,
|
||||
# it is always to remove users and the `users` field is the only key in the write dict
|
||||
users = vals.get("user_ids")
|
||||
implied_group = implied_ids and implied_ids[0][1]
|
||||
users_exclude_operation = (
|
||||
users and len(vals) == 1 and all(u[0] == 3 for u in users)
|
||||
)
|
||||
# ``all(u[0] == 3 for u in users)`` is to be sure that all operations are for removing.
|
||||
# `(3, id)` tuple removes the record from the set (the Many2many field `users`)
|
||||
add_implied_group_operation = implied_group in [
|
||||
group[2].id for group in classified_group
|
||||
]
|
||||
curr_user_allowed = self.env.user._is_superuser() or self.env.user.has_group(
|
||||
"access_restricted.group_allow_add_implied_from_settings"
|
||||
)
|
||||
if (
|
||||
users_exclude_operation
|
||||
or add_implied_group_operation
|
||||
and curr_user_allowed
|
||||
):
|
||||
self = self.with_user(SUPERUSER_ID)
|
||||
else:
|
||||
# do nothing with groups if there is no permission to add from settings
|
||||
return
|
||||
|
||||
# in the https://github.com/odoo/odoo/commit/5f12e244f6e57b8edb56788147774150e2ae134d commit
|
||||
# the method was refactored due to a higher performance.
|
||||
# Super method lacks of orm part so as consequent ir rules are not checked and we check its conditions manually.
|
||||
# We apply super method and check the difference of implied groups,
|
||||
# if the not proper group was set error is raised
|
||||
check_for_implied_ids = (
|
||||
"implied_ids" in vals
|
||||
and vals["implied_ids"]
|
||||
and self.env.user.id != SUPERUSER_ID
|
||||
)
|
||||
if check_for_implied_ids:
|
||||
implied_ids_before = self.mapped("implied_ids")
|
||||
groups_before = self.env.user.group_ids
|
||||
|
||||
result = super(ResGroups, self).write(vals)
|
||||
|
||||
if check_for_implied_ids:
|
||||
implied_ids_after = self.mapped("implied_ids")
|
||||
group_no_one = self.env.ref("base.group_no_one")
|
||||
implied_group_ids = implied_ids_after - implied_ids_before - group_no_one
|
||||
|
||||
# R1 <= R2 True if all records of R1 are also in R2
|
||||
if not implied_group_ids <= groups_before:
|
||||
raise AccessError(
|
||||
_(
|
||||
"You cannot add groups to Implied groups, because you are not allowed to increase your rights. "
|
||||
"Please contact your system administrator."
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
13
access_restricted/models/test_config_settings.py
Normal file
13
access_restricted/models/test_config_settings.py
Normal file
@ -0,0 +1,13 @@
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class TestConfigSettings(models.TransientModel):
|
||||
|
||||
_description = "Test config settings"
|
||||
_inherit = ["res.config.settings"]
|
||||
|
||||
group_test_access_restricted = fields.Boolean(
|
||||
group="base.group_system",
|
||||
# random group for test purposes
|
||||
implied_group="base.group_multi_currency",
|
||||
)
|
||||
Reference in New Issue
Block a user