Server IP : 127.0.0.2 / Your IP : 3.17.4.144 Web Server : Apache/2.4.18 (Ubuntu) System : User : www-data ( ) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : disk_free_space,disk_total_space,diskfreespace,dl,exec,fpaththru,getmyuid,getmypid,highlight_file,ignore_user_abord,leak,listen,link,opcache_get_configuration,opcache_get_status,passthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,php_uname,phpinfo,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,pclose,popen,proc_open,proc_close,proc_get_status,proc_nice,proc_terminate,shell_exec,source,show_source,system,virtual MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /opt/odoo/odoo/addons/base/tests/ |
Upload File : |
# -*- 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('odoo.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('odoo.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('odoo.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.")