[FIX] models: check groups on inverse fields
Before this, groups on non-stored inverse fields were not checked upon write. The impact on existing fields is pretty small, since the inverse methods of those fields are subject to access rights on the records they use. closes odoo/odoo#30356
This commit is contained in:
@@ -276,6 +276,16 @@ class TestFields(common.TransactionCase):
|
||||
self.assertEqual(record.bar, 'Ho')
|
||||
self.assertEqual(record.counts, {'compute': 0, 'inverse': 1})
|
||||
|
||||
def test_13_inverse_access(self):
|
||||
""" test access rights on inverse fields """
|
||||
foo = self.env['test_new_api.category'].create({'name': 'Foo'})
|
||||
user = self.env['res.users'].create({'name': 'Foo', 'login': 'foo'})
|
||||
self.assertFalse(user.has_group('base.group_system'))
|
||||
# add group on non-stored inverse field
|
||||
self.patch(type(foo).display_name, 'groups', 'base.group_system')
|
||||
with self.assertRaises(AccessError):
|
||||
foo.sudo(user).display_name = 'Forbidden'
|
||||
|
||||
def test_14_search(self):
|
||||
""" test search on computed fields """
|
||||
discussion = self.env.ref('test_new_api.discussion_0')
|
||||
@@ -577,6 +587,26 @@ class TestFields(common.TransactionCase):
|
||||
self.assertEqual(attribute_record.bar, 'DEFDEF')
|
||||
self.assertFalse(self.env.has_todo())
|
||||
|
||||
# add group on company-dependent field
|
||||
self.assertFalse(user0.has_group('base.group_system'))
|
||||
self.patch(type(record).foo, 'groups', 'base.group_system')
|
||||
with self.assertRaises(AccessError):
|
||||
record.sudo(user0).foo = 'forbidden'
|
||||
|
||||
user0.write({'groups_id': [(4, self.env.ref('base.group_system').id)]})
|
||||
record.sudo(user0).foo = 'yes we can'
|
||||
|
||||
# add ir.rule to prevent access on record
|
||||
self.assertTrue(user0.has_group('base.group_user'))
|
||||
model_id = self.env['ir.model'].search([('model', '=', record._name)]).id
|
||||
rule = self.env['ir.rule'].create({
|
||||
'model_id': model_id,
|
||||
'groups': [self.env.ref('base.group_user').id],
|
||||
'domain_force': str([('id', '!=', record.id)]),
|
||||
})
|
||||
with self.assertRaises(AccessError):
|
||||
record.sudo(user0).foo = 'forbidden'
|
||||
|
||||
def test_28_sparse(self):
|
||||
""" test sparse fields. """
|
||||
record = self.env['test_new_api.sparse'].create({})
|
||||
|
||||
+6
-1
@@ -3568,10 +3568,15 @@ class BaseModel(object):
|
||||
protected_fields = map(self._fields.get, new_vals)
|
||||
with self.env.protecting(protected_fields, self):
|
||||
# write old-style fields with (low-level) method _write
|
||||
if old_vals:
|
||||
if old_vals or new_vals:
|
||||
# if log_access is enabled, this updates 'write_date' and
|
||||
# 'write_uid' and check access rules, even when old_vals is
|
||||
# empty
|
||||
self._write(old_vals)
|
||||
|
||||
if new_vals:
|
||||
self.check_field_access_rights('write', list(new_vals))
|
||||
|
||||
self.modified(set(new_vals) - set(old_vals))
|
||||
|
||||
# put the values of fields into cache, and inverse them
|
||||
|
||||
Reference in New Issue
Block a user