diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-02-14 18:42:19 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-02-14 18:42:19 +0100 |
| commit | b277705e52232e5d28c5ec5fc381631fcb1964f8 (patch) | |
| tree | 437ed09707b32b9fa4ed5eb678214d9b46e6b598 /odoo | |
| parent | 38be857b4016f120e3cf119a94ca92d035bdab31 (diff) | |
| parent | c0f24d54cfab764c0b89df977757e06974a658c6 (diff) | |
[MERGE] forward port branch saas-15 up to c0f24d54cfa
Diffstat (limited to 'odoo')
| -rw-r--r-- | odoo/addons/test_new_api/tests/test_new_fields.py | 40 | ||||
| -rw-r--r-- | odoo/fields.py | 16 | ||||
| -rw-r--r-- | odoo/models.py | 7 |
3 files changed, 60 insertions, 3 deletions
diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 83a359ac951..b86b4ce5953 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -281,6 +281,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') @@ -586,6 +596,10 @@ class TestFields(common.TransactionCase): self.env['ir.property'].create({'name': 'foo', 'fields_id': field_tag_id.id, 'value': tag0, 'type': 'many2one'}) + # assumption: users don't have access to 'ir.property' + accesses = self.env['ir.model.access'].search([('model_id.model', '=', 'ir.property')]) + accesses.write(dict.fromkeys(['perm_read', 'perm_write', 'perm_create', 'perm_unlink'], False)) + # create/modify a record, and check the value for each user record = self.env['test_new_api.company'].create({ 'foo': 'main', @@ -639,6 +653,13 @@ class TestFields(common.TransactionCase): self.assertEqual(record.sudo(user1).foo, False) self.assertEqual(record.sudo(user2).foo, 'default') + # set field with 'force_company' in context + record.sudo(user0).with_context(force_company=company1.id).foo = 'beta' + record.invalidate_cache() + self.assertEqual(record.sudo(user0).foo, 'main') + self.assertEqual(record.sudo(user1).foo, 'beta') + self.assertEqual(record.sudo(user2).foo, 'default') + # create company record and attribute company_record = self.env['test_new_api.company'].create({'foo': 'ABC'}) attribute_record = self.env['test_new_api.company.attr'].create({ @@ -658,6 +679,25 @@ 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')) + rule = self.env['ir.rule'].create({ + 'model_id': self.env['ir.model']._get_id(record._name), + '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_30_read(self): """ test computed fields as returned by read(). """ discussion = self.env.ref('test_new_api.discussion_0') diff --git a/odoo/fields.py b/odoo/fields.py index 24683bbd0c8..b0100d4f549 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -622,13 +622,25 @@ class Field(MetaField('DummyField', (object,), {})): return model.env['ir.property'].get(self.name, self.model_name) def _compute_company_dependent(self, records): - Property = records.env['ir.property'] + # read property as superuser, as the current user may not have access + context = records.env.context + if 'force_company' not in context: + field_id = records.env['ir.model.fields']._get_id(self.model_name, self.name) + company = records.env['res.company']._company_default_get(self.model_name, field_id) + context = dict(context, force_company=company.id) + Property = records.env(user=SUPERUSER_ID, context=context)['ir.property'] values = Property.get_multi(self.name, self.model_name, records.ids) for record in records: record[self.name] = values.get(record.id) def _inverse_company_dependent(self, records): - Property = records.env['ir.property'] + # update property as superuser, as the current user may not have access + context = records.env.context + if 'force_company' not in context: + field_id = records.env['ir.model.fields']._get_id(self.model_name, self.name) + company = records.env['res.company']._company_default_get(self.model_name, field_id) + context = dict(context, force_company=company.id) + Property = records.env(user=SUPERUSER_ID, context=context)['ir.property'] values = { record.id: self.convert_to_write(record[self.name], record) for record in records diff --git a/odoo/models.py b/odoo/models.py index 1fc937f8f5e..bedf7fec10e 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3102,10 +3102,15 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): protected_fields = [self._fields[n] for n in 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 |
