diff --git a/odoo/addons/base/models/ir_ui_view.py b/odoo/addons/base/models/ir_ui_view.py index 6b8b50ceb88..0e76813cd5a 100644 --- a/odoo/addons/base/models/ir_ui_view.py +++ b/odoo/addons/base/models/ir_ui_view.py @@ -406,11 +406,14 @@ actual arch. return True - @api.constrains('type', 'groups_id') + @api.constrains('type', 'groups_id', 'inherit_id') def _check_groups(self): for view in self: - if view.type == 'qweb' and view.groups_id: - raise ValidationError(_("Qweb view cannot have 'Groups' define on the record. Use 'groups' attributes inside the view definition")) + if (view.type == 'qweb' and + view.groups_id and + view.inherit_id and + view.mode != 'primary'): + raise ValidationError(_("Inherited Qweb view cannot have 'Groups' define on the record. Use 'groups' attributes inside the view definition")) @api.constrains('inherit_id') def _check_000_inheritance(self): @@ -606,6 +609,21 @@ actual arch. return self.browse(view_ids).sudo().filtered(accessible) + def _check_view_access(self): + """ Verify that a view is accessible by the current user based on the + groups attribute. Views with no groups are considered private. + """ + if self.inherit_id and self.mode != 'primary': + return self.inherit_id._check_view_access() + if self.groups_id & self.env.user.groups_id: + return True + if self.groups_id: + error = _("View '%s' accessible only to groups %s ") % \ + (self.key, ", ".join([g.name for g in self.groups_id])) + else: + error = _("View '%s' is private") % self.key + raise AccessError(error) + def handle_view_error(self, message, *, raise_exception=True, from_exception=None, from_traceback=None): """ Handle a view error by raising an exception or logging a warning, depending on the value of `raise_exception`. @@ -1494,7 +1512,9 @@ actual arch. """ Return a template content based on external id Read access on ir.ui.view required """ - return self._read_template(self.get_view_id(xml_id)) + template_id = self.get_view_id(xml_id) + self.browse(template_id)._check_view_access() + return self._read_template(template_id) @api.model def get_view_id(self, template): @@ -1603,10 +1623,8 @@ actual arch. @api.model def render_public_asset(self, template, values=None): - if template not in PUBLIC_ASSETS: - _logger.warning("Add the external id %s in global variable PUBLC_ASSSETS to make the arch accessible in RPC", template) - raise ValidationError(_("Asset %s not accessible") % template) - template = self.browse(self.get_view_id(template)) + template = self.sudo().browse(self.get_view_id(template)) + template._check_view_access() return template.sudo()._render(values, engine="ir.qweb") def _render_template(self, template, values=None, engine='ir.qweb'):