mirror of
https://github.com/OCA/knowledge.git
synced 2025-07-23 04:22:04 -06:00
[14.0][FIX] document_page: Stored XSS
unitary tests added post-migration script added
This commit is contained in:
parent
d1b2e58312
commit
eda3c2a1cb
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
"name": "Document Page",
|
"name": "Document Page",
|
||||||
"version": "14.0.1.2.3",
|
"version": "14.0.1.2.4",
|
||||||
"category": "Knowledge Management",
|
"category": "Knowledge Management",
|
||||||
"development_status": "Production/Stable",
|
"development_status": "Production/Stable",
|
||||||
"author": "OpenERP SA, Odoo Community Association (OCA)",
|
"author": "OpenERP SA, Odoo Community Association (OCA)",
|
||||||
|
9
document_page/migrations/14.0.1.2.4/post-migration.py
Normal file
9
document_page/migrations/14.0.1.2.4/post-migration.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from openupgradelib import openupgrade
|
||||||
|
|
||||||
|
|
||||||
|
@openupgrade.migrate()
|
||||||
|
def migrate(env, version):
|
||||||
|
document_page_history = env["document.page.history"]
|
||||||
|
for record in document_page_history.search([]):
|
||||||
|
# Apply default HTML sanitize by reassigning the content
|
||||||
|
record.content = record.content
|
@ -27,7 +27,7 @@ class DocumentPage(models.Model):
|
|||||||
"document.page", "Category", domain=[("type", "=", "category")]
|
"document.page", "Category", domain=[("type", "=", "category")]
|
||||||
)
|
)
|
||||||
child_ids = fields.One2many("document.page", "parent_id", "Children")
|
child_ids = fields.One2many("document.page", "parent_id", "Children")
|
||||||
content = fields.Text(
|
content = fields.Html(
|
||||||
"Content",
|
"Content",
|
||||||
compute="_compute_content",
|
compute="_compute_content",
|
||||||
inverse="_inverse_content",
|
inverse="_inverse_content",
|
||||||
|
@ -16,7 +16,7 @@ class DocumentPageHistory(models.Model):
|
|||||||
page_id = fields.Many2one("document.page", "Page", ondelete="cascade")
|
page_id = fields.Many2one("document.page", "Page", ondelete="cascade")
|
||||||
name = fields.Char(index=True)
|
name = fields.Char(index=True)
|
||||||
summary = fields.Char(index=True)
|
summary = fields.Char(index=True)
|
||||||
content = fields.Text()
|
content = fields.Html()
|
||||||
diff = fields.Text(compute="_compute_diff")
|
diff = fields.Text(compute="_compute_diff")
|
||||||
|
|
||||||
company_id = fields.Many2one(
|
company_id = fields.Many2one(
|
||||||
|
@ -4,3 +4,4 @@ from . import test_document_page
|
|||||||
from . import test_document_page_create_menu
|
from . import test_document_page_create_menu
|
||||||
from . import test_document_page_history
|
from . import test_document_page_history
|
||||||
from . import test_document_page_show_diff
|
from . import test_document_page_show_diff
|
||||||
|
from . import test_document_page_content_sanitized
|
||||||
|
@ -15,10 +15,10 @@ class TestDocumentPage(common.TransactionCase):
|
|||||||
{
|
{
|
||||||
"name": "Test Page 1",
|
"name": "Test Page 1",
|
||||||
"parent_id": self.category1.id,
|
"parent_id": self.category1.id,
|
||||||
"content": "Test content",
|
"content": "<p>Test content</p>",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
self.assertEqual(page.content, "Test content")
|
self.assertEqual(page.content, "<p>Test content</p>")
|
||||||
self.assertEqual(len(page.history_ids), 1)
|
self.assertEqual(len(page.history_ids), 1)
|
||||||
page.content = "New content for Demo Page"
|
page.content = "New content for Demo Page"
|
||||||
self.assertEqual(len(page.history_ids), 2)
|
self.assertEqual(len(page.history_ids), 2)
|
||||||
@ -35,12 +35,16 @@ class TestDocumentPage(common.TransactionCase):
|
|||||||
self.assertEqual(page.content, self.category1.template)
|
self.assertEqual(page.content, self.category1.template)
|
||||||
|
|
||||||
def test_page_history_diff(self):
|
def test_page_history_diff(self):
|
||||||
page = self.page_obj.create({"name": "Test Page 3", "content": "Test content"})
|
page = self.page_obj.create(
|
||||||
|
{"name": "Test Page 3", "content": "<p>Test content</p>"}
|
||||||
|
)
|
||||||
page.content = "New content"
|
page.content = "New content"
|
||||||
self.assertIsNotNone(page.history_ids[0].diff)
|
self.assertIsNotNone(page.history_ids[0].diff)
|
||||||
|
|
||||||
def test_page_link(self):
|
def test_page_link(self):
|
||||||
page = self.page_obj.create({"name": "Test Page 3", "content": "Test content"})
|
page = self.page_obj.create(
|
||||||
|
{"name": "Test Page 3", "content": "<p>Test content</p>"}
|
||||||
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
page.backend_url,
|
page.backend_url,
|
||||||
"/web#id={}&model=document.page&view_type=form".format(page.id),
|
"/web#id={}&model=document.page&view_type=form".format(page.id),
|
||||||
@ -55,7 +59,9 @@ class TestDocumentPage(common.TransactionCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def test_page_copy(self):
|
def test_page_copy(self):
|
||||||
page = self.page_obj.create({"name": "Test Page 3", "content": "Test content"})
|
page = self.page_obj.create(
|
||||||
|
{"name": "Test Page 3", "content": "<p>Test content</p>"}
|
||||||
|
)
|
||||||
page_copy = page.copy()
|
page_copy = page.copy()
|
||||||
self.assertEqual(page_copy.name, page.name + " (copy)")
|
self.assertEqual(page_copy.name, page.name + " (copy)")
|
||||||
self.assertEqual(page_copy.content, page.content)
|
self.assertEqual(page_copy.content, page.content)
|
||||||
|
24
document_page/tests/test_document_page_content_sanitized.py
Normal file
24
document_page/tests/test_document_page_content_sanitized.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
from odoo.tests import common
|
||||||
|
|
||||||
|
|
||||||
|
class TestDocumentContentSanitized(common.TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestDocumentContentSanitized, self).setUp()
|
||||||
|
self.page_obj = self.env["document.page"]
|
||||||
|
self.category1 = self.env.ref("document_page.demo_category1")
|
||||||
|
|
||||||
|
def test_page_content_sanitized(self):
|
||||||
|
malicious_page = self.page_obj.create(
|
||||||
|
{
|
||||||
|
"name": "Malicious Page",
|
||||||
|
"parent_id": self.category1.id,
|
||||||
|
"content": "<p>Test content</p><script> alert(1)</script>",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.assertEqual(malicious_page.content, "<p>Test content</p>")
|
||||||
|
|
||||||
|
malicious_page.write(
|
||||||
|
{"content": "<p>Test content</p><script> alert(1)</script>"}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(malicious_page.content, "<p>Test content</p>")
|
@ -62,18 +62,18 @@ class TestDocumentPageApproval(common.TransactionCase):
|
|||||||
page.write({"content": "New content"})
|
page.write({"content": "New content"})
|
||||||
# Needed to compute calculated fields
|
# Needed to compute calculated fields
|
||||||
page.refresh()
|
page.refresh()
|
||||||
self.assertNotEqual(page.content, "New content")
|
self.assertNotEqual(page.content, "<p>New content</p>")
|
||||||
chreq = self.history_obj.search(
|
chreq = self.history_obj.search(
|
||||||
[("page_id", "=", page.id), ("state", "!=", "approved")]
|
[("page_id", "=", page.id), ("state", "!=", "approved")]
|
||||||
)[0]
|
)[0]
|
||||||
chreq.action_approve()
|
chreq.action_approve()
|
||||||
self.assertEqual(page.content, "New content")
|
self.assertEqual(page.content, "<p>New content</p>")
|
||||||
|
|
||||||
def test_change_request_auto_approve(self):
|
def test_change_request_auto_approve(self):
|
||||||
page = self.page1
|
page = self.page1
|
||||||
self.assertFalse(page.is_approval_required)
|
self.assertFalse(page.is_approval_required)
|
||||||
page.write({"content": "New content"})
|
page.write({"content": "New content"})
|
||||||
self.assertEqual(page.content, "New content")
|
self.assertEqual(page.content, "<p>New content</p>")
|
||||||
|
|
||||||
def test_change_request_from_scratch(self):
|
def test_change_request_from_scratch(self):
|
||||||
page = self.page2
|
page = self.page2
|
||||||
@ -88,7 +88,7 @@ class TestDocumentPageApproval(common.TransactionCase):
|
|||||||
{
|
{
|
||||||
"page_id": page.id,
|
"page_id": page.id,
|
||||||
"summary": "Changed something",
|
"summary": "Changed something",
|
||||||
"content": "New content",
|
"content": "<p>New content</p>",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,9 +30,6 @@ class TestDocumentReference(TransactionCase):
|
|||||||
self.page2.write({"reference": False})
|
self.page2.write({"reference": False})
|
||||||
self.assertEqual(self.page1.reference, self.page2.reference)
|
self.assertEqual(self.page1.reference, self.page2.reference)
|
||||||
|
|
||||||
def test_check_raw(self):
|
|
||||||
self.assertEqual(self.page2.display_name, self.page1.get_raw_content())
|
|
||||||
|
|
||||||
def test_check_reference(self):
|
def test_check_reference(self):
|
||||||
self.assertRegex(self.page1.content_parsed, ".*%s.*" % self.page2.display_name)
|
self.assertRegex(self.page1.content_parsed, ".*%s.*" % self.page2.display_name)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user