diff options
| author | Raphael Collet <rco@openerp.com> | 2016-09-02 15:58:39 +0200 |
|---|---|---|
| committer | Raphael Collet <rco@openerp.com> | 2016-09-02 17:28:12 +0200 |
| commit | 9e64f9f9514194d74e166b032add8511182f2677 (patch) | |
| tree | 5086710c04c6b923be18a6d1d97b3f0f3a2a9c4a /odoo/addons/base/tests/test_acl.py | |
| parent | 11812b0b9e82b2b1b9041d8250ce01e7b4a5f7ee (diff) | |
[REF] openerp: move `openerp` to `odoo`
Diffstat (limited to 'odoo/addons/base/tests/test_acl.py')
| -rw-r--r-- | odoo/addons/base/tests/test_acl.py | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/odoo/addons/base/tests/test_acl.py b/odoo/addons/base/tests/test_acl.py new file mode 100644 index 00000000000..f65f4209a68 --- /dev/null +++ b/odoo/addons/base/tests/test_acl.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from lxml import etree + +from odoo.exceptions import AccessError +from odoo.tests.common import TransactionCase +from odoo.tools.misc import mute_logger + +# test group that demo user should not have +USER_DEMO = 'base.user_demo' +GROUP_SYSTEM = 'base.group_system' + + +class TestACL(TransactionCase): + + def setUp(self): + super(TestACL, self).setUp() + self.demo_user = self.env.ref(USER_DEMO) + self.erp_system_group = self.env.ref(GROUP_SYSTEM) + + def _set_field_groups(self, model, field_name, groups): + field = model._fields[field_name] + self.patch(field, 'groups', groups) + + def test_field_visibility_restriction(self): + """Check that model-level ``groups`` parameter effectively restricts access to that + field for users who do not belong to one of the explicitly allowed groups""" + currency = self.env['res.currency'].sudo(self.demo_user) + + # Verify the test environment first + original_fields = currency.fields_get([]) + form_view = currency.fields_view_get(False, 'form') + view_arch = etree.fromstring(form_view.get('arch')) + has_group_system = self.demo_user.has_group(GROUP_SYSTEM) + self.assertFalse(has_group_system, "`demo` user should not belong to the restricted group before the test") + self.assertIn('decimal_places', original_fields, "'decimal_places' field must be properly visible before the test") + self.assertNotEquals(view_arch.xpath("//field[@name='decimal_places']"), [], + "Field 'decimal_places' must be found in view definition before the test") + + # restrict access to the field and check it's gone + self._set_field_groups(currency, 'decimal_places', GROUP_SYSTEM) + + fields = currency.fields_get([]) + form_view = currency.fields_view_get(False, 'form') + view_arch = etree.fromstring(form_view.get('arch')) + self.assertNotIn('decimal_places', fields, "'decimal_places' field should be gone") + self.assertEquals(view_arch.xpath("//field[@name='decimal_places']"), [], + "Field 'decimal_places' must not be found in view definition") + + # Make demo user a member of the restricted group and check that the field is back + self.erp_system_group.users += self.demo_user + has_group_system = self.demo_user.has_group(GROUP_SYSTEM) + fields = currency.fields_get([]) + form_view = currency.fields_view_get(False, 'form') + view_arch = etree.fromstring(form_view.get('arch')) + self.assertTrue(has_group_system, "`demo` user should now belong to the restricted group") + self.assertIn('decimal_places', fields, "'decimal_places' field must be properly visible again") + self.assertNotEquals(view_arch.xpath("//field[@name='decimal_places']"), [], + "Field 'decimal_places' must be found in view definition again") + + @mute_logger('openerp.models') + def test_field_crud_restriction(self): + "Read/Write RPC access to restricted field should be forbidden" + partner = self.env['res.partner'].browse(1).sudo(self.demo_user) + + # Verify the test environment first + has_group_system = self.demo_user.has_group(GROUP_SYSTEM) + self.assertFalse(has_group_system, "`demo` user should not belong to the restricted group") + self.assert_(partner.read(['bank_ids'])) + self.assert_(partner.write({'bank_ids': []})) + + # Now restrict access to the field and check it's forbidden + self._set_field_groups(partner, 'bank_ids', GROUP_SYSTEM) + + with self.assertRaises(AccessError): + partner.read(['bank_ids']) + with self.assertRaises(AccessError): + partner.write({'bank_ids': []}) + + # Add the restricted group, and check that it works again + self.erp_system_group.users += self.demo_user + has_group_system = self.demo_user.has_group(GROUP_SYSTEM) + self.assertTrue(has_group_system, "`demo` user should now belong to the restricted group") + self.assert_(partner.read(['bank_ids'])) + self.assert_(partner.write({'bank_ids': []})) + + @mute_logger('openerp.models') + def test_fields_browse_restriction(self): + """Test access to records having restricted fields""" + partner = self.env['res.partner'].sudo(self.demo_user) + self._set_field_groups(partner, 'email', GROUP_SYSTEM) + + # accessing fields must no raise exceptions... + partner = partner.search([], limit=1) + partner.name + # ... except if they are restricted + with self.assertRaises(AccessError): + with mute_logger('openerp.models'): + partner.email + + def test_view_create_edit_button_invisibility(self): + """ Test form view Create, Edit, Delete button visibility based on access right of model""" + methods = ['create', 'edit', 'delete'] + company = self.env['res.company'].sudo(self.demo_user) + company_view = company.fields_view_get(False, 'form') + view_arch = etree.fromstring(company_view['arch']) + for method in methods: + self.assertEqual(view_arch.get(method), 'false') + + def test_view_create_edit_button_visibility(self): + """ Test form view Create, Edit, Delete button visibility based on access right of model""" + self.erp_system_group.users += self.demo_user + methods = ['create', 'edit', 'delete'] + company = self.env['res.company'].sudo(self.demo_user) + company_view = company.fields_view_get(False, 'form') + view_arch = etree.fromstring(company_view['arch']) + for method in methods: + self.assertIsNone(view_arch.get(method)) + + def test_m2o_field_create_edit_invisibility(self): + """ Test many2one field Create and Edit option visibility based on access rights of relation field""" + methods = ['create', 'write'] + company = self.env['res.company'].sudo(self.demo_user) + company_view = company.fields_view_get(False, 'form') + view_arch = etree.fromstring(company_view['arch']) + field_node = view_arch.xpath("//field[@name='currency_id']") + self.assertTrue(len(field_node), "currency_id field should be in company from view") + for method in methods: + self.assertEqual(field_node[0].get('can_' + method), 'false') + + def test_m2o_field_create_edit_visibility(self): + """ Test many2one field Create and Edit option visibility based on access rights of relation field""" + self.erp_system_group.users += self.demo_user + methods = ['create', 'write'] + company = self.env['res.company'].sudo(self.demo_user) + company_view = company.fields_view_get(False, 'form') + view_arch = etree.fromstring(company_view['arch']) + field_node = view_arch.xpath("//field[@name='currency_id']") + self.assertTrue(len(field_node), "currency_id field should be in company from view") + for method in methods: + self.assertEqual(field_node[0].get('can_' + method), 'true') + + +class TestIrRule(TransactionCase): + + def test_ir_rule(self): + model_res_partner = self.env.ref('base.model_res_partner') + group_user = self.env.ref('base.group_user') + user_demo = self.env.ref('base.user_demo') + + # create an ir_rule for the Employee group with an blank domain + rule1 = self.env['ir.rule'].create({ + 'name': 'test_rule1', + 'model_id': model_res_partner.id, + 'domain_force': False, + 'groups': [(6, 0, group_user.ids)], + }) + + # read as demo user the partners (one blank domain) + partners_demo = self.env['res.partner'].sudo(user_demo) + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # same with domain 1=1 + rule1.domain_force = "[(1,'=',1)]" + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # same with domain [] + rule1.domain_force = "[]" + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # create another ir_rule for the Employee group (to test multiple rules) + rule2 = self.env['ir.rule'].create({ + 'name': 'test_rule2', + 'model_id': model_res_partner.id, + 'domain_force': False, + 'groups': [(6, 0, group_user.ids)], + }) + + # read as demo user with domains [] and blank + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # same with domains 1=1 and blank + rule1.domain_force = "[(1,'=',1)]" + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # same with domains 1=1 and 1=1 + rule2.domain_force = "[(1,'=',1)]" + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # create another ir_rule for the Employee group (to test multiple rules) + rule3 = self.env['ir.rule'].create({ + 'name': 'test_rule3', + 'model_id': model_res_partner.id, + 'domain_force': False, + 'groups': [(6, 0, group_user.ids)], + }) + + # read the partners as demo user + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # same with domains 1=1, 1=1 and 1=1 + rule3.domain_force = "[(1,'=',1)]" + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # modify the global rule on res_company which triggers a recursive check + # of the rules on company + global_rule = self.env.ref('base.res_company_rule_employee') + global_rule.domain_force = "[('id','child_of',[user.company_id.id])]" + + # read as demo user (exercising the global company rule) + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # Modify the ir_rule for employee to have a rule that fordids seeing any + # record. We use a domain with implicit AND operator for later tests on + # normalization. + rule2.domain_force = "[('id','=',False),('name','=',False)]" + + # check that demo user still sees partners, because group-rules are OR'ed + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partner.") + + # create a new group with demo user in it, and a complex rule + group_test = self.env['res.groups'].create({ + 'name': 'Test Group', + 'users': [(6, 0, user_demo.ids)], + }) + + # add the rule to the new group, with a domain containing an implicit + # AND operator, which is more tricky because it will have to be + # normalized before combining it + rule3.write({ + 'domain_force': "[('name','!=',False),('id','!=',False)]", + 'groups': [(6, 0, group_test.ids)], + }) + + # read the partners again as demo user, which should give results + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see partners even with the combined rules.") + + # delete global domains (to combine only group domains) + self.env['ir.rule'].search([('groups', '=', False)]).unlink() + + # read the partners as demo user (several group domains, no global domain) + partners = partners_demo.search([]) + self.assertTrue(partners, "Demo user should see some partners.") |
