aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xMailman/Defaults.py.in10
-rw-r--r--Mailman/Gui/Privacy.py14
-rw-r--r--Mailman/Handlers/WrapMessage.py22
-rwxr-xr-xMailman/MailList.py2
-rw-r--r--Mailman/Version.py2
-rwxr-xr-xMailman/versions.py2
-rwxr-xr-xNEWS7
7 files changed, 52 insertions, 7 deletions
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index 8049c36c..1ea39ebe 100755
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -1093,6 +1093,11 @@ DEFAULT_DMARC_QUARANTINE_MODERATION_ACTION = Yes
# 4 = Discard
DEFAULT_DMARC_MODERATION_ACTION = 0
+# Default for text to be added to a separate text/plain part preceding the
+# message/rfc822 part containing the original message when
+# dmarc_moderation_action is Wrap Message.
+DEFAULT_DMARC_WRAPPED_MESSAGE_TEXT = ''
+
# Parameters for DMARC DNS lookups. If you are seeing 'DNSException:
# Unable to query DMARC policy ...' entries in your error log, you may need
# to adjust these.
@@ -1105,8 +1110,9 @@ DMARC_RESOLVER_LIFETIME = seconds(5)
# for posting/moderation.
# If two poster addresses with the same local part but
# different domains are to be considered equivalents for list
-# membership tests, the domains are put here. The format is
-# one or more groups of equivalent domains. Within a group,
+# membership tests, the domains are put in the list's equivalent_domains.
+# This provides a default value for new lists.
+# The format is one or more groups of equivalent domains. Within a group,
# the domains are separated by commas and multiple groups are
# separated by semicolons. White space is ignored.
# For example:
diff --git a/Mailman/Gui/Privacy.py b/Mailman/Gui/Privacy.py
index 905532ae..e6a2fd82 100644
--- a/Mailman/Gui/Privacy.py
+++ b/Mailman/Gui/Privacy.py
@@ -301,6 +301,20 @@ class Privacy(GUIBase):
>rejection notice</a> to
be sent to anyone who posts to this list from a domain
with a DMARC Reject%(quarantine)s Policy.""")),
+
+ ('dmarc_wrapped_message_text', mm_cfg.Text, (10, WIDTH), 1,
+ _("""If dmarc_moderation_action applies and is Wrap Message,
+ and this text is provided, the text will be placed in a
+ separate text/plain MIME part preceding the original message
+ part in the wrapped message."""),
+
+ _("""A wrapped message will either be a multipart/mixed message
+ with up to four sub-parts; a text/plain part containing
+ msg_header, a text/plain part containing
+ dmarc_wrapped_message_text, a message/rfc822 part containing the
+ original message and a text/plain part containing msg_footer, or
+ a message/rfc822 message containing only the original message if
+ none of the other parts are applicable.""")),
('equivalent_domains', mm_cfg.Text, (10, WIDTH), 1,
_("""A 'two dimensional' list of email address domains which are
diff --git a/Mailman/Handlers/WrapMessage.py b/Mailman/Handlers/WrapMessage.py
index 0e47e1e4..83f521fb 100644
--- a/Mailman/Handlers/WrapMessage.py
+++ b/Mailman/Handlers/WrapMessage.py
@@ -24,6 +24,9 @@ original message.
import copy
+from email.MIMEMessage import MIMEMessage
+from email.MIMEText import MIMEText
+
from Mailman import Utils
# Headers from the original that we want to keep in the wrapper.
@@ -63,12 +66,23 @@ def process(mlist, msg, msgdata):
if key.lower() not in KEEPERS:
del msg[key]
msg['MIME-Version'] = '1.0'
- msg['Content-Type'] = 'message/rfc822'
- msg['Content-Disposition'] = 'inline'
msg['Message-ID'] = Utils.unique_message_id(mlist)
# Add the headers from CookHeaders.
for k, v in msgdata['add_header'].items():
msg[k] = v
- # And set the payload the way email parses it.
- msg.set_payload([omsg])
+ # Are we including dmarc_wrapped_message_text? I.e., do we have text and
+ # are we wrapping because of dmarc_moderation_action?
+ if mlist.dmarc_wrapped_message_text and msgdata.get('from_is_list') == 2:
+ part1 = MIMEText(Utils.wrap(mlist.dmarc_wrapped_message_text),
+ 'plain',
+ Utils.GetCharSet(mlist.preferred_language))
+ part1['Content-Disposition'] = 'inline'
+ part2 = MIMEMessage(omsg)
+ part2['Content-Disposition'] = 'inline'
+ msg['Content-Type'] = 'multipart/mixed'
+ msg.set_payload([part1, part2])
+ else:
+ msg['Content-Type'] = 'message/rfc822'
+ msg['Content-Disposition'] = 'inline'
+ msg.set_payload([omsg])
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index 88bd320b..c317c32e 100755
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -395,6 +395,8 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin,
self.dmarc_quarantine_moderation_action = (
mm_cfg.DEFAULT_DMARC_QUARANTINE_MODERATION_ACTION)
self.dmarc_moderation_notice = ''
+ self.dmarc_wrapped_message_text = (
+ mm_cfg.DEFAULT_DMARC_WRAPPED_MESSAGE_TEXT)
self.equivalent_domains = (
mm_cfg.DEFAULT_EQUIVALENT_DOMAINS)
self.accept_these_nonmembers = []
diff --git a/Mailman/Version.py b/Mailman/Version.py
index 93616e5f..9d127bdf 100644
--- a/Mailman/Version.py
+++ b/Mailman/Version.py
@@ -37,7 +37,7 @@ HEX_VERSION = ((MAJOR_REV << 24) | (MINOR_REV << 16) | (MICRO_REV << 8) |
(REL_LEVEL << 4) | (REL_SERIAL << 0))
# config.pck schema version number
-DATA_FILE_VERSION = 106
+DATA_FILE_VERSION = 107
# qfile/*.db schema version number
QFILE_SCHEMA_VERSION = 3
diff --git a/Mailman/versions.py b/Mailman/versions.py
index ffcd49e5..873edad1 100755
--- a/Mailman/versions.py
+++ b/Mailman/versions.py
@@ -407,6 +407,8 @@ def NewVars(l):
add_only_if_missing('dmarc_quarantine_moderation_action',
mm_cfg.DEFAULT_DMARC_QUARANTINE_MODERATION_ACTION)
add_only_if_missing('dmarc_moderation_notice', '')
+ add_only_if_missing('dmarc_wrapped_message_text',
+ mm_cfg.DEFAULT_DMARC_WRAPPED_MESSAGE_TEXT)
add_only_if_missing('equivalent_domains',
mm_cfg.DEFAULT_EQUIVALENT_DOMAINS)
add_only_if_missing('new_member_options',
diff --git a/NEWS b/NEWS
index 4dad342c..b14f50c6 100755
--- a/NEWS
+++ b/NEWS
@@ -64,6 +64,13 @@ Here is a history of user visible changes to Mailman.
New Features
+ - There is a new list attribute dmarc_wrapped_message_text and a
+ DEFAULT_DMARC_WRAPPED_MESSAGE_TEXT setting to set the default for new
+ lists. This text is added to a message which is wrapped because of
+ dmarc_moderation_action in a separate text/plain part that precedes the
+ message/rfc822 part containing the original message. It can be used to
+ provide an explanation of why the message was wrapped or similar info.
+
- There is a new list attribute equivalent_domains and a
DEFAULT_EQUIVALENT_DOMAINS setting to set the default for new lists which
in turn defaults to the empty string. This provides a way to specify one