Mark Sapiro pushed to branch master at GNU Mailman / Mailman Core


Commits:
5ca0e415 by Mark Sapiro at 2019-05-15T23:47:39Z
Catch various exceptions in email join command.

- - - - -
3c4e6ad9 by Mark Sapiro at 2019-05-15T23:47:39Z
Merge branch 'eml_err' into 'master'

Catch various exceptions in email join command.

Closes #583 and #577

See merge request mailman/mailman!516
- - - - -


3 changed files:

- src/mailman/commands/eml_membership.py
- src/mailman/commands/tests/test_eml_membership.py
- src/mailman/docs/NEWS.rst


Changes:

=====================================
src/mailman/commands/eml_membership.py
=====================================
@@ -20,9 +20,10 @@
 from email.utils import formataddr, parseaddr
 from mailman.core.i18n import _
 from mailman.interfaces.command import ContinueProcessing, IEmailCommand
-from mailman.interfaces.member import DeliveryMode, MemberRole
+from mailman.interfaces.member import (
+    AlreadySubscribedError, DeliveryMode, MembershipIsBannedError)
 from mailman.interfaces.subscriptions import (
-    ISubscriptionManager, ISubscriptionService)
+    ISubscriptionManager, SubscriptionPendingError)
 from mailman.interfaces.usermanager import IUserManager
 from public import public
 from zope.component import getUtility
@@ -93,16 +94,18 @@ used.
         joins.add(email)
         results.joins = joins
         person = formataddr((display_name, email))                # noqa: F841
-        # Is this person already a member of the list?  Search for all
-        # matching memberships.
-        members = getUtility(ISubscriptionService).find_members(
-            email, mlist.list_id, MemberRole.member)
-        if len(members) > 0:
-            print(_('$person is already a member'), file=results)
-            return ContinueProcessing.yes
         subscriber = match_subscriber(email, display_name)
-        ISubscriptionManager(mlist).register(subscriber)
-        print(_('Confirmation email sent to $person'), file=results)
+        try:
+            ISubscriptionManager(mlist).register(subscriber)
+        except (AlreadySubscribedError, MembershipIsBannedError) as e:
+            print(str(e), file=results)
+        except SubscriptionPendingError:
+            # SubscriptionPendingError doesn't return an error message.
+            listname = mlist.fqdn_listname                        # noqa: F841
+            print(_('$person has a pending subscription for $listname'),
+                  file=results)
+        else:
+            print(_('Confirmation email sent to $person'), file=results)
         return ContinueProcessing.yes
 
     def _parse_arguments(self, arguments, results):


=====================================
src/mailman/commands/tests/test_eml_membership.py
=====================================
@@ -15,14 +15,16 @@
 # You should have received a copy of the GNU General Public License along with
 # GNU Mailman.  If not, see <https://www.gnu.org/licenses/>.
 
-"""Test the Leave command."""
+"""Test the Join and Leave commands."""
 
 import unittest
 
 from mailman.app.lifecycle import create_list
-from mailman.commands.eml_membership import Leave
+from mailman.commands.eml_membership import Join, Leave
 from mailman.email.message import Message
+from mailman.interfaces.bans import IBanManager
 from mailman.interfaces.mailinglist import SubscriptionPolicy
+from mailman.interfaces.subscriptions import ISubscriptionManager
 from mailman.interfaces.usermanager import IUserManager
 from mailman.runners.command import Results
 from mailman.testing.helpers import set_preferred
@@ -52,3 +54,64 @@ class TestLeave(unittest.TestCase):
         self.assertEqual(
             str(results).splitlines()[-1],
             'leave: a...@example.com is not a member of a...@example.com')
+
+
+class TestJoin(unittest.TestCase):
+    layer = ConfigLayer
+
+    def setUp(self):
+        self._mlist = create_list('a...@example.com')
+        self._command = Join()
+
+    def test_join_already_a_member(self):
+        # Try to subscribe someone who is already a member.  Anne is a real
+        # user, with a validated address, but she is not a member of the
+        # mailing list yet.
+        anne = getUtility(IUserManager).create_user('a...@example.com')
+        set_preferred(anne)
+        # First subscribe anne.
+        ISubscriptionManager(self._mlist).register(anne, pre_verified=True,
+                                                   pre_confirmed=True,
+                                                   pre_approved=True)
+        # Then initiate a subscription.
+        msg = Message()
+        msg['From'] = 'a...@example.com'
+        results = Results()
+        self._command.process(self._mlist, msg, {}, (), results)
+        self.assertEqual(
+            str(results).splitlines()[-1],
+            'a...@example.com is already a MemberRole.member of '
+            'mailing list a...@example.com')
+
+    def test_join_banned(self):
+        # Try to subscribe someone who is banned.  Anne is a real
+        # user, with a validated address, but she is not a member of the
+        # mailing list and is banned from joining.
+        # Add anne to the ban list.
+        IBanManager(self._mlist).ban('a...@example.com')
+        # Then initiate a subscription.
+        msg = Message()
+        msg['From'] = 'a...@example.com'
+        results = Results()
+        self._command.process(self._mlist, msg, {}, (), results)
+        self.assertEqual(
+            str(results).splitlines()[-1],
+            'a...@example.com is not allowed to subscribe to a...@example.com')
+
+    def test_join_pending(self):
+        self._mlist.subscription_policy = SubscriptionPolicy.confirm
+        # Try to subscribe someone who already has a subscription pending.
+        # Anne is a real user, with a validated address, who already has a
+        # pending subscription for this mailing list.
+        anne = getUtility(IUserManager).create_user('a...@example.com')
+        set_preferred(anne)
+        # Initiate a subscription.
+        ISubscriptionManager(self._mlist).register(anne)
+        # And try to subscribe.
+        msg = Message()
+        msg['From'] = 'a...@example.com'
+        results = Results()
+        self._command.process(self._mlist, msg, {}, (), results)
+        self.assertEqual(
+            str(results).splitlines()[-1],
+            'a...@example.com has a pending subscription for a...@example.com')


=====================================
src/mailman/docs/NEWS.rst
=====================================
@@ -27,6 +27,8 @@ Bugs
 * A post from a nonmember matching the legacy ``accept_these_nonmembers`` is
   now subject to subsequent rules rather than accepted immediately.
   (Closes #587)
+* Email attempts to subscribe a user who is banned or has a subscription
+  already pending are now handled properly.  (Closes #577 and #583)
 
 Command line
 ------------



View it on GitLab: 
https://gitlab.com/mailman/mailman/compare/78ef269ef419e3607593ea249831ce554b7e749c...3c4e6ad9a7b8cec0633de87e01a496b8ebb53f7d

-- 
View it on GitLab: 
https://gitlab.com/mailman/mailman/compare/78ef269ef419e3607593ea249831ce554b7e749c...3c4e6ad9a7b8cec0633de87e01a496b8ebb53f7d
You're receiving this email because of your account on gitlab.com.


_______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: 
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to