[IMP] *: make HTML fields with sanitized attributes edited as text-only

*: web_editor

When an HTML field sanitizes its attributes, it can still be filled with
HTML content (blocks, styling, power box commands) using the website
builder. This causes problems because those elements can then be broken
by the sanitizing.
It is possible to break elements so badly that the page cannot be
edited anymore to fix the problem.

This commit prevents the user from dropping snippet blocks inside the
content of such fields.

Steps to reproduce:
(Unless `slide.slide`'s `description` becomes
`sanitize_attributes=False` in the meantime.)
- Edit a single Course's slide.
- Drop a Carousel into the description field at the bottom.
- Save.

=> Carousel did not work.

Worse:
- Instead of the Carousel, drop a Countdown.

=> An error happens on each page reload, and the edit mode cannot be
reached anymore.

task-3293600

Part-of: odoo/odoo#120588
This commit is contained in:
Benoit Socias
2023-07-11 03:35:39 +02:00
parent 4978894a1b
commit 1bf2a891dd
2 changed files with 23 additions and 16 deletions
+19 -13
View File
@@ -403,19 +403,25 @@ class HTML(models.AbstractModel):
if options.get('inherit_branding'):
field = record._fields[field_name]
if field.sanitize:
if field.sanitize_overridable and not record.user_has_groups('base.group_sanitize_override'):
try:
field.convert_to_column(record[field_name], record)
except UserError:
# The field contains element(s) that would be removed if
# sanitized. It means that someone who was part of a
# group allowing to bypass the sanitation saved that
# field previously. Mark the field as not editable.
attrs['data-oe-sanitize-prevent-edition'] = 1
if not (field.sanitize_overridable and record.user_has_groups('base.group_sanitize_override')):
# Don't mark the field as 'sanitize' if the sanitize is
# defined as overridable and the user has the right to do so
attrs['data-oe-sanitize'] = 1 if field.sanitize_form else 'allow_form'
if field.sanitize_overridable:
if record.user_has_groups('base.group_sanitize_override'):
# Don't mark the field as 'sanitize' if the sanitize
# is defined as overridable and the user has the right
# to do so
return attrs
else:
try:
field.convert_to_column(record[field_name], record)
except UserError:
# The field contains element(s) that would be
# removed if sanitized. It means that someone who
# was part of a group allowing to bypass the
# sanitation saved that field previously. Mark the
# field as not editable.
attrs['data-oe-sanitize-prevent-edition'] = 1
return attrs
# The field edition is not fully prevented and the sanitation cannot be bypassed
attrs['data-oe-sanitize'] = 'no_block' if field.sanitize_attributes else 1 if field.sanitize_form else 'allow_form'
return attrs
@@ -3229,14 +3229,15 @@ var SnippetsMenu = Widget.extend({
* false: always fobid
*/
_insertDropzone: function ($hook, vertical, style, canBeSanitizedUnless) {
const skip = $hook.closest('[data-oe-sanitize="no_block"]').length;
let forbidSanitize;
if (canBeSanitizedUnless === 'form') {
forbidSanitize = $hook.closest('[data-oe-sanitize]:not([data-oe-sanitize="allow_form"])').length;
forbidSanitize = $hook.closest('[data-oe-sanitize]:not([data-oe-sanitize="allow_form"]):not([data-oe-sanitize="no_block"])').length;
} else {
forbidSanitize = !canBeSanitizedUnless && $hook.closest('[data-oe-sanitize]').length;
forbidSanitize = !canBeSanitizedUnless && $hook.closest('[data-oe-sanitize]:not([data-oe-sanitize="no_block"])').length;
}
var $dropzone = $('<div/>', {
'class': 'oe_drop_zone oe_insert' + (vertical ? ' oe_vertical' : '') +
'class': skip ? 'd-none' : 'oe_drop_zone oe_insert' + (vertical ? ' oe_vertical' : '') +
(forbidSanitize ? ' text-center oe_drop_zone_danger' : ''),
});
if (style) {