diff options
| author | Aurélien Bompard | 2016-02-09 12:23:38 +0100 |
|---|---|---|
| committer | Barry Warsaw | 2016-03-31 18:29:27 -0400 |
| commit | 71cfeda5fb51c49fd87b6d34e00221a3725b9ec0 (patch) | |
| tree | d571db90e7010643ea7cca81ab91eaee89e0f378 /src | |
| parent | 011d278abcc25d417673f70a4eac0a8a78137d95 (diff) | |
| download | mailman-71cfeda5fb51c49fd87b6d34e00221a3725b9ec0.tar.gz mailman-71cfeda5fb51c49fd87b6d34e00221a3725b9ec0.tar.zst mailman-71cfeda5fb51c49fd87b6d34e00221a3725b9ec0.zip | |
Members and nonmembers moderation action fallback
Members and nonmember's moderation action should be None by default, and
in that case the moderation rule should fallback to the mailing list's
default action.
Fixes: #189
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/chains/docs/moderation.rst | 29 | ||||
| -rw-r--r-- | src/mailman/model/docs/membership.rst | 23 | ||||
| -rw-r--r-- | src/mailman/model/member.py | 10 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_member.py | 21 | ||||
| -rw-r--r-- | src/mailman/rest/docs/addresses.rst | 5 | ||||
| -rw-r--r-- | src/mailman/rest/docs/membership.rst | 50 | ||||
| -rw-r--r-- | src/mailman/rest/members.py | 4 | ||||
| -rw-r--r-- | src/mailman/rules/docs/moderation.rst | 17 | ||||
| -rw-r--r-- | src/mailman/rules/moderation.py | 9 | ||||
| -rw-r--r-- | src/mailman/rules/tests/test_moderation.py | 57 | ||||
| -rw-r--r-- | src/mailman/utilities/importer.py | 2 | ||||
| -rw-r--r-- | src/mailman/utilities/tests/test_import.py | 5 |
12 files changed, 144 insertions, 88 deletions
diff --git a/src/mailman/chains/docs/moderation.rst b/src/mailman/chains/docs/moderation.rst index cd0a8eb26..2415b8f4b 100644 --- a/src/mailman/chains/docs/moderation.rst +++ b/src/mailman/chains/docs/moderation.rst @@ -33,12 +33,7 @@ determined by the mailing list's settings. By default, a mailing list is not set to moderate new member postings. :: - >>> from mailman.testing.helpers import subscribe - >>> member = subscribe(mlist, 'Anne', email='anne@example.com') - >>> member - <Member: Anne Person <anne@example.com> on test@example.com - as MemberRole.member> - >>> print(member.moderation_action) + >>> print(mlist.default_member_action) Action.defer In order to find out whether the message is held or accepted, we can subscribe @@ -58,6 +53,18 @@ to Zope events that are triggered on each case. ... for miss in event.msgdata.get('rule_misses', []): ... print(' ', miss) +The user Anne will be a list member. A list member's default moderation action +is ``None``, meaning that it will use the mailing list's +``default_member_action``. + + >>> from mailman.testing.helpers import subscribe + >>> member = subscribe(mlist, 'Anne', email='anne@example.com') + >>> member + <Member: Anne Person <anne@example.com> on test@example.com + as MemberRole.member> + >>> print(member.moderation_action is None) + True + Anne's post to the mailing list runs through the incoming runner's default built-in chain. No rules hit and so the message is accepted. :: @@ -173,8 +180,8 @@ Nonmembers ========== Registered nonmembers are handled very similarly to members, the main -difference being that they usually have a default moderation action. This is -how the incoming runner adds sender addresses as nonmembers. +difference being that the mailing list's default moderation action is +different. This is how the incoming runner adds sender addresses as nonmembers. >>> from zope.component import getUtility >>> from mailman.interfaces.usermanager import IUserManager @@ -211,5 +218,11 @@ moderator approval. >>> nonmember = mlist.nonmembers.get_member('bart@example.com') >>> nonmember <Member: bart@example.com on test@example.com as MemberRole.nonmember> + +A nonmember's default moderation action is ``None``, meaning that it will use +the mailing list's ``default_nonmember_action``. + >>> print(nonmember.moderation_action) + None + >>> print(mlist.default_nonmember_action) Action.hold diff --git a/src/mailman/model/docs/membership.rst b/src/mailman/model/docs/membership.rst index 0fd748d6a..c8452abf0 100644 --- a/src/mailman/model/docs/membership.rst +++ b/src/mailman/model/docs/membership.rst @@ -273,23 +273,26 @@ automatically accepted for posting to the mailing list. aperson@example.com MemberRole.owner Action.accept bperson@example.com MemberRole.moderator Action.accept -By default, members have a *deferred* action which specifies that the posting -should go through the normal moderation checks. +By default, members and nonmembers have their action set to None, meaning that +the mailing list's ``default_member_action`` or ``default_nonmember_action`` +will be used. >>> for member in sorted(mlist.members.members, ... key=attrgetter('address.email')): ... print(member.address.email, member.role, member.moderation_action) - aperson@example.com MemberRole.member Action.defer - bperson@example.com MemberRole.member Action.defer - cperson@example.com MemberRole.member Action.defer - hperson@example.com MemberRole.member Action.defer - iperson@example.com MemberRole.member Action.defer - -Postings by nonmembers are held for moderator approval by default. + aperson@example.com MemberRole.member None + bperson@example.com MemberRole.member None + cperson@example.com MemberRole.member None + hperson@example.com MemberRole.member None + iperson@example.com MemberRole.member None >>> for member in mlist.nonmembers.members: ... print(member.address.email, member.role, member.moderation_action) - fperson@example.com MemberRole.nonmember Action.hold + fperson@example.com MemberRole.nonmember None + +The mailing list's default action for members is *deferred*, which specifies +that the posting should go through the normal moderation checks. Its default +action for nonmembers is to hold for moderator approval. Changing subscriptions diff --git a/src/mailman/model/member.py b/src/mailman/model/member.py index 99f2de9b8..a6555c0fe 100644 --- a/src/mailman/model/member.py +++ b/src/mailman/model/member.py @@ -76,14 +76,10 @@ class Member(Model): raise ValueError('subscriber must be a user or address') if role in (MemberRole.owner, MemberRole.moderator): self.moderation_action = Action.accept - elif role is MemberRole.member: - self.moderation_action = getUtility(IListManager).get_by_list_id( - list_id).default_member_action else: - assert role is MemberRole.nonmember, ( - 'Invalid MemberRole: {}'.format(role)) - self.moderation_action = getUtility(IListManager).get_by_list_id( - list_id).default_nonmember_action + assert role in (MemberRole.member, MemberRole.nonmember), ( + 'Invalid MemberRole: {0}'.format(role)) + self.moderation_action = None def __repr__(self): return '<Member: {} on {} as {}>'.format( diff --git a/src/mailman/model/tests/test_member.py b/src/mailman/model/tests/test_member.py index 3a24d9680..51402b659 100644 --- a/src/mailman/model/tests/test_member.py +++ b/src/mailman/model/tests/test_member.py @@ -20,6 +20,7 @@ import unittest from mailman.app.lifecycle import create_list +from mailman.interfaces.action import Action from mailman.interfaces.member import MemberRole, MembershipError from mailman.interfaces.user import UnverifiedAddressError from mailman.interfaces.usermanager import IUserManager @@ -100,3 +101,23 @@ class TestMember(unittest.TestCase): member = self._mlist.members.get_member('anne@example.com') member.unsubscribe() self.assertEqual(len(list(self._mlist.members.members)), 0) + + def test_default_moderation_action(self): + # Owners and moderators have their posts accepted, members and + # nonmembers default to the mailing list's action for their type. + anne = self._usermanager.create_user('anne@example.com') + bart = self._usermanager.create_user('bart@example.com') + cris = self._usermanager.create_user('cris@example.com') + dana = self._usermanager.create_user('dana@example.com') + set_preferred(anne) + set_preferred(bart) + set_preferred(cris) + set_preferred(dana) + anne_member = self._mlist.subscribe(anne, MemberRole.owner) + bart_member = self._mlist.subscribe(bart, MemberRole.moderator) + cris_member = self._mlist.subscribe(cris, MemberRole.member) + dana_member = self._mlist.subscribe(dana, MemberRole.nonmember) + self.assertEqual(anne_member.moderation_action, Action.accept) + self.assertEqual(bart_member.moderation_action, Action.accept) + self.assertIsNone(cris_member.moderation_action) + self.assertIsNone(dana_member.moderation_action) diff --git a/src/mailman/rest/docs/addresses.rst b/src/mailman/rest/docs/addresses.rst index c850503c4..e5dff0f7c 100644 --- a/src/mailman/rest/docs/addresses.rst +++ b/src/mailman/rest/docs/addresses.rst @@ -379,7 +379,6 @@ Elle can get her memberships for each of her email addresses. http_etag: "..." list_id: ant.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/4 @@ -390,7 +389,6 @@ Elle can get her memberships for each of her email addresses. http_etag: "..." list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/4 @@ -422,7 +420,6 @@ does not show up in the list of memberships for his other address. http_etag: "..." list_id: ant.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/4 @@ -433,7 +430,6 @@ does not show up in the list of memberships for his other address. http_etag: "..." list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/4 @@ -450,7 +446,6 @@ does not show up in the list of memberships for his other address. http_etag: "..." list_id: bee.example.com member_id: 3 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/4 diff --git a/src/mailman/rest/docs/membership.rst b/src/mailman/rest/docs/membership.rst index 3d2d9a010..ec8765d68 100644 --- a/src/mailman/rest/docs/membership.rst +++ b/src/mailman/rest/docs/membership.rst @@ -50,7 +50,6 @@ the REST interface. http_etag: ... list_id: bee.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -67,7 +66,6 @@ Bart's specific membership can be accessed directly: http_etag: ... list_id: bee.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -88,7 +86,6 @@ the REST interface. http_etag: ... list_id: bee.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -99,7 +96,6 @@ the REST interface. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -123,7 +119,6 @@ subscribes, she is returned first. http_etag: ... list_id: bee.example.com member_id: 3 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -134,7 +129,6 @@ subscribes, she is returned first. http_etag: ... list_id: bee.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -145,7 +139,6 @@ subscribes, she is returned first. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -175,7 +168,6 @@ User ids are different than member ids. http_etag: ... list_id: ant.example.com member_id: 4 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -186,7 +178,6 @@ User ids are different than member ids. http_etag: ... list_id: ant.example.com member_id: 5 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/5 user: http://localhost:9001/3.0/users/2 @@ -197,7 +188,6 @@ User ids are different than member ids. http_etag: ... list_id: bee.example.com member_id: 3 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -208,7 +198,6 @@ User ids are different than member ids. http_etag: ... list_id: bee.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -219,7 +208,6 @@ User ids are different than member ids. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -238,7 +226,6 @@ We can also get just the members of a single mailing list. http_etag: ... list_id: ant.example.com member_id: 4 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -249,7 +236,6 @@ We can also get just the members of a single mailing list. http_etag: ... list_id: ant.example.com member_id: 5 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/5 user: http://localhost:9001/3.0/users/2 @@ -276,7 +262,6 @@ page. http_etag: ... list_id: ant.example.com member_id: 4 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -295,7 +280,6 @@ This works with members of a single list as well as with all members. http_etag: ... list_id: ant.example.com member_id: 4 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -353,7 +337,6 @@ mailing list. http_etag: ... list_id: ant.example.com member_id: 4 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -364,7 +347,6 @@ mailing list. http_etag: ... list_id: ant.example.com member_id: 5 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/5 user: http://localhost:9001/3.0/users/2 @@ -386,7 +368,6 @@ mailing list. http_etag: ... list_id: bee.example.com member_id: 3 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -397,7 +378,6 @@ mailing list. http_etag: ... list_id: bee.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -408,7 +388,6 @@ mailing list. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -467,7 +446,6 @@ example, we can search for all the memberships of a particular address. http_etag: ... list_id: ant.example.com member_id: 4 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -478,7 +456,6 @@ example, we can search for all the memberships of a particular address. http_etag: ... list_id: bee.example.com member_id: 3 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -498,7 +475,6 @@ Or, we can find all the memberships for a particular mailing list. http_etag: ... list_id: bee.example.com member_id: 3 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -509,7 +485,6 @@ Or, we can find all the memberships for a particular mailing list. http_etag: ... list_id: bee.example.com member_id: 1 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -520,7 +495,6 @@ Or, we can find all the memberships for a particular mailing list. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -553,7 +527,6 @@ list. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -585,7 +558,6 @@ Or, we can find all the memberships for an address with a specific role. http_etag: ... list_id: ant.example.com member_id: 5 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/5 user: http://localhost:9001/3.0/users/2 @@ -596,7 +568,6 @@ Or, we can find all the memberships for an address with a specific role. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -618,7 +589,6 @@ Finally, we can search for a specific member given all three criteria. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -640,7 +610,6 @@ Search can also be performed using HTTP GET queries. http_etag: ... list_id: bee.example.com member_id: 2 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -699,7 +668,6 @@ Elly is now a known user, and a member of the mailing list. http_etag: ... list_id: ant.example.com member_id: 8 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/8 user: http://localhost:9001/3.0/users/5 @@ -746,7 +714,6 @@ list with her preferred address. http_etag: "..." list_id: ant.example.com member_id: 9 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/9 user: http://localhost:9001/3.0/users/6 @@ -772,7 +739,6 @@ the new address. http_etag: "..." list_id: ant.example.com member_id: 9 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/9 user: http://localhost:9001/3.0/users/6 @@ -840,7 +806,6 @@ addresses. http_etag: "..." list_id: ant.example.com member_id: 10 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/10 user: http://localhost:9001/3.0/users/7 @@ -852,7 +817,6 @@ addresses. http_etag: "..." list_id: bee.example.com member_id: 11 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/11 user: http://localhost:9001/3.0/users/7 @@ -911,7 +875,6 @@ his membership ids have not changed. http_etag: "..." list_id: ant.example.com member_id: 10 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/10 user: http://localhost:9001/3.0/users/7 @@ -922,7 +885,6 @@ his membership ids have not changed. http_etag: "..." list_id: bee.example.com member_id: 11 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/11 user: http://localhost:9001/3.0/users/7 @@ -952,7 +914,6 @@ mode of delivery. http_etag: "..." list_id: bee.example.com member_id: 11 - moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/11 user: http://localhost:9001/3.0/users/7 @@ -970,9 +931,14 @@ The moderation action for a member can be changed by PATCH'ing the >>> dump_json('http://localhost:9001/3.0/members/10') address: http://localhost:9001/3.0/addresses/hperson@example.com - ... - moderation_action: defer - ... + delivery_mode: regular + email: hperson@example.com + http_etag: "6d544208d60e578189fc023748f1ec467290abb5" + list_id: ant.example.com + member_id: 10 + role: member + self_link: http://localhost:9001/3.0/members/10 + user: http://localhost:9001/3.0/users/7 >>> dump_json('http://localhost:9001/3.0/members/10', { ... 'moderation_action': 'hold', diff --git a/src/mailman/rest/members.py b/src/mailman/rest/members.py index b56fa3c8d..c842ccd7d 100644 --- a/src/mailman/rest/members.py +++ b/src/mailman/rest/members.py @@ -61,10 +61,12 @@ class _MemberBase(CollectionMixin): email=member.address.email, list_id=member.list_id, member_id=member_id, - moderation_action=member.moderation_action, role=role, self_link=self.api.path_to('members/{}'.format(member_id)), ) + # Add the moderation action if there is one. + if member.moderation_action is not None: + response['moderation_action'] = member.moderation_action # Add the user link if there is one. user = member.user if user is not None: diff --git a/src/mailman/rules/docs/moderation.rst b/src/mailman/rules/docs/moderation.rst index f5ceec29a..56602189b 100644 --- a/src/mailman/rules/docs/moderation.rst +++ b/src/mailman/rules/docs/moderation.rst @@ -2,9 +2,10 @@ Moderation ========== -All members and nonmembers have a moderation action. When the action is not -`defer`, the `moderation` rule flags the message as needing moderation. This -might be to automatically accept, discard, reject, or hold the message. +All members and nonmembers have a moderation action, which defaults to the +list's default action. When the action is not `defer`, the `moderation` rule +flags the message as needing moderation. This might be to automatically +accept, discard, reject, or hold the message. Two separate rules check for member and nonmember moderation. Member moderation happens early in the built-in chain, while nonmember moderation @@ -30,7 +31,7 @@ postings are not moderated. as MemberRole.member> >>> member = mlist.members.get_member('aperson@example.com') - >>> print(member.moderation_action) + >>> print(mlist.default_member_action) Action.defer Because Anne is not moderated, the member moderation rule does not match. @@ -44,9 +45,9 @@ Because Anne is not moderated, the member moderation rule does not match. >>> member_rule.check(mlist, member_msg, {}) False -Once the member's moderation action is set to something other than `defer`, -the rule matches. Also, the message metadata has a few extra pieces of -information for the eventual moderation chain. +Once the member's moderation action is set to something other than `defer` or +``None``, the rule matches. Also, the message metadata has a few extra pieces +of information for the eventual moderation chain. >>> from mailman.interfaces.action import Action >>> member.moderation_action = Action.hold @@ -78,7 +79,7 @@ Bart, who is not a member of the mailing list, sends a message to the list. as MemberRole.nonmember> >>> nonmember = mlist.nonmembers.get_member('bperson@example.com') - >>> print(nonmember.moderation_action) + >>> print(mlist.default_nonmember_action) Action.hold When Bart is registered as a nonmember of the list, his moderation action is diff --git a/src/mailman/rules/moderation.py b/src/mailman/rules/moderation.py index fdecd1d5f..9c89cf0b2 100644 --- a/src/mailman/rules/moderation.py +++ b/src/mailman/rules/moderation.py @@ -42,8 +42,10 @@ class MemberModeration: """See `IRule`.""" for sender in msg.senders: member = mlist.members.get_member(sender) - action = (None if member is None - else member.moderation_action) + if member is None: + return False + action = (member.moderation_action + or mlist.default_member_action) if action is Action.defer: # The regular moderation rules apply. return False @@ -112,7 +114,8 @@ class NonmemberModeration: _record_action(msgdata, action, sender, reason.format(action)) return True - action = nonmember.moderation_action + action = (nonmember.moderation_action + or mlist.default_nonmember_action) if action is Action.defer: # The regular moderation rules apply. return False diff --git a/src/mailman/rules/tests/test_moderation.py b/src/mailman/rules/tests/test_moderation.py index df1658792..3e80aeeb5 100644 --- a/src/mailman/rules/tests/test_moderation.py +++ b/src/mailman/rules/tests/test_moderation.py @@ -144,3 +144,60 @@ A message body. self.assertEqual( msgdata['moderation_action'], action_name, 'Wrong action for {}: {}'.format(address, action_name)) + + def test_nonmember_fallback_to_list_defaults(self): + # https://gitlab.com/mailman/mailman/issues/189 + self._mlist.default_nonmember_action = Action.hold + user_manager = getUtility(IUserManager) + user_manager.create_address('anne@example.com') + rule = moderation.NonmemberModeration() + msg = mfs("""\ +From: anne@example.com +To: test@example.com +Subject: A test message +Message-ID: <ant> +MIME-Version: 1.0 + +A message body. +""") + # First, the message should get held + msgdata = {} + result = rule.check(self._mlist, msg, msgdata) + self.assertTrue(result) + self.assertEqual(msgdata.get('moderation_action'), 'hold') + # Then the list's default nonmember action is changed + self._mlist.default_nonmember_action = Action.discard + msg.replace_header('Message-ID', '<ant2>') + # This time, the message should be discarded + result = rule.check(self._mlist, msg, msgdata) + self.assertTrue(result) + self.assertEqual(msgdata.get('moderation_action'), 'discard') + + def test_member_fallback_to_list_defaults(self): + # https://gitlab.com/mailman/mailman/issues/189 + self._mlist.default_member_action = Action.accept + user_manager = getUtility(IUserManager) + anne = user_manager.create_address('anne@example.com') + self._mlist.subscribe(anne, MemberRole.member) + rule = moderation.MemberModeration() + msg = mfs("""\ +From: anne@example.com +To: test@example.com +Subject: A test message +Message-ID: <ant> +MIME-Version: 1.0 + +A message body. +""") + # First, the message should get held + msgdata = {} + result = rule.check(self._mlist, msg, msgdata) + self.assertTrue(result) + self.assertEqual(msgdata.get('moderation_action'), 'accept') + # Then the list's default nonmember action is changed + self._mlist.default_member_action = Action.hold + msg.replace_header('Message-ID', '<ant2>') + # This time, the message should be discarded + result = rule.check(self._mlist, msg, msgdata) + self.assertTrue(result) + self.assertEqual(msgdata.get('moderation_action'), 'hold') diff --git a/src/mailman/utilities/importer.py b/src/mailman/utilities/importer.py index 9a5684d9c..da19613d8 100644 --- a/src/mailman/utilities/importer.py +++ b/src/mailman/utilities/importer.py @@ -576,8 +576,6 @@ def import_roster(mlist, config_dict, members, role, action=None): # option to know which action should be taken. action = member_moderation_action_mapping( config_dict.get("member_moderation_action")) - else: - action = Action.accept if action is not None: # Either this was set right above or in the function's arguments # for nonmembers. diff --git a/src/mailman/utilities/tests/test_import.py b/src/mailman/utilities/tests/test_import.py index 637f78585..83161bf1f 100644 --- a/src/mailman/utilities/tests/test_import.py +++ b/src/mailman/utilities/tests/test_import.py @@ -1112,9 +1112,10 @@ class TestPreferencesImport(unittest.TestCase): self._do_test(128, dict(moderation_action=Action.discard)) def test_no_moderate(self): - # If option flag Moderate is not set, action is accept + # If option flag Moderate is not set, action is None (fallback to the + # mailing list's action). self._pckdict['member_moderation_action'] = 1 # reject - self._do_test(0, dict(moderation_action=Action.accept)) + self._do_test(0, dict(moderation_action=None)) def test_multiple_options(self): # DontReceiveDuplicates & DisableMime & SuppressPasswordReminder |
