fix template variable handling

This commit is contained in:
2021-10-04 12:08:16 +02:00
parent 91f5b34795
commit 32bebf873d
2 changed files with 31 additions and 21 deletions

View File

@@ -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")

View File

@@ -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'))