summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Trigaux <mat@odoo.com>2020-02-06 15:03:00 +0100
committerMartin Trigaux <mat@odoo.com>2020-05-14 13:59:10 +0200
commit56a8c9e4311d24c33b7ad08b8230e4be345a85b8 (patch)
tree20ae492b0a187131bae67cc0250f30f686f4231a
parentccc98e01691b88c2da9c484c0e6de235b9d18548 (diff)
[FIX] *: add sudo when accessing views
The method fields_view_get should be the only way to retrieve the view content. This method is executed in a super-user context. To avoid retrieving views for a model a user does not have access to (as it may reveal some informations like name of fields), add a verification of 'read' rights before retrieving the view content. Execute _postprocess_access_rights with sudo(False) as this method is used to evaluate which buttons should be displayed. Remove the su flag to avoid misleading the user and displaying a button they won't be able to use. Retrieving the database id from an view key is not considered as a sensitive information and get_view_id and viewref can be left as a public methods. Add missing sudo when needed Change _handle_visibility in website to avoid increasing the query count: Checking the visibility (to fail most of the time) to retry in sudo was making unecessary queries.
-rw-r--r--addons/web_editor/models/ir_qweb.py2
-rw-r--r--addons/website/controllers/main.py5
-rw-r--r--addons/website/models/ir_ui_view.py5
-rw-r--r--addons/website/models/website.py6
-rw-r--r--odoo/addons/base/models/ir_actions_report.py2
-rw-r--r--odoo/addons/base/models/ir_qweb.py4
-rw-r--r--odoo/addons/base/models/ir_ui_view.py9
-rw-r--r--odoo/models.py5
8 files changed, 20 insertions, 18 deletions
diff --git a/addons/web_editor/models/ir_qweb.py b/addons/web_editor/models/ir_qweb.py
index fdc5407e6f0..5eceda7855f 100644
--- a/addons/web_editor/models/ir_qweb.py
+++ b/addons/web_editor/models/ir_qweb.py
@@ -64,7 +64,7 @@ class QWeb(models.AbstractModel):
key = el.attrib.pop('t-snippet')
el.set('t-call', key)
el.set('t-call-options', "{'snippet-key': '" + key + "'}")
- View = self.env['ir.ui.view']
+ View = self.env['ir.ui.view'].sudo()
view_id = View.get_view_id(key)
name = View.browse(view_id).name
thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail")
diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py
index c4e0e20675a..93d44718b9b 100644
--- a/addons/website/controllers/main.py
+++ b/addons/website/controllers/main.py
@@ -340,7 +340,10 @@ class Website(Home):
@http.route('/website/toggle_switchable_view', type='json', auth='user', website=True)
def toggle_switchable_view(self, view_key):
- request.website.viewref(view_key).toggle_active()
+ if request.website.user_has_groups('website.group_website_designer'):
+ request.website.viewref(view_key).toggle_active()
+ else:
+ return werkzeug.exceptions.Forbidden()
@http.route('/website/reset_template', type='http', auth='user', methods=['POST'], website=True, csrf=False)
def reset_template(self, view_id, mode='soft', redirect='/', **kwargs):
diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py
index 7f670a81a46..12d2831c0d8 100644
--- a/addons/website/models/ir_ui_view.py
+++ b/addons/website/models/ir_ui_view.py
@@ -359,10 +359,7 @@ class View(models.Model):
"""
error = False
- try:
- self.visibility # avoid useless sudo() in case page is public
- except AccessError:
- self = self.sudo()
+ self = self.sudo()
if self.visibility and not request.env.user.has_group('website.group_website_designer'):
if (self.visibility == 'connected' and request.website.is_public_user()):
diff --git a/addons/website/models/website.py b/addons/website/models/website.py
index d230000c23f..c0c65070311 100644
--- a/addons/website/models/website.py
+++ b/addons/website/models/website.py
@@ -670,7 +670,7 @@ class Website(models.Model):
:param raise_if_not_found: should the method raise an error if no view found
:return: The view record or empty recordset
'''
- View = self.env['ir.ui.view']
+ View = self.env['ir.ui.view'].sudo()
view = View
if isinstance(view_id, str):
if 'website_id' in self._context:
@@ -700,7 +700,7 @@ class Website(models.Model):
@tools.ormcache_context(keys=('website_id',))
def _cache_customize_show_views(self):
- views = self.env['ir.ui.view'].with_context(active_test=False).search([('customize_show', '=', True)])
+ views = self.env['ir.ui.view'].with_context(active_test=False).sudo().search([('customize_show', '=', True)])
views = views.filter_duplicate()
return {v.key: v.active for v in views}
@@ -862,7 +862,7 @@ class Website(models.Model):
def get_website_pages(self, domain=[], order='name', limit=None):
domain += self.get_current_website().website_domain()
- pages = self.env['website.page'].search(domain, order=order, limit=limit)
+ pages = self.env['website.page'].sudo().search(domain, order=order, limit=limit)
return pages
def search_pages(self, needle=None, limit=None):
diff --git a/odoo/addons/base/models/ir_actions_report.py b/odoo/addons/base/models/ir_actions_report.py
index 23cd5a043e5..1cc1380d9da 100644
--- a/odoo/addons/base/models/ir_actions_report.py
+++ b/odoo/addons/base/models/ir_actions_report.py
@@ -552,7 +552,7 @@ class IrActionsReport(models.Model):
website = request.website
context = dict(context, translatable=context.get('lang') != request.env['ir.http']._get_default_lang().code)
- view_obj = self.env['ir.ui.view'].with_context(context)
+ view_obj = self.env['ir.ui.view'].sudo().with_context(context)
values.update(
time=time,
context_timestamp=lambda t: fields.Datetime.context_timestamp(self.with_context(tz=user.tz), t),
diff --git a/odoo/addons/base/models/ir_qweb.py b/odoo/addons/base/models/ir_qweb.py
index 5c45c91060f..10ed4ad7c2f 100644
--- a/odoo/addons/base/models/ir_qweb.py
+++ b/odoo/addons/base/models/ir_qweb.py
@@ -118,7 +118,7 @@ class IrQWeb(models.AbstractModel, QWeb):
if lang != env.context.get('lang'):
env = env(context=dict(env.context, lang=lang))
- template = env['ir.ui.view'].read_template(name)
+ template = env['ir.ui.view'].sudo().read_template(name)
# QWeb's `read_template` will check if one of the first children of
# what we send to it has a "t-name" attribute having `name` as value
@@ -126,7 +126,7 @@ class IrQWeb(models.AbstractModel, QWeb):
# with view ids or children view or children primary views, force it here.
def is_child_view(view_name):
view_id = self.env['ir.ui.view'].get_view_id(view_name)
- view = self.env['ir.ui.view'].browse(view_id)
+ view = self.env['ir.ui.view'].sudo().browse(view_id)
return view.inherit_id is not None
if isinstance(name, int) or is_child_view(name):
diff --git a/odoo/addons/base/models/ir_ui_view.py b/odoo/addons/base/models/ir_ui_view.py
index 9eb5ad4fc41..1acd844c7cb 100644
--- a/odoo/addons/base/models/ir_ui_view.py
+++ b/odoo/addons/base/models/ir_ui_view.py
@@ -864,7 +864,8 @@ actual arch.
""" Compute and set on node access rights based on view type. Specific
views can add additional specific rights like creating columns for
many2one-based grouping views. """
- Model = self.env[model]
+ # testing ACL as real user
+ Model = self.env[model].sudo(False)
is_base_model = self.env.context.get('base_model_name', model) == model
if node.tag in ('kanban', 'tree', 'form', 'activity'):
@@ -971,7 +972,7 @@ actual arch.
}
attrs['views'] = views
if field.comodel_name in self.env:
- Comodel = self.env[field.comodel_name]
+ Comodel = self.env[field.comodel_name].sudo(False)
node_info['attr_model'] = Comodel
if field.type in ('many2one', 'many2many'):
can_create = Comodel.check_access_rights('create', raise_exception=False)
@@ -1505,7 +1506,7 @@ actual arch.
return template
if '.' not in template:
raise ValueError('Invalid template id: %r' % template)
- view = self.search([('key', '=', template)], limit=1)
+ view = self.sudo().search([('key', '=', template)], limit=1)
return view and view.id or self.env['ir.model.data'].xmlid_to_res_id(template, raise_if_not_found=True)
def clear_cache(self):
@@ -1627,7 +1628,7 @@ actual arch.
time=time,
datetime=datetime,
relativedelta=relativedelta,
- xmlid=self.key,
+ xmlid=self.sudo().key,
viewid=self.id,
to_text=pycompat.to_text,
image_data_uri=image_data_uri,
diff --git a/odoo/models.py b/odoo/models.py
index c6b757bd304..6a1aefd3693 100644
--- a/odoo/models.py
+++ b/odoo/models.py
@@ -1463,7 +1463,7 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
@api.model
def _fields_view_get(self, view_id=None, view_type='form', toolbar=False, submenu=False):
- View = self.env['ir.ui.view']
+ View = self.env['ir.ui.view'].sudo()
result = {
'model': self._name,
'field_parent': False,
@@ -1528,7 +1528,8 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})):
* if some tag other than 'position' is found in parent view
:raise Invalid ArchitectureError: if there is view type other than form, tree, calendar, search etc defined on the structure
"""
- view = self.env['ir.ui.view'].browse(view_id)
+ self.check_access_rights('read')
+ view = self.env['ir.ui.view'].sudo().browse(view_id)
# Get the view arch and all other attributes describing the composition of the view
result = self._fields_view_get(view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu)