diff options
-rwxr-xr-x | Mailman/Defaults.py.in | 22 | ||||
-rw-r--r-- | Mailman/Gui/Privacy.py | 27 | ||||
-rw-r--r-- | Mailman/Handlers/Moderate.py | 6 | ||||
-rwxr-xr-x | Mailman/MailList.py | 2 | ||||
-rw-r--r-- | Mailman/Utils.py | 34 | ||||
-rwxr-xr-x | Mailman/versions.py | 2 | ||||
-rwxr-xr-x | NEWS | 7 |
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 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 @@ -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 |