aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Sapiro <mark@msapiro.net>2015-01-23 15:50:47 -0800
committerMark Sapiro <mark@msapiro.net>2015-01-23 15:50:47 -0800
commit792407be592b8e7d523cb134a01b09101cbc2cad (patch)
treef66aaacb3c7781e490ea9c365510c75e46818f81
parent0e3c1fbaf0c80ed865945a14e604954daaf80a6a (diff)
downloadmailman2-792407be592b8e7d523cb134a01b09101cbc2cad.tar.gz
mailman2-792407be592b8e7d523cb134a01b09101cbc2cad.tar.xz
mailman2-792407be592b8e7d523cb134a01b09101cbc2cad.zip
Implemented the equivalent domains feature for list posting/moderation.
-rwxr-xr-xMailman/Defaults.py.in22
-rw-r--r--Mailman/Gui/Privacy.py27
-rw-r--r--Mailman/Handlers/Moderate.py6
-rwxr-xr-xMailman/MailList.py2
-rw-r--r--Mailman/Utils.py34
-rwxr-xr-xMailman/versions.py2
-rwxr-xr-xNEWS7
7 files changed, 99 insertions, 1 deletions
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index 8a5e6b0e..8049c36c 100755
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -1101,7 +1101,27 @@ DMARC_RESOLVER_TIMEOUT = seconds(3)
# The total time to spend trying to get an answer to the question.
DMARC_RESOLVER_LIFETIME = seconds(5)
-# What shold happen to non-member posts which are do not match explicit
+# What domains should be considered equivalent when testing list membership
+# 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,
+# the domains are separated by commas and multiple groups are
+# separated by semicolons. White space is ignored.
+# For example:
+#
+# 'example.com,mail.example.com;mac.com,me.com,icloud.com'
+#
+# In this example, if user@example.com is a list member,
+# a post from user@mail.example.com will be treated as if it is
+# from user@example.com for list membership/moderation purposes,
+# and likewise, if user@me.com is a list member, posts from
+# user@mac.com or user@icloud.com will be treated as if from
+# user@me.com.
+DEFAULT_EQUIVALENT_DOMAINS = ''
+
+# What should happen to non-member posts which are do not match explicit
# non-member actions?
# 0 = Accept
# 1 = Hold
diff --git a/Mailman/Gui/Privacy.py b/Mailman/Gui/Privacy.py
index 3c32bf50..905532ae 100644
--- a/Mailman/Gui/Privacy.py
+++ b/Mailman/Gui/Privacy.py
@@ -302,6 +302,33 @@ class Privacy(GUIBase):
be sent to anyone who posts to this list from a domain
with a DMARC Reject%(quarantine)s Policy.""")),
+ ('equivalent_domains', mm_cfg.Text, (10, WIDTH), 1,
+ _("""A 'two dimensional' list of email address domains which are
+ considered equivalent when checking if a post is from a list
+ member."""),
+
+ _("""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,
+ the domains are separated by commas and multiple groups are
+ separated by semicolons. White space is ignored.
+ <p>For example:<pre>
+ example.com,mail.example.com;mac.com,me.com,icloud.com
+ </pre>
+ <p>In this example, if user@example.com is a list member,
+ a post from user@mail.example.com will be treated as if it is
+ from user@example.com for list membership/moderation purposes,
+ and likewise, if user@me.com is a list member, posts from
+ user@mac.com or user@icloud.com will be treated as if from
+ user@me.com.
+ <p>Note that the poster's address is first tested for list
+ membership, and the equivalent domain addresses are only tested
+ if the poster's address is not that of a member.
+ <p>Also note that moderation of the equivalent domain address
+ will apply to the post, but other options such as 'ack' or
+ 'not&nbsp;metoo' will not.""")),
+
_('Non-member filters'),
('accept_these_nonmembers', mm_cfg.EmailListEx, (10, WIDTH), 1,
diff --git a/Mailman/Handlers/Moderate.py b/Mailman/Handlers/Moderate.py
index 225ee37f..dfc2c567 100644
--- a/Mailman/Handlers/Moderate.py
+++ b/Mailman/Handlers/Moderate.py
@@ -54,6 +54,12 @@ def process(mlist, msg, msgdata):
for sender in msg.get_senders():
if mlist.isMember(sender):
break
+ for sender in Utils.check_eq_domains(sender,
+ mlist.equivalent_domains):
+ if mlist.isMember(sender):
+ break
+ if mlist.isMember(sender):
+ break
else:
sender = None
if sender:
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index dca8c8f5..88bd320b 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.equivalent_domains = (
+ mm_cfg.DEFAULT_EQUIVALENT_DOMAINS)
self.accept_these_nonmembers = []
self.hold_these_nonmembers = []
self.reject_these_nonmembers = []
diff --git a/Mailman/Utils.py b/Mailman/Utils.py
index 0cb9f122..13c4ed8b 100644
--- a/Mailman/Utils.py
+++ b/Mailman/Utils.py
@@ -1216,3 +1216,37 @@ def IsDMARCProhibited(mlist, email):
return False
+
+def check_eq_domains(email, domains_list):
+ """The arguments are an email address and a string representing a
+ list of lists in a form like 'a,b,c;1,2' representing [['a', 'b',
+ 'c'],['1', '2']]. The inner lists are domains which are
+ equivalent in some sense. The return is an empty list or a list
+ of email addresses equivalent to the first argument.
+ For example, given
+
+ email = 'user@me.com'
+ domains_list = '''domain1, domain2; mac.com, me.com, icloud.com;
+ domaina, domainb
+ '''
+
+ check_eq_domains(email, domains_list) will return
+ ['user@mac.com', 'user@icloud.com']
+ """
+ if not domains_list:
+ return []
+ try:
+ local, domain = email.rsplit('@', 1)
+ except ValueError:
+ return []
+ domain = domain.lower()
+ domains_list = re.sub('\s', '', domains_list).lower()
+ domains = domains_list.split(';')
+ domains_list = []
+ for d in domains:
+ domains_list.append(d.split(','))
+ for domains in domains_list:
+ if domain in domains:
+ return [local + '@' + x for x in domains if x != domain]
+ return []
+
diff --git a/Mailman/versions.py b/Mailman/versions.py
index d0960e0d..ffcd49e5 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('equivalent_domains',
+ mm_cfg.DEFAULT_EQUIVALENT_DOMAINS)
add_only_if_missing('new_member_options',
mm_cfg.DEFAULT_NEW_MEMBER_OPTIONS)
# Emergency moderation flag
diff --git a/NEWS b/NEWS
index 2b736f0f..4dad342c 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 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
+ or more groups of domains, e.g., mac.com, me.com, icloud.com, which are
+ considered equivalent for validating list membership for posting and
+ moderation purposes.
+
- There is a new WEB_HEAD_ADD setting to specify text to be added to the
<HEAD> section of Mailman's internally generated web pages. This doesn't
apply to pages built from templates, but in those cases, custom templates