Skip to content

Commit

Permalink
feat: allow more HTML tags in report description (#20908)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktmud committed Jul 29, 2022
1 parent e7acb1a commit e739ff5
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 3 deletions.
38 changes: 35 additions & 3 deletions superset/reports/notifications/email.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,31 @@
TABLE_TAGS = ["table", "th", "tr", "td", "thead", "tbody", "tfoot"]
TABLE_ATTRIBUTES = ["colspan", "rowspan", "halign", "border", "class"]

ALLOWED_TAGS = [
"a",
"abbr",
"acronym",
"b",
"blockquote",
"br",
"code",
"div",
"em",
"i",
"li",
"ol",
"p",
"strong",
"ul",
] + TABLE_TAGS

ALLOWED_ATTRIBUTES = {
"a": ["href", "title"],
"abbr": ["title"],
"acronym": ["title"],
**{tag: TABLE_ATTRIBUTES for tag in TABLE_TAGS},
}


@dataclass
class EmailContent:
Expand Down Expand Up @@ -82,13 +107,19 @@ def _get_content(self) -> EmailContent:
}

# Strip any malicious HTML from the description
description = bleach.clean(self._content.description or "")
description = bleach.clean(
self._content.description or "",
tags=ALLOWED_TAGS,
attributes=ALLOWED_ATTRIBUTES,
)

# Strip malicious HTML from embedded data, allowing only table elements
if self._content.embedded_data is not None:
df = self._content.embedded_data
html_table = bleach.clean(
df.to_html(na_rep="", index=True),
df.to_html(na_rep="", index=True, escape=True),
# pandas will escape the HTML in cells already, so passing
# more allowed tags here will not work
tags=TABLE_TAGS,
attributes=TABLE_ATTRIBUTES,
)
Expand Down Expand Up @@ -127,7 +158,8 @@ def _get_content(self) -> EmailContent:
</style>
</head>
<body>
<p>{description}</p>
<div>{description}</div>
<br>
<b><a href="{url}">{call_to_action}</a></b><p></p>
{html_table}
{img_tag}
Expand Down
47 changes: 47 additions & 0 deletions tests/unit_tests/notifications/email_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import pandas as pd
from flask.ctx import AppContext


def test_render_description_with_html(app_context: AppContext) -> None:
# `superset.models.helpers`, a dependency of following imports,
# requires app context
from superset.reports.models import ReportRecipients, ReportRecipientType
from superset.reports.notifications.base import NotificationContent
from superset.reports.notifications.email import EmailNotification

content = NotificationContent(
name="test alert",
embedded_data=pd.DataFrame(
{
"A": [1, 2, 3],
"B": [4, 5, 6],
"C": ["111", "222", '<a href="http://www.example.com">333</a>'],
}
),
description='<p>This is <a href="#">a test</a> alert</p><br />',
)
email_body = (
EmailNotification(
recipient=ReportRecipients(type=ReportRecipientType.EMAIL), content=content
)
._get_content()
.body
)
assert '<p>This is <a href="#">a test</a> alert</p><br>' in email_body
assert '<td>&lt;a href="http://www.example.com"&gt;333&lt;/a&gt;</td>' in email_body

0 comments on commit e739ff5

Please sign in to comment.