fix template variable handling
This commit is contained in:
@@ -29,6 +29,8 @@ from collections import defaultdict
|
|||||||
from copy import copy
|
from copy import copy
|
||||||
from email.message import MIMEPart
|
from email.message import MIMEPart
|
||||||
from email.policy import SMTPUTF8
|
from email.policy import SMTPUTF8
|
||||||
|
from html import escape
|
||||||
|
from urllib.parse import quote
|
||||||
|
|
||||||
from pyquarantine import replace_illegal_chars
|
from pyquarantine import replace_illegal_chars
|
||||||
from pyquarantine.base import CustomLogger
|
from pyquarantine.base import CustomLogger
|
||||||
@@ -231,12 +233,10 @@ class AddDisclaimer:
|
|||||||
self.text_template = f.read()
|
self.text_template = f.read()
|
||||||
|
|
||||||
with open(html_template, "r") as f:
|
with open(html_template, "r") as f:
|
||||||
html = BeautifulSoup(f.read(), "html.parser")
|
self.html_template = f.read()
|
||||||
|
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise RuntimeError(e)
|
raise RuntimeError(e)
|
||||||
body = html.find('body')
|
|
||||||
self.html_template = body or html
|
|
||||||
self.action = action.lower()
|
self.action = action.lower()
|
||||||
assert self.action in ["prepend", "append"], \
|
assert self.action in ["prepend", "append"], \
|
||||||
f"invalid action '{action}'"
|
f"invalid action '{action}'"
|
||||||
@@ -252,13 +252,20 @@ class AddDisclaimer:
|
|||||||
if text_content is None and html_content is None:
|
if text_content is None and html_content is None:
|
||||||
raise RuntimeError("message does not contain any body part")
|
raise RuntimeError("message does not contain any body part")
|
||||||
|
|
||||||
|
variables = defaultdict(str, milter.msginfo["vars"])
|
||||||
|
variables["ENVELOPE_FROM"] = escape(
|
||||||
|
milter.msginfo["mailfrom"], quote=False)
|
||||||
|
variables["ENVELOPE_FROM_URL"] = escape(
|
||||||
|
quote(milter.msginfo["mailfrom"]), quote=False)
|
||||||
|
|
||||||
if text_content is not None:
|
if text_content is not None:
|
||||||
logger.info(f"{self.action} text disclaimer")
|
logger.info(f"{self.action} text disclaimer")
|
||||||
|
text_template = self.text_template.format_map(variables)
|
||||||
|
|
||||||
if self.action == "prepend":
|
if self.action == "prepend":
|
||||||
content = f"{self.text_template}{text_content}"
|
content = f"{text_template}{text_content}"
|
||||||
else:
|
else:
|
||||||
content = f"{text_content}{self.text_template}"
|
content = f"{text_content}{text_template}"
|
||||||
|
|
||||||
text_body.set_content(
|
text_body.set_content(
|
||||||
content.encode(), maintype="text", subtype="plain")
|
content.encode(), maintype="text", subtype="plain")
|
||||||
@@ -269,17 +276,19 @@ class AddDisclaimer:
|
|||||||
logger.info(f"{self.action} html disclaimer")
|
logger.info(f"{self.action} html disclaimer")
|
||||||
|
|
||||||
soup = BeautifulSoup(html_content, "html.parser")
|
soup = BeautifulSoup(html_content, "html.parser")
|
||||||
|
|
||||||
body = soup.find('body')
|
body = soup.find('body')
|
||||||
if not body:
|
if not body:
|
||||||
body = soup
|
body = soup
|
||||||
elif _has_content_before_body_tag(soup):
|
elif _has_content_before_body_tag(soup):
|
||||||
body = soup
|
body = soup
|
||||||
|
|
||||||
|
html_template = self.html_template.format_map(variables)
|
||||||
|
html_template = BeautifulSoup(html_template, "html.parser")
|
||||||
|
html_template = html_template.find("body") or html_template
|
||||||
if self.action == "prepend":
|
if self.action == "prepend":
|
||||||
body.insert(0, copy(self.html_template))
|
body.insert(0, html_template)
|
||||||
else:
|
else:
|
||||||
body.append(self.html_template)
|
body.append(html_template)
|
||||||
|
|
||||||
html_body.set_content(
|
html_body.set_content(
|
||||||
str(soup).encode(), maintype="text", subtype="html")
|
str(soup).encode(), maintype="text", subtype="html")
|
||||||
|
|||||||
@@ -258,26 +258,27 @@ class EMailNotification(BaseNotification):
|
|||||||
|
|
||||||
# generate dict containing all template variables
|
# generate dict containing all template variables
|
||||||
variables = defaultdict(str, template_vars)
|
variables = defaultdict(str, template_vars)
|
||||||
variables.update({
|
variables["HTML_TEXT"] = sanitized_text
|
||||||
"HTML_TEXT": sanitized_text,
|
variables["ENVELOPE_FROM"] = escape(mailfrom, quote=False)
|
||||||
"FROM": escape(msg["from"], quote=False),
|
variables["ENVELOPE_FROM_URL"] = escape(
|
||||||
"ENVELOPE_FROM": escape(mailfrom, quote=False),
|
quote(mailfrom), quote=False)
|
||||||
"ENVELOPE_FROM_URL": escape(quote(mailfrom),
|
variables["ENVELOPE_TO"] = escape(recipient, quote=False)
|
||||||
quote=False),
|
variables["ENVELOPE_TO_URL"] = escape(quote(recipient))
|
||||||
"TO": escape(msg["to"], quote=False),
|
for field in ["from", "to", "subject"]:
|
||||||
"ENVELOPE_TO": escape(recipient, quote=False),
|
value = msg[field]
|
||||||
"ENVELOPE_TO_URL": escape(quote(recipient)),
|
if not value:
|
||||||
"SUBJECT": escape(msg["subject"], quote=False)})
|
continue
|
||||||
|
variables[field.upper()] = escape(value, quote=False)
|
||||||
|
|
||||||
# parse template
|
# parse template
|
||||||
htmltext = self.template.format_map(variables)
|
htmltext = self.template.format_map(variables)
|
||||||
|
|
||||||
newmsg = MIMEMultipart('related')
|
newmsg = MIMEMultipart('related')
|
||||||
newmsg["From"] = self.from_header.format_map(
|
newmsg["From"] = self.from_header.format_map(
|
||||||
defaultdict(str, FROM=msg["from"]))
|
defaultdict(str, FROM=variables["FROM"]))
|
||||||
newmsg["To"] = msg["to"]
|
newmsg["To"] = variables["TO"]
|
||||||
newmsg["Subject"] = self.subject.format_map(
|
newmsg["Subject"] = self.subject.format_map(
|
||||||
defaultdict(str, SUBJECT=msg["subject"]))
|
defaultdict(str, SUBJECT=variables["SUBJECT"]))
|
||||||
newmsg["Date"] = email.utils.formatdate()
|
newmsg["Date"] = email.utils.formatdate()
|
||||||
newmsg.attach(MIMEText(htmltext, "html", 'UTF-8'))
|
newmsg.attach(MIMEText(htmltext, "html", 'UTF-8'))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user