[FIX] base_automation: access action fields using sudo
The user executing an action triggering an base automation may not have access to the base.automation record itself (regular employee or portal) Added test test_on_create_restricted failed before this patch as the portal does not have the rights to read the base.automation record Fixes odoo/odoo#59680 X-original-commit: 33a7142f298eeda7808d6d07e80231836442a0ce
This commit is contained in:
@@ -194,8 +194,9 @@ class BaseAutomation(models.Model):
|
||||
|
||||
def _filter_pre(self, records):
|
||||
""" Filter the records that satisfy the precondition of action ``self``. """
|
||||
if self.filter_pre_domain and records:
|
||||
domain = [('id', 'in', records.ids)] + safe_eval.safe_eval(self.filter_pre_domain, self._get_eval_context())
|
||||
self_sudo = self.sudo()
|
||||
if self_sudo.filter_pre_domain and records:
|
||||
domain = [('id', 'in', records.ids)] + safe_eval.safe_eval(self_sudo.filter_pre_domain, self._get_eval_context())
|
||||
return records.sudo().search(domain).with_env(records.env)
|
||||
else:
|
||||
return records
|
||||
@@ -205,8 +206,9 @@ class BaseAutomation(models.Model):
|
||||
|
||||
def _filter_post_export_domain(self, records):
|
||||
""" Filter the records that satisfy the postcondition of action ``self``. """
|
||||
if self.filter_domain and records:
|
||||
domain = [('id', 'in', records.ids)] + safe_eval.safe_eval(self.filter_domain, self._get_eval_context())
|
||||
self_sudo = self.sudo()
|
||||
if self_sudo.filter_domain and records:
|
||||
domain = [('id', 'in', records.ids)] + safe_eval.safe_eval(self_sudo.filter_domain, self._get_eval_context())
|
||||
return records.sudo().search(domain).with_env(records.env), domain
|
||||
else:
|
||||
return records, None
|
||||
@@ -262,7 +264,8 @@ class BaseAutomation(models.Model):
|
||||
|
||||
def _check_trigger_fields(self, record):
|
||||
""" Return whether any of the trigger fields has been modified on ``record``. """
|
||||
if not self.trigger_field_ids:
|
||||
self_sudo = self.sudo()
|
||||
if not self_sudo.trigger_field_ids:
|
||||
# all fields are implicit triggers
|
||||
return True
|
||||
|
||||
@@ -280,7 +283,7 @@ class BaseAutomation(models.Model):
|
||||
field.convert_to_cache(record[name], record, validate=False) !=
|
||||
field.convert_to_cache(old_vals[name], record, validate=False)
|
||||
)
|
||||
return any(differ(field.name) for field in self.trigger_field_ids)
|
||||
return any(differ(field.name) for field in self_sudo.trigger_field_ids)
|
||||
|
||||
def _register_hook(self):
|
||||
""" Patch models that should trigger action rules based on creation,
|
||||
@@ -389,7 +392,7 @@ class BaseAutomation(models.Model):
|
||||
def base_automation_onchange(self):
|
||||
action_rule = self.env['base.automation'].browse(action_rule_id)
|
||||
result = {}
|
||||
server_action = action_rule.action_server_id.with_context(active_model=self._name, onchange_self=self)
|
||||
server_action = action_rule.sudo().action_server_id.with_context(active_model=self._name, onchange_self=self)
|
||||
try:
|
||||
res = server_action.run()
|
||||
except Exception as e:
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from . import test_automation
|
||||
@@ -0,0 +1,90 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.tests import TransactionCase
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
import odoo.tests
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestAutomation(TransactionCase):
|
||||
|
||||
def test_01_on_create(self):
|
||||
""" Simple on_create with admin user """
|
||||
self.env["base.automation"].create({
|
||||
"name": "Force Archived Contacts",
|
||||
"trigger": "on_create_or_write",
|
||||
"model_id": self.env.ref("base.model_res_partner").id,
|
||||
"type": "ir.actions.server",
|
||||
"trigger_field_ids": [(6, 0, [self.env.ref("base.field_res_partner__name").id])],
|
||||
"fields_lines": [(0, 0, {
|
||||
"col1": self.env.ref("base.field_res_partner__active").id,
|
||||
"evaluation_type": "equation",
|
||||
"value": "False",
|
||||
})],
|
||||
})
|
||||
|
||||
# verify the partner can be created and the action still runs
|
||||
bilbo = self.env["res.partner"].create({"name": "Bilbo Baggins"})
|
||||
self.assertFalse(bilbo.active)
|
||||
|
||||
# verify the partner can be updated and the action still runs
|
||||
bilbo.active = True
|
||||
bilbo.name = "Bilbo"
|
||||
self.assertFalse(bilbo.active)
|
||||
|
||||
|
||||
def test_02_on_create_restricted(self):
|
||||
""" on_create action with low portal user """
|
||||
action = self.env["base.automation"].create({
|
||||
"name": "Force Archived Filters",
|
||||
"trigger": "on_create_or_write",
|
||||
"model_id": self.env.ref("base.model_ir_filters").id,
|
||||
"type": "ir.actions.server",
|
||||
"trigger_field_ids": [(6, 0, [self.env.ref("base.field_ir_filters__name").id])],
|
||||
"fields_lines": [(0, 0, {
|
||||
"col1": self.env.ref("base.field_ir_filters__active").id,
|
||||
"evaluation_type": "equation",
|
||||
"value": "False",
|
||||
})],
|
||||
})
|
||||
# action cached was cached with admin, force CacheMiss
|
||||
action.env.clear()
|
||||
|
||||
self_portal = self.env["ir.filters"].with_user(self.env.ref("base.user_demo").id)
|
||||
# verify the portal user can create ir.filters but can not read base.automation
|
||||
self.assertTrue(self_portal.env["ir.filters"].check_access_rights("create", raise_exception=False))
|
||||
self.assertFalse(self_portal.env["base.automation"].check_access_rights("read", raise_exception=False))
|
||||
|
||||
# verify the filter can be created and the action still runs
|
||||
filters = self_portal.create({
|
||||
"name": "Where is Bilbo?",
|
||||
"domain": "[('name', 'ilike', 'bilbo')]",
|
||||
"model_id": "res.partner",
|
||||
})
|
||||
self.assertFalse(filters.active)
|
||||
|
||||
# verify the filter can be updated and the action still runs
|
||||
filters.active = True
|
||||
filters.name = "Where is Bilbo Baggins?"
|
||||
self.assertFalse(filters.active)
|
||||
|
||||
|
||||
def test_03_on_change_restricted(self):
|
||||
""" on_create action with low portal user """
|
||||
action = self.env["base.automation"].create({
|
||||
"name": "Force Archived Filters",
|
||||
"trigger": "on_change",
|
||||
"model_id": self.env.ref("base.model_ir_filters").id,
|
||||
"type": "ir.actions.server",
|
||||
"on_change_field_ids": [(6, 0, [self.env.ref("base.field_ir_filters__name").id])],
|
||||
"state": "code",
|
||||
"code": """action = {'value': {'active': False}}""",
|
||||
})
|
||||
# action cached was cached with admin, force CacheMiss
|
||||
action.env.clear()
|
||||
|
||||
self_portal = self.env["ir.filters"].with_user(self.env.ref("base.user_demo").id)
|
||||
|
||||
# simulate a onchange call on name
|
||||
onchange = self_portal.onchange({}, [], {"name": "1", "active": ""})
|
||||
self.assertEqual(onchange["value"]["active"], False)
|
||||
Reference in New Issue
Block a user