Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REF][IMP] Access Rules for Variables and Values with Tests #166

Closed
wants to merge 10 commits into from
831 changes: 412 additions & 419 deletions cetmix_tower_server/README.rst

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions cetmix_tower_server/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright Cetmix OU
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Cetmix Tower Server Management",
"summary": "Flexible Server Management directly from Odoo",
Expand All @@ -23,6 +24,7 @@
"security/cx_tower_server_security.xml",
"security/cx_tower_command_security.xml",
"security/cx_tower_variable_value_security.xml",
"security/cx_tower_variable_security.xml",
"security/cx_tower_plan_security.xml",
"security/cx_tower_plan_line_security.xml",
"security/cx_tower_plan_line_action_security.xml",
Expand Down
14 changes: 7 additions & 7 deletions cetmix_tower_server/models/cx_tower_access_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ class CxTowerAccessMixin(models.AbstractModel):
_name = "cx.tower.access.mixin"
_description = "Cetmix Tower access mixin"

access_level = fields.Selection(
tendil marked this conversation as resolved.
Show resolved Hide resolved
lambda self: self._selection_access_level(),
string="Access Level",
default=lambda self: self._default_access_level(),
required=True,
)

def _selection_access_level(self):
"""Available access levels

Expand All @@ -31,10 +38,3 @@ def _default_access_level(self):
Char: `access_level` field selection value
"""
return "2"

access_level = fields.Selection(
lambda self: self._selection_access_level(),
string="Access Level",
default=lambda self: self._default_access_level(),
required=True,
)
2 changes: 1 addition & 1 deletion cetmix_tower_server/models/cx_tower_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class TowerVariable(models.Model):
_name = "cx.tower.variable"
_description = "Cetmix Tower Variable"
_inherit = ["cx.tower.reference.mixin"]
_inherit = ["cx.tower.reference.mixin", "cx.tower.access.mixin"]

_order = "name"

Expand Down
68 changes: 68 additions & 0 deletions cetmix_tower_server/models/cx_tower_variable_value.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class TowerVariableValue(models.Model):
_description = "Cetmix Tower Variable Values"
_inherit = [
"cx.tower.reference.mixin",
"cx.tower.access.mixin",
]
_rec_name = "variable_reference"
_order = "variable_reference"
Expand Down Expand Up @@ -144,6 +145,15 @@ def _onchange_variable_id(self):
else:
rec.option_id = None

@api.onchange("variable_id")
def _onchange_variable_id_set_access_level(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use "compute" with "readonly=False" instead of "onchange" wherever it's possible.

"""
Automatically set the `access_level` field based on the `variable_id`.
"""
for rec in self:
if rec.variable_id:
rec.access_level = rec.variable_id.access_level

@api.constrains("is_global", "value_char")
def _constraint_global_unique(self):
"""Ensure that there is only one global value exist for the same variable
Expand Down Expand Up @@ -180,6 +190,35 @@ def _compute_variable_ids(self):
["value_char"], force_record=record
)

@api.constrains("access_level", "variable_id")
def _check_access_level_consistency(self):
"""
Ensure that the access level of the variable value is not lower than
the access level of the associated variable.
"""
for rec in self:
if rec.variable_id and rec.access_level < rec.variable_id.access_level:
raise ValidationError(
_(
"The access level for Variable Value '%(value)s' cannot be"
"lower than the access level of its Variable '%(variable)s'.\n"
"Variable Access Level: %(var_level)s\n"
"Variable Value Access Level: %(val_level)s",
value=rec.value_char or "Undefined",
variable=rec.variable_id.name,
var_level=dict(
rec.fields_get(["access_level"])["access_level"][
"selection"
]
)[rec.variable_id.access_level],
val_level=dict(
rec.fields_get(["access_level"])["access_level"][
"selection"
]
)[rec.access_level],
)
)

def _inverse_value_char(self):
"""Set option_id based on value_char"""
for rec in self:
Expand All @@ -200,6 +239,35 @@ def _inverse_value_char(self):
)
)

@api.constrains("access_level", "variable_id")
def _check_access_level_consistency(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is the same function in L194, isn't it?

"""
Ensure that the access level of the variable value is not lower than
the access level of the associated variable.
"""
for rec in self:
if rec.variable_id and rec.access_level < rec.variable_id.access_level:
raise ValidationError(
_(
"The access level for Variable Value '%(value)s' cannot be"
"lower than the access level of its Variable '%(variable)s'.\n"
"Variable Access Level: %(var_level)s\n"
"Variable Value Access Level: %(val_level)s",
value=rec.value_char or "Undefined",
variable=rec.variable_id.name,
var_level=dict(
rec.fields_get(["access_level"])["access_level"][
"selection"
]
)[rec.variable_id.access_level],
val_level=dict(
rec.fields_get(["access_level"])["access_level"][
"selection"
]
)[rec.access_level],
)
)

def _used_in_models(self):
"""Returns information about models which use this mixin.

Expand Down
28 changes: 28 additions & 0 deletions cetmix_tower_server/security/cx_tower_variable_security.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>

<!-- user -->
<record id="cx_tower_variable_rule_group_user_access" model="ir.rule">
<field name="name">Tower Variable: User Access Rule</field>
<field name="model_id" ref="model_cx_tower_variable" />
<field name="domain_force">[('access_level', '=', '1')]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_user'))]" />
</record>

<!-- manager -->
<record id="cx_tower_variable_rule_group_manager_access" model="ir.rule">
<field name="name">Tower Variable: Manager Access Rule</field>
<field name="model_id" ref="model_cx_tower_variable" />
<field name="domain_force">[('access_level', '&lt;=', '2')]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
</record>

<!-- root -->
<record id="cx_tower_variable_rule_group_root_access" model="ir.rule">
<field name="name">Tower Variable: Root Access Rule</field>
<field name="model_id" ref="model_cx_tower_variable" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
</record>

</odoo>
62 changes: 39 additions & 23 deletions cetmix_tower_server/security/cx_tower_variable_value_security.xml
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>

<record
id="cx_tower_variable_value_rule_group_user_and_manager_access"
model="ir.rule"
>
<field name="name">Tower variable value: user and manager access rule</field>
<!-- user -->
<record id="cx_tower_variable_value_rule_group_user_access" model="ir.rule">
<field name="name">Tower Variable Value: User Access Rule</field>
<field name="model_id" ref="model_cx_tower_variable_value" />
<field name="domain_force">['|', ('is_global', '=', True),
('server_id.message_partner_ids', 'in', [user.partner_id.id])]</field>
<field
name="groups"
eval="[(4, ref('cetmix_tower_server.group_user')), (4, ref('cetmix_tower_server.group_manager'))]"
/>
<field name="domain_force">
[
('access_level', '=', '1'),
('server_id.message_partner_ids', 'in', [user.partner_id.id])
]
</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_user'))]" />
</record>

<!-- manager -->
<record id="cx_tower_variable_value_rule_group_manager_access" model="ir.rule">
<field name="name">Tower Variable Value: Manager Access Rule</field>
<field name="model_id" ref="model_cx_tower_variable_value" />
<field name="domain_force">
[
'|',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

('access_level', '&lt;=', '2'),
'|',
('is_global', '=', True),
('server_id.message_partner_ids', 'in', [user.partner_id.id])

('is_global', '=', True),
'&amp;',
('access_level', '&lt;=', '2'),
('server_id.message_partner_ids', 'in', [user.partner_id.id])
]
</field>
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_manager'))]" />
</record>

<record id="cx_tower_variable_value_action_rule_group_user_access" model="ir.rule">
<field
name="name"
>Tower variable value: user access to variable values in plan line action
rule</field>
>Tower variable Value: User Access to Variable Values in Plan Line Action
Rule</field>
<field name="model_id" ref="model_cx_tower_variable_value" />
<field name="domain_force">
[
Expand All @@ -40,8 +55,8 @@
>
<field
name="name"
>Tower variable value: manager access to variable values in plan line
action rule</field>
>Tower Variable Value: Manager Access to Variable Values in Plan Line
Action Rule</field>
<field name="model_id" ref="model_cx_tower_variable_value" />
<field name="domain_force">
[
Expand All @@ -62,8 +77,8 @@
>
<field
name="name"
>Tower variable value: manager delete own variable values in plan line
action</field>
>Tower Variable Value: Manager Delete own Variable Values in Plan Line
Action</field>
<field name="model_id" ref="model_cx_tower_variable_value" />
<field name="domain_force">
[
Expand All @@ -87,8 +102,8 @@
>
<field
name="name"
>Tower variable value: manager access to variable values in server
template rule</field>
>Tower Variable Value: Manager Access to Variable Values in Server
Template Rule</field>
<field name="model_id" ref="model_cx_tower_variable_value" />
<field name="domain_force">[
('server_template_id.message_partner_ids', 'in', [user.partner_id.id]),
Expand All @@ -103,8 +118,8 @@
>
<field
name="name"
>Tower variable value: manager delete own variable values in server
template rule</field>
>Tower Variable Value: Manager Delete own Variable Values in Server
Template Rule</field>
<field name="model_id" ref="model_cx_tower_variable_value" />
<field name="domain_force">
[
Expand All @@ -118,11 +133,12 @@
<field name="perm_write" eval="0" />
</record>

<!-- root -->
<record id="cx_tower_variable_value_rule_group_root_access" model="ir.rule">
<field name="name">Tower variable value: root access rule</field>
<field name="name">Tower Variable Value: Root Access Rule</field>
<field name="model_id" ref="model_cx_tower_variable_value" />
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4,ref('cetmix_tower_server.group_root'))]" />
<field name="groups" eval="[(4, ref('cetmix_tower_server.group_root'))]" />
</record>

</odoo>
Loading
Loading