5 from openerp.tools.misc import mute_logger
6 from openerp.tests import common
8 # test group that demo user should not have
9 GROUP_TECHNICAL_FEATURES = 'base.group_no_one'
12 class TestACL(common.TransactionCase):
15 super(TestACL, self).setUp()
16 self.res_currency = self.registry('res.currency')
17 self.res_partner = self.registry('res.partner')
18 self.res_users = self.registry('res.users')
19 _, self.demo_uid = self.registry('ir.model.data').get_object_reference(self.cr, self.uid, 'base', 'user_demo')
20 self.tech_group = self.registry('ir.model.data').get_object(self.cr, self.uid,
21 *(GROUP_TECHNICAL_FEATURES.split('.')))
23 def _set_field_groups(self, model, field_name, groups):
24 field = model._fields[field_name]
25 column = model._columns[field_name]
26 old_groups = field.groups
27 old_prefetch = column._prefetch
30 column.groups = groups
31 column._prefetch = False
35 field.groups = old_groups
36 column.groups = old_groups
37 column._prefetch = old_prefetch
39 def test_field_visibility_restriction(self):
40 """Check that model-level ``groups`` parameter effectively restricts access to that
41 field for users who do not belong to one of the explicitly allowed groups"""
42 # Verify the test environment first
43 original_fields = self.res_currency.fields_get(self.cr, self.demo_uid, [])
44 form_view = self.res_currency.fields_view_get(self.cr, self.demo_uid, False, 'form')
45 view_arch = etree.fromstring(form_view.get('arch'))
46 has_tech_feat = self.res_users.has_group(self.cr, self.demo_uid, GROUP_TECHNICAL_FEATURES)
47 self.assertFalse(has_tech_feat, "`demo` user should not belong to the restricted group before the test")
48 self.assertTrue('accuracy' in original_fields, "'accuracy' field must be properly visible before the test")
49 self.assertNotEquals(view_arch.xpath("//field[@name='accuracy']"), [],
50 "Field 'accuracy' must be found in view definition before the test")
52 # restrict access to the field and check it's gone
53 self._set_field_groups(self.res_currency, 'accuracy', GROUP_TECHNICAL_FEATURES)
55 fields = self.res_currency.fields_get(self.cr, self.demo_uid, [])
56 form_view = self.res_currency.fields_view_get(self.cr, self.demo_uid, False, 'form')
57 view_arch = etree.fromstring(form_view.get('arch'))
58 self.assertFalse('accuracy' in fields, "'accuracy' field should be gone")
59 self.assertEquals(view_arch.xpath("//field[@name='accuracy']"), [],
60 "Field 'accuracy' must not be found in view definition")
62 # Make demo user a member of the restricted group and check that the field is back
63 self.tech_group.write({'users': [(4, self.demo_uid)]})
64 has_tech_feat = self.res_users.has_group(self.cr, self.demo_uid, GROUP_TECHNICAL_FEATURES)
65 fields = self.res_currency.fields_get(self.cr, self.demo_uid, [])
66 form_view = self.res_currency.fields_view_get(self.cr, self.demo_uid, False, 'form')
67 view_arch = etree.fromstring(form_view.get('arch'))
68 #import pprint; pprint.pprint(fields); pprint.pprint(form_view)
69 self.assertTrue(has_tech_feat, "`demo` user should now belong to the restricted group")
70 self.assertTrue('accuracy' in fields, "'accuracy' field must be properly visible again")
71 self.assertNotEquals(view_arch.xpath("//field[@name='accuracy']"), [],
72 "Field 'accuracy' must be found in view definition again")
75 self.tech_group.write({'users': [(3, self.demo_uid)]})
77 @mute_logger('openerp.models')
78 def test_field_crud_restriction(self):
79 "Read/Write RPC access to restricted field should be forbidden"
80 # Verify the test environment first
81 has_tech_feat = self.res_users.has_group(self.cr, self.demo_uid, GROUP_TECHNICAL_FEATURES)
82 self.assertFalse(has_tech_feat, "`demo` user should not belong to the restricted group")
83 self.assert_(self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids']))
84 self.assert_(self.res_partner.write(self.cr, self.demo_uid, [1], {'bank_ids': []}))
86 # Now restrict access to the field and check it's forbidden
87 self._set_field_groups(self.res_partner, 'bank_ids', GROUP_TECHNICAL_FEATURES)
89 with self.assertRaises(openerp.osv.orm.except_orm):
90 self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids'])
91 with self.assertRaises(openerp.osv.orm.except_orm):
92 self.res_partner.write(self.cr, self.demo_uid, [1], {'bank_ids': []})
94 # Add the restricted group, and check that it works again
95 self.tech_group.write({'users': [(4, self.demo_uid)]})
96 has_tech_feat = self.res_users.has_group(self.cr, self.demo_uid, GROUP_TECHNICAL_FEATURES)
97 self.assertTrue(has_tech_feat, "`demo` user should now belong to the restricted group")
98 self.assert_(self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids']))
99 self.assert_(self.res_partner.write(self.cr, self.demo_uid, [1], {'bank_ids': []}))
102 self.tech_group.write({'users': [(3, self.demo_uid)]})
104 @mute_logger('openerp.models')
105 def test_fields_browse_restriction(self):
106 """Test access to records having restricted fields"""
107 self._set_field_groups(self.res_partner, 'email', GROUP_TECHNICAL_FEATURES)
109 pid = self.res_partner.search(self.cr, self.demo_uid, [], limit=1)[0]
110 part = self.res_partner.browse(self.cr, self.demo_uid, pid)
111 # accessing fields must no raise exceptions...
113 # ... except if they are restricted
114 with self.assertRaises(openerp.osv.orm.except_orm) as cm:
115 with mute_logger('openerp.models'):
118 self.assertEqual(cm.exception.args[0], 'AccessError')
120 if __name__ == '__main__':
123 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: