# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from unittest.mock import patch
import email.policy
import email.message
import re
import threading
from odoo.addons.base.models.ir_mail_server import extract_rfc2822_addresses
from odoo.tests.common import BaseCase, TransactionCase
from odoo.tests import tagged
from odoo.tools import (
is_html_empty, html_to_inner_content, html_sanitize, append_content_to_html, plaintext2html,
email_domain_normalize, email_normalize, email_split, email_split_and_format, html2plaintext,
misc, formataddr, email_anonymize,
prepend_html_content,
config,
)
from . import test_mail_examples
class TestSanitizer(BaseCase):
""" Test the html sanitizer that filters html to remove unwanted attributes """
def test_basic_sanitizer(self):
cases = [
("yop", "
Merci à l'intérêt pour notre produit.nous vous contacterons bientôt. Merci
"), # unicode
]
for content, expected in cases:
html = html_sanitize(content)
self.assertEqual(html, expected, 'html_sanitize is broken')
def test_evil_malicious_code(self):
# taken from https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#Tests
cases = [
("
Here is a test mail
With a break line
Then two
From: Mitchell Admin <dummy@example.com>
Sent: Monday, November 20, 2023 8:34 AM
To: test user <dummy@example.com>
Subject: test (#23)
"""
expected = """
Here is a test mail
With a break line
Then two
From: Mitchell Admin <dummy@example.com>
Sent: Monday, November 20, 2023 8:34 AM
To: test user <dummy@example.com>
Subject: test (#23)
"""
result = html_sanitize(case)
self.assertEqual(result, expected)
def test_sanitize_unescape_emails(self):
not_emails = [
'
cat
',
'

']
for not_email in not_emails:
sanitized = html_sanitize(not_email)
left_part = not_email.split('>')[0] # take only left part, as the sanitizer could add data information on node
self.assertNotIn(misc.html_escape(not_email), sanitized, 'html_sanitize stripped emails of original html')
self.assertIn(left_part, sanitized)
def test_style_parsing(self):
test_data = [
(
'
Coin coin ',
['background-color:red', 'Coin coin'],
['position', 'top', 'left']
), (
"""
youplaboum
""",
['font-size:30px', 'youplaboum'],
['some-property', 'top', 'cheval']
), (
'
Coincoin',
[],
['width']
)
]
for test, in_lst, out_lst in test_data:
new_html = html_sanitize(test, sanitize_attributes=False, sanitize_style=True, strip_style=False, strip_classes=False)
for text in in_lst:
self.assertIn(text, new_html)
for text in out_lst:
self.assertNotIn(text, new_html)
# style should not be sanitized if removed
new_html = html_sanitize(test_data[0][0], sanitize_attributes=False, strip_style=True, strip_classes=False)
self.assertEqual(new_html, u'
Coin coin ')
def test_style_class(self):
html = html_sanitize(test_mail_examples.REMOVE_CLASS, sanitize_attributes=True, sanitize_style=True, strip_classes=True)
for ext in test_mail_examples.REMOVE_CLASS_IN:
self.assertIn(ext, html)
for ext in test_mail_examples.REMOVE_CLASS_OUT:
self.assertNotIn(ext, html,)
def test_style_class_only(self):
html = html_sanitize(test_mail_examples.REMOVE_CLASS, sanitize_attributes=False, sanitize_style=True, strip_classes=True)
for ext in test_mail_examples.REMOVE_CLASS_IN:
self.assertIn(ext, html)
for ext in test_mail_examples.REMOVE_CLASS_OUT:
self.assertNotIn(ext, html,)
def test_edi_source(self):
html = html_sanitize(test_mail_examples.EDI_LIKE_HTML_SOURCE)
self.assertIn(
'font-family: \'Lucida Grande\', Ubuntu, Arial, Verdana, sans-serif;', html,
'html_sanitize removed valid styling')
self.assertIn(
'src="https://www.paypal.com/en_US/i/btn/btn_paynowCC_LG.gif"', html,
'html_sanitize removed valid img')
self.assertNotIn('