Add dynamic template variables according to regex
This commit is contained in:
@@ -119,9 +119,13 @@ class QuarantineMilter(Milter.Base):
|
||||
|
||||
# check email header against quarantine regex
|
||||
self.logger.debug("{}: {}: checking header against regex '{}'".format(self.queueid, quarantine["name"], quarantine["regex"]))
|
||||
if quarantine["regex_compiled"].match(header):
|
||||
match = quarantine["regex_compiled"].search(header)
|
||||
if match:
|
||||
self.logger.debug("{}: {}: header matched regex".format(self.queueid, quarantine["name"]))
|
||||
|
||||
if "subgroups" not in quarantine.keys():
|
||||
# save subgroups of match into the quarantine object for later use as template variables
|
||||
quarantine["subgroups"] = match.groups(default="")
|
||||
quarantine["named_subgroups"] = match.groupdict(default="")
|
||||
# check for whitelisted recipients
|
||||
whitelist = quarantine["whitelist_obj"]
|
||||
if whitelist != None:
|
||||
@@ -212,7 +216,8 @@ class QuarantineMilter(Milter.Base):
|
||||
# add email to quarantine
|
||||
self.logger.info("{}: adding to quarantine '{}' for: {}".format(self.queueid, quarantine["name"], ", ".join(recipients)))
|
||||
try:
|
||||
quarantine_id = quarantine["quarantine_obj"].add(self.queueid, self.mailfrom, recipients, self.subject, fp=self.fp)
|
||||
quarantine_id = quarantine["quarantine_obj"].add(self.queueid, self.mailfrom, recipients, self.subject, self.fp,
|
||||
quarantine["subgroups"], quarantine["named_subgroups"])
|
||||
except RuntimeError as e:
|
||||
self.logger.error("{}: unable to add to quarantine '{}': {}".format(self.queueid, quarantine["name"], e))
|
||||
return Milter.TEMPFAIL
|
||||
@@ -222,7 +227,8 @@ class QuarantineMilter(Milter.Base):
|
||||
# notify
|
||||
self.logger.info("{}: sending notification for quarantine '{}' to: {}".format(self.queueid, quarantine["name"], ", ".join(recipients)))
|
||||
try:
|
||||
quarantine["notification_obj"].notify(self.queueid, quarantine_id, self.subject, self.mailfrom, recipients, fp=self.fp)
|
||||
quarantine["notification_obj"].notify(self.queueid, quarantine_id, self.subject, self.mailfrom, recipients, self.fp,
|
||||
quarantine["subgroups"], quarantine["named_subgroups"])
|
||||
except RuntimeError as e:
|
||||
self.logger.error("{}: unable to send notification for quarantine '{}': {}".format(self.queueid, quarantine["name"], e))
|
||||
return Milter.TEMPFAIL
|
||||
@@ -316,7 +322,7 @@ def generate_milter_config(configtest=False, config_files=[]):
|
||||
|
||||
# pre-compile regex
|
||||
logger.debug("{}: compiling regex '{}'".format(quarantine_name, config["regex"]))
|
||||
config["regex_compiled"] = re.compile(config["regex"])
|
||||
config["regex_compiled"] = re.compile(config["regex"], re.MULTILINE + re.DOTALL)
|
||||
|
||||
# create quarantine instance
|
||||
quarantine_type = config["quarantine_type"].lower()
|
||||
|
||||
@@ -33,7 +33,7 @@ class BaseNotification(object):
|
||||
self.config = config
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
def notify(self, queueid, quarantine_id, subject, mailfrom, recipients, fp, synchronous=False):
|
||||
def notify(self, queueid, quarantine_id, subject, mailfrom, recipients, fp, subgroups=None, named_subgroups=None, synchronous=False):
|
||||
fp.seek(0)
|
||||
pass
|
||||
|
||||
@@ -224,9 +224,9 @@ class EMailNotification(BaseNotification):
|
||||
|
||||
return soup
|
||||
|
||||
def notify(self, queueid, quarantine_id, subject, mailfrom, recipients, fp, synchronous=False):
|
||||
def notify(self, queueid, quarantine_id, subject, mailfrom, recipients, fp, subgroups=None, named_subgroups=None, synchronous=False):
|
||||
"Notify recipients via email."
|
||||
super(EMailNotification, self).notify(queueid, quarantine_id, subject, mailfrom, recipients, fp, synchronous)
|
||||
super(EMailNotification, self).notify(queueid, quarantine_id, subject, mailfrom, recipients, fp, subgroups, named_subgroups, synchronous)
|
||||
|
||||
# extract html text from email
|
||||
self.logger.debug("{}: extraction email text from original email".format(queueid))
|
||||
@@ -244,21 +244,29 @@ class EMailNotification(BaseNotification):
|
||||
# sanitizing email text of original email
|
||||
sanitized_text = self.sanitize(queueid, soup)
|
||||
|
||||
# escape possible html entities in subject
|
||||
subject = escape(subject)
|
||||
|
||||
# sending email notifications
|
||||
for recipient in recipients:
|
||||
self.logger.debug("{}: generating notification email for '{}'".format(queueid, recipient))
|
||||
self.logger.debug("{}: parsing email template".format(queueid))
|
||||
|
||||
htmltext = self.template.format( \
|
||||
EMAIL_HTML_TEXT=sanitized_text, \
|
||||
EMAIL_FROM=escape(mailfrom), \
|
||||
EMAIL_TO=escape(recipient), \
|
||||
EMAIL_SUBJECT=subject, \
|
||||
EMAIL_QUARANTINE_ID=quarantine_id
|
||||
)
|
||||
# generate dict containing all template variables
|
||||
variables = {
|
||||
"EMAIL_HTML_TEXT": sanitized_text,
|
||||
"EMAIL_FROM": escape(mailfrom),
|
||||
"EMAIL_TO": escape(recipient),
|
||||
"EMAIL_SUBJECT": escape(subject),
|
||||
"EMAIL_QUARANTINE_ID": quarantine_id
|
||||
}
|
||||
if subgroups:
|
||||
number = 0
|
||||
for subgroup in subgroups:
|
||||
variables["SUBGROUP_{}".format(number)] = escape(subgroup)
|
||||
if named_subgroups:
|
||||
for key, value in named_subgroups.items(): named_subgroups[key] = escape(value)
|
||||
variables.update(named_subgroups)
|
||||
|
||||
# parse template
|
||||
htmltext = self.template.format(**variables)
|
||||
|
||||
msg = MIMEMultipart('alternative')
|
||||
msg["Subject"] = self.subject
|
||||
|
||||
@@ -33,7 +33,7 @@ class BaseQuarantine(object):
|
||||
self.config = config
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
def add(self, queueid, mailfrom, recipients, subject, fp):
|
||||
def add(self, queueid, mailfrom, recipients, subject, fp, subgroups=None, named_subgroups=None):
|
||||
"Add email to quarantine."
|
||||
fp.seek(0)
|
||||
return ""
|
||||
@@ -109,9 +109,9 @@ class FileQuarantine(BaseQuarantine):
|
||||
except IOError as e:
|
||||
raise RuntimeError("unable to remove data file: {}".format(e))
|
||||
|
||||
def add(self, queueid, mailfrom, recipients, subject, fp):
|
||||
def add(self, queueid, mailfrom, recipients, subject, fp, subgroups=None, named_subgroups=None):
|
||||
"Add email to file quarantine and return quarantine-id."
|
||||
super(FileQuarantine, self).add(queueid, mailfrom, recipients, subject, fp)
|
||||
super(FileQuarantine, self).add(queueid, mailfrom, recipients, subject, fp, subgroups, named_subgroups)
|
||||
quarantine_id = "{}_{}".format(datetime.now().strftime("%Y%m%d%H%M%S"), queueid)
|
||||
|
||||
# save mail
|
||||
@@ -123,7 +123,9 @@ class FileQuarantine(BaseQuarantine):
|
||||
"recipients": recipients,
|
||||
"subject": subject,
|
||||
"date": timegm(gmtime()),
|
||||
"queue_id": queueid
|
||||
"queue_id": queueid,
|
||||
"subgroups": subgroups,
|
||||
"named_subgroups": named_subgroups
|
||||
}
|
||||
try:
|
||||
self._save_metafile(quarantine_id, metadata)
|
||||
@@ -223,7 +225,8 @@ class FileQuarantine(BaseQuarantine):
|
||||
datafile = os.path.join(self.directory, quarantine_id)
|
||||
try:
|
||||
with open(datafile, "rb") as fp:
|
||||
self.config["notification_obj"].notify(metadata["queue_id"], quarantine_id, metadata["subject"], metadata["mailfrom"], recipients, fp, synchronous=True)
|
||||
self.config["notification_obj"].notify(metadata["queue_id"], quarantine_id, metadata["subject"], metadata["mailfrom"], recipients, fp,
|
||||
metadata["subgroups"], metadata["named_subgroups"], synchronous=True)
|
||||
except IOError as e:
|
||||
raise(RuntimeError("unable to read data file: {}".format(e)))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user