From 388c222c6c4bb7e2fe3e67009b248359ae0fd3db Mon Sep 17 00:00:00 2001 From: fja-odoo Date: Tue, 31 Mar 2020 14:04:15 +0000 Subject: [PATCH] [IMP] base, *: allow html fields not to sanitize forms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * = event, website_event_track, website_sale, website_hr_recruitment, website_livechat, website_sale, website_slides The option to sanitize or not the forms was not available, this will allow better flexibility on whether forms should be sanitized or not on an HTML field. Also we use this new param to allow forms to be added on some already existing html fields where forms where sanitized out. task-2209554 closes odoo/odoo#47318 Signed-off-by: Jérémy Kersten (jke) --- addons/event/models/event_event.py | 2 +- addons/sale_quotation_builder/models/sale_order.py | 4 ++-- addons/sale_quotation_builder/models/sale_order_template.py | 4 ++-- addons/website_event_track/models/event_track.py | 2 +- addons/website_hr_recruitment/models/hr_recruitment.py | 2 +- addons/website_livechat/models/im_livechat.py | 2 +- addons/website_sale/models/product.py | 4 ++-- addons/website_slides/models/slide_channel.py | 2 +- addons/website_slides/models/slide_slide.py | 2 +- odoo/fields.py | 3 +++ odoo/tools/mail.py | 4 ++-- 11 files changed, 17 insertions(+), 14 deletions(-) diff --git a/addons/event/models/event_event.py b/addons/event/models/event_event.py index 7acafd5b7a6..ff9304ff954 100644 --- a/addons/event/models/event_event.py +++ b/addons/event/models/event_event.py @@ -103,7 +103,7 @@ class EventEvent(models.Model): name = fields.Char(string='Event', translate=True, required=True) note = fields.Text(string='Note') - description = fields.Html(string='Description', translate=html_translate, sanitize_attributes=False) + description = fields.Html(string='Description', translate=html_translate, sanitize_attributes=False, sanitize_form=False) active = fields.Boolean(default=True) user_id = fields.Many2one( 'res.users', string='Responsible', tracking=True, diff --git a/addons/sale_quotation_builder/models/sale_order.py b/addons/sale_quotation_builder/models/sale_order.py index 9cd20c4b93c..22c88388fc5 100644 --- a/addons/sale_quotation_builder/models/sale_order.py +++ b/addons/sale_quotation_builder/models/sale_order.py @@ -8,7 +8,7 @@ from odoo.tools.translate import html_translate class SaleOrder(models.Model): _inherit = 'sale.order' - website_description = fields.Html('Website Description', sanitize_attributes=False, translate=html_translate) + website_description = fields.Html('Website Description', sanitize_attributes=False, translate=html_translate, sanitize_form=False) @api.onchange('partner_id') def onchange_update_description_lang(self): @@ -40,7 +40,7 @@ class SaleOrder(models.Model): class SaleOrderLine(models.Model): _inherit = "sale.order.line" - website_description = fields.Html('Website Description', sanitize=False, translate=html_translate) + website_description = fields.Html('Website Description', sanitize=False, translate=html_translate, sanitize_form=False) @api.model def create(self, values): diff --git a/addons/sale_quotation_builder/models/sale_order_template.py b/addons/sale_quotation_builder/models/sale_order_template.py index d2240caa574..c7fe6a08f6a 100644 --- a/addons/sale_quotation_builder/models/sale_order_template.py +++ b/addons/sale_quotation_builder/models/sale_order_template.py @@ -8,7 +8,7 @@ from odoo.tools.translate import html_translate class SaleOrderTemplate(models.Model): _inherit = "sale.order.template" - website_description = fields.Html('Website Description', translate=html_translate, sanitize_attributes=False) + website_description = fields.Html('Website Description', translate=html_translate, sanitize_attributes=False, sanitize_form=False) def open_template(self): self.ensure_one() @@ -22,7 +22,7 @@ class SaleOrderTemplate(models.Model): class SaleOrderTemplateLine(models.Model): _inherit = "sale.order.template.line" - website_description = fields.Html('Website Description', related='product_id.product_tmpl_id.quotation_only_description', translate=html_translate, readonly=False) + website_description = fields.Html('Website Description', related='product_id.product_tmpl_id.quotation_only_description', translate=html_translate, readonly=False, sanitize_form=False) @api.onchange('product_id') def _onchange_product_id(self): diff --git a/addons/website_event_track/models/event_track.py b/addons/website_event_track/models/event_track.py index 6a75af9b40a..57b635ed019 100644 --- a/addons/website_event_track/models/event_track.py +++ b/addons/website_event_track/models/event_track.py @@ -68,7 +68,7 @@ class Track(models.Model): " * Grey is the default situation\n" " * Red indicates something is preventing the progress of this track\n" " * Green indicates the track is ready to be pulled to the next stage") - description = fields.Html(translate=html_translate, sanitize_attributes=False) + description = fields.Html(translate=html_translate, sanitize_attributes=False, sanitize_form=False) date = fields.Datetime('Track Date') date_end = fields.Datetime('Track End Date', compute='_compute_end_date', store=True) duration = fields.Float('Duration', default=1.5, help="Track duration in hours.") diff --git a/addons/website_hr_recruitment/models/hr_recruitment.py b/addons/website_hr_recruitment/models/hr_recruitment.py index 4f250a623e1..f03ab2e054a 100644 --- a/addons/website_hr_recruitment/models/hr_recruitment.py +++ b/addons/website_hr_recruitment/models/hr_recruitment.py @@ -44,7 +44,7 @@ class Job(models.Model): default_description = self.env["ir.model.data"].xmlid_to_object("website_hr_recruitment.default_website_description") return (default_description.render() if default_description else "") - website_description = fields.Html('Website description', translate=html_translate, sanitize_attributes=False, default=_get_default_website_description, prefetch=False) + website_description = fields.Html('Website description', translate=html_translate, sanitize_attributes=False, default=_get_default_website_description, prefetch=False, sanitize_form=False) def _compute_website_url(self): super(Job, self)._compute_website_url() diff --git a/addons/website_livechat/models/im_livechat.py b/addons/website_livechat/models/im_livechat.py index 282966c90cc..5e3bdbabfc6 100644 --- a/addons/website_livechat/models/im_livechat.py +++ b/addons/website_livechat/models/im_livechat.py @@ -16,4 +16,4 @@ class ImLivechatChannel(models.Model): for channel in self: channel.website_url = "/livechat/channel/%s" % (slug(channel),) - website_description = fields.Html("Website description", default=False, help="Description of the channel displayed on the website page", sanitize_attributes=False, translate=html_translate) + website_description = fields.Html("Website description", default=False, help="Description of the channel displayed on the website page", sanitize_attributes=False, translate=html_translate, sanitize_form=False) diff --git a/addons/website_sale/models/product.py b/addons/website_sale/models/product.py index 0f3bc938ebe..15078bb4b18 100644 --- a/addons/website_sale/models/product.py +++ b/addons/website_sale/models/product.py @@ -149,7 +149,7 @@ class ProductPublicCategory(models.Model): child_id = fields.One2many('product.public.category', 'parent_id', string='Children Categories') parents_and_self = fields.Many2many('product.public.category', compute='_compute_parents_and_self') sequence = fields.Integer(help="Gives the sequence order when displaying a list of product categories.", index=True, default=_default_sequence) - website_description = fields.Html('Category Description', sanitize_attributes=False, translate=html_translate) + website_description = fields.Html('Category Description', sanitize_attributes=False, translate=html_translate, sanitize_form=False) product_tmpl_ids = fields.Many2many('product.template', relation='product_public_category_product_template_rel') @api.constrains('parent_id') @@ -177,7 +177,7 @@ class ProductTemplate(models.Model): _mail_post_access = 'read' _check_company_auto = True - website_description = fields.Html('Description for the website', sanitize_attributes=False, translate=html_translate) + website_description = fields.Html('Description for the website', sanitize_attributes=False, translate=html_translate, sanitize_form=False) alternative_product_ids = fields.Many2many( 'product.template', 'product_alternative_rel', 'src_id', 'dest_id', check_company=True, string='Alternative Products', help='Suggest alternatives to your customer (upsell strategy). ' diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index cb6ea814a18..43a496513ad 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -90,7 +90,7 @@ class Channel(models.Model): active = fields.Boolean(default=True) description = fields.Text('Description', translate=True, help="The description that is displayed on top of the course page, just below the title") description_short = fields.Text('Short Description', translate=True, help="The description that is displayed on the course card") - description_html = fields.Html('Detailed Description', translate=tools.html_translate, sanitize_attributes=False) + description_html = fields.Html('Detailed Description', translate=tools.html_translate, sanitize_attributes=False, sanitize_form=False) channel_type = fields.Selection([ ('documentation', 'Documentation'), ('training', 'Training')], string="Course type", default="documentation", required=True) diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index c3bf14af5a2..b99a3723963 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -172,7 +172,7 @@ class Slide(models.Model): slide_resource_ids = fields.One2many('slide.slide.resource', 'slide_id', string="Additional Resource for this slide") slide_resource_downloadable = fields.Boolean('Allow Download', default=False, help="Allow the user to download the content of the slide.") mime_type = fields.Char('Mime-type') - html_content = fields.Html("HTML Content", help="Custom HTML content for slides of type 'Web Page'.", translate=True) + html_content = fields.Html("HTML Content", help="Custom HTML content for slides of type 'Web Page'.", translate=True, sanitize_form=False) # website website_id = fields.Many2one(related='channel_id.website_id', readonly=True) date_published = fields.Datetime('Publish Date', readonly=True, tracking=True) diff --git a/odoo/fields.py b/odoo/fields.py index 9a54022c986..38dd2b8d833 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -1627,6 +1627,7 @@ class Html(_String): 'sanitize_tags': True, # whether to sanitize tags (only a white list of attributes is accepted) 'sanitize_attributes': True, # whether to sanitize attributes (only a white list of attributes is accepted) 'sanitize_style': False, # whether to sanitize style attributes + 'sanitize_form': True, # whether to sanitize forms 'strip_style': False, # whether to strip style attributes (removed and therefore not sanitized) 'strip_classes': False, # whether to strip classes attributes } @@ -1662,6 +1663,7 @@ class Html(_String): sanitize_tags=self.sanitize_tags, sanitize_attributes=self.sanitize_attributes, sanitize_style=self.sanitize_style, + sanitize_form=self.sanitize_form, strip_style=self.strip_style, strip_classes=self.strip_classes) return value @@ -1675,6 +1677,7 @@ class Html(_String): sanitize_tags=self.sanitize_tags, sanitize_attributes=self.sanitize_attributes, sanitize_style=self.sanitize_style, + sanitize_form=self.sanitize_form, strip_style=self.strip_style, strip_classes=self.strip_classes) return value diff --git a/odoo/tools/mail.py b/odoo/tools/mail.py index d1bc961e8ff..8738f132f72 100644 --- a/odoo/tools/mail.py +++ b/odoo/tools/mail.py @@ -166,7 +166,7 @@ class _Cleaner(clean.Cleaner): return super(_Cleaner, self).allow_element(el) -def html_sanitize(src, silent=True, sanitize_tags=True, sanitize_attributes=False, sanitize_style=False, strip_style=False, strip_classes=False): +def html_sanitize(src, silent=True, sanitize_tags=True, sanitize_attributes=False, sanitize_style=False, sanitize_form=True, strip_style=False, strip_classes=False): if not src: return src src = ustr(src, errors='replace') @@ -184,7 +184,7 @@ def html_sanitize(src, silent=True, sanitize_tags=True, sanitize_attributes=Fals 'page_structure': True, 'style': strip_style, # True = remove style tags/attrs 'sanitize_style': sanitize_style, # True = sanitize styling - 'forms': True, # True = remove form tags + 'forms': sanitize_form, # True = remove form tags 'remove_unknown_tags': False, 'comments': False, 'processing_instructions': False