From 8eb575a1cf97e330a3d5545be81ab5eb0976de6a Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Tue, 25 Feb 2020 18:31:21 +0100 Subject: [PATCH] [IMP] base: allow using groups_id on ir.ui.view Allow groups_id on top level view as a way to relax the access of some views There was some scenarios where ir.ui.view were still needed to be accessible. For instance the website.snippet is needed to display the website editor sidebar to designers. The website.compiled_assets_wysiwyg is needed to display the app switcher on the website to employees. This should cover most of the cases where a view still must be accessible and no specific controller is available. --- odoo/addons/base/models/ir_ui_view.py | 34 ++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) 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'):