[FIX] base: Remove label from views if user groups forbid the field

Without this patch, if a view defines a `<label for="forbidden_field"/>` anywhere, the web client tries to fetch the field data, but since the user has no access, it gets an error.

Now, if the label targets a forbidden field, it gets removed from the view, as happens with the related field. The client doesn't know of that field's existence and no errors happen.

closes odoo/odoo#38876

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
fw-bot
2019-10-18 08:35:39 +00:00
committed by Thibault Delavallée
parent 97a5054eeb
commit ed1236275f
2 changed files with 33 additions and 4 deletions
+8 -3
View File
@@ -728,11 +728,16 @@ actual arch.
"""
Model = self.env[model]
if node.tag == 'field' and node.get('name') in Model._fields:
field = Model._fields[node.get('name')]
field_name = None
if node.tag == "field":
field_name = node.get("name")
elif node.tag == "label":
field_name = node.get("for")
if field_name and field_name in Model._fields:
field = Model._fields[field_name]
if field.groups and not self.user_has_groups(groups=field.groups):
node.getparent().remove(node)
fields.pop(node.get('name'), None)
fields.pop(field_name, None)
# no point processing view-level ``groups`` anymore, return
return False
if node.get('groups'):
+25 -1
View File
@@ -28,6 +28,24 @@ class TestACL(TransactionCase):
field for users who do not belong to one of the explicitly allowed groups"""
currency = self.env['res.currency'].with_user(self.demo_user)
# Add a view that adds a label for the field we are going to check
extension = self.env["ir.ui.view"].create({
"name": "Add separate label for decimal_places",
"model": "res.currency",
"inherit_id": self.env.ref("base.view_currency_form").id,
"arch": """
<data>
<field name="decimal_places" position="attributes">
<attribute name="nolabel">1</attribute>
</field>
<field name="decimal_places" position="before">
<label for="decimal_places"/>
</field>
</data>
""",
})
currency = currency.with_context(check_view_ids=extension.ids)
# Verify the test environment first
original_fields = currency.fields_get([])
form_view = currency.fields_view_get(False, 'form')
@@ -35,8 +53,10 @@ class TestACL(TransactionCase):
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.assertNotEqual(view_arch.xpath("//field[@name='decimal_places']"), [],
self.assertNotEqual(view_arch.xpath("//field[@name='decimal_places'][@nolabel='1']"), [],
"Field 'decimal_places' must be found in view definition before the test")
self.assertNotEqual(view_arch.xpath("//label[@for='decimal_places']"), [],
"Label for '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)
@@ -47,6 +67,8 @@ class TestACL(TransactionCase):
self.assertNotIn('decimal_places', fields, "'decimal_places' field should be gone")
self.assertEqual(view_arch.xpath("//field[@name='decimal_places']"), [],
"Field 'decimal_places' must not be found in view definition")
self.assertEqual(view_arch.xpath("//label[@for='decimal_places']"), [],
"Label for '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
@@ -58,6 +80,8 @@ class TestACL(TransactionCase):
self.assertIn('decimal_places', fields, "'decimal_places' field must be properly visible again")
self.assertNotEqual(view_arch.xpath("//field[@name='decimal_places']"), [],
"Field 'decimal_places' must be found in view definition again")
self.assertNotEqual(view_arch.xpath("//label[@for='decimal_places']"), [],
"Label for 'decimal_places' must be found in view definition again")
@mute_logger('odoo.models')
def test_field_crud_restriction(self):