Skip to content
Snippets Groups Projects
Commit 980d1b14 authored by Nicolas Seinlet's avatar Nicolas Seinlet Committed by Raphael Collet
Browse files

[FIX] base_automation: avoid access right issues filter domains


If some filter domains use M2O to models current user cannot access,
using sudo() permit to filter even when user cannot access linked
models.

for the accuracy of the fix, add a unit test which reproduce the exact
reported bug.

closes odoo/odoo#43582

Signed-off-by: default avatarRaphael Collet (rco) <rco@openerp.com>
parent 20d2659e
No related branches found
No related tags found
No related merge requests found
......@@ -156,7 +156,7 @@ class BaseAutomation(models.Model):
""" Filter the records that satisfy the precondition of action ``self``. """
if self.filter_pre_domain and records:
domain = [('id', 'in', records.ids)] + safe_eval(self.filter_pre_domain, self._get_eval_context())
return records.search(domain)
return records.sudo().search(domain).with_env(records.env)
else:
return records
......@@ -167,7 +167,7 @@ class BaseAutomation(models.Model):
""" Filter the records that satisfy the postcondition of action ``self``. """
if self.filter_domain and records:
domain = [('id', 'in', records.ids)] + safe_eval(self.filter_domain, self._get_eval_context())
return records.search(domain), domain
return records.sudo().search(domain).with_env(records.env), domain
else:
return records, None
......
......@@ -2,4 +2,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_base_automation,base.automation,model_base_automation,,1,0,0,0
access_base_automation_config,base.automation config,model_base_automation,base.group_system,1,1,1,1
access_base_automation_lead_test,access_base_automation_lead_test,model_base_automation_lead_test,base.group_system,1,1,1,1
access_base_automation_line_test,access_base_automation_line_test,model_base_automation_line_test,base.group_system,1,1,1,1
\ No newline at end of file
access_base_automation_line_test,access_base_automation_line_test,model_base_automation_line_test,base.group_system,1,1,1,1
access_base_automation_link_test,access_base_automation_link_test,model_base_automation_link_test,,1,1,1,1
access_base_automation_linked_test,access_base_automation_linked_test,model_base_automation_linked_test,,1,1,1,1
......@@ -3,6 +3,7 @@
from unittest.mock import patch
from odoo.tests import common
from odoo.exceptions import AccessError
@common.tagged('post_install','-at_install')
......@@ -205,3 +206,60 @@ class base_automation_test(common.TransactionCase):
self.assertEqual(lead.name, 'XX', "No update should have happened.")
lead.partner_id = partner1
self.assertEqual(lead.name, 'XXX', "One update should have happened.")
def test_30_modelwithoutaccess(self):
"""
Ensure a domain on a M2O without user access doesn't fail.
We create a base automation with a filter on a model the user haven't access to
- create a group
- restrict acl to this group and set only admin in it
- create base.automation with a filter
- create a record in the restricted model in admin
- create a record in the non restricted model in demo
"""
Model = self.env['base.automation.link.test']
Comodel = self.env['base.automation.linked.test']
new_group = self.env['res.groups'].create({
'name': "Access to base.automation.linked.test",
"users": [(6, 0, [self.user_admin.id,])]
})
self.env.ref("base_automation.access_base_automation_linked_test").write({"group_id": new_group.id})
# sanity check: user demo has no access to the comodel of 'linked_id'
with self.assertRaises(AccessError):
Comodel.with_user(self.user_demo).check_access_rights('read')
# check base automation with filter that performs Comodel.search()
self.env['base.automation'].create({
'name': 'test no access',
'model_id': self.env['ir.model']._get_id("base.automation.link.test"),
'trigger': 'on_create_or_write',
'filter_pre_domain': "[('linked_id.another_field', '=', 'something')]",
'state': 'code',
'active': True,
'code': "action = [rec.name for rec in records]"
})
Comodel.create([
{'name': 'a first record', 'another_field': 'something'},
{'name': 'another record', 'another_field': 'something different'},
])
rec1 = Model.create({'name': 'a record'})
rec1.write({'name': 'a first record'})
rec2 = Model.with_user(self.user_demo).create({'name': 'another record'})
rec2.write({'name': 'another value'})
# check base automation with filter that performs Comodel.name_search()
self.env['base.automation'].create({
'name': 'test no name access',
'model_id': self.env['ir.model']._get_id("base.automation.link.test"),
'trigger': 'on_create_or_write',
'filter_pre_domain': "[('linked_id', '=', 'whatever')]",
'state': 'code',
'active': True,
'code': "action = [rec.name for rec in records]"
})
rec3 = Model.create({'name': 'a random record'})
rec3.write({'name': 'a first record'})
rec4 = Model.with_user(self.user_demo).create({'name': 'again another record'})
rec4.write({'name': 'another value'})
......@@ -49,3 +49,19 @@ class LineTest(models.Model):
name = fields.Char()
lead_id = fields.Many2one('base.automation.lead.test', ondelete='cascade')
user_id = fields.Many2one('res.users')
class ModelWithAccess(models.Model):
_name = "base.automation.link.test"
_description = "Automated Rule Link Test"
name = fields.Char()
linked_id = fields.Many2one('base.automation.linked.test', ondelete='cascade')
class ModelWithoutAccess(models.Model):
_name = "base.automation.linked.test"
_description = "Automated Rule Linked Test"
name = fields.Char()
another_field = fields.Char()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment