summaryrefslogtreecommitdiff
path: root/src/mailman/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/commands')
-rw-r--r--src/mailman/commands/docs/membership.rst50
-rw-r--r--src/mailman/commands/eml_confirm.py7
-rw-r--r--src/mailman/commands/eml_membership.py50
-rw-r--r--src/mailman/commands/tests/test_confirm.py11
4 files changed, 58 insertions, 60 deletions
diff --git a/src/mailman/commands/docs/membership.rst b/src/mailman/commands/docs/membership.rst
index bdebba8f7..49e80511d 100644
--- a/src/mailman/commands/docs/membership.rst
+++ b/src/mailman/commands/docs/membership.rst
@@ -70,7 +70,7 @@ The ``subscribe`` command is an alias.
Joining the sender
------------------
-When the message has a From field, that address will be subscribed.
+When the message has a ``From`` field, that address will be subscribed.
>>> msg = message_from_string("""\
... From: Anne Person <anne@example.com>
@@ -85,13 +85,10 @@ When the message has a From field, that address will be subscribed.
Confirmation email sent to Anne Person <anne@example.com>
<BLANKLINE>
-Anne is not yet a member because she must confirm her subscription request
-first.
+Anne is not yet a member of the mailing list because she must confirm her
+subscription request first.
- >>> from mailman.interfaces.usermanager import IUserManager
- >>> from zope.component import getUtility
- >>> user_manager = getUtility(IUserManager)
- >>> print(user_manager.get_user('anne@example.com'))
+ >>> print(mlist.members.get_member('anne@example.com'))
None
Mailman has sent her the confirmation message.
@@ -118,10 +115,7 @@ Mailman has sent her the confirmation message.
<BLANKLINE>
Before you can start using GNU Mailman at this site, you must first
confirm that this is your email address. You can do this by replying to
- this message, keeping the Subject header intact. Or you can visit this
- web page
- <BLANKLINE>
- http://lists.example.com/confirm/...
+ this message, keeping the Subject header intact.
<BLANKLINE>
If you do not wish to register this email address simply disregard this
message. If you think you are being maliciously subscribed to the list, or
@@ -130,8 +124,7 @@ Mailman has sent her the confirmation message.
alpha-owner@example.com
<BLANKLINE>
-Once Anne confirms her registration, she will be made a member of the mailing
-list.
+Anne confirms her registration.
::
>>> def extract_token(message):
@@ -156,13 +149,7 @@ list.
Confirmed
<BLANKLINE>
- >>> user = user_manager.get_user('anne@example.com')
- >>> print(user.display_name)
- Anne Person
- >>> list(user.addresses)
- [<Address: Anne Person <anne@example.com> [verified] at ...>]
-
-Anne is also now a member of the mailing list.
+Anne is now a member of the mailing list.
>>> mlist.members.get_member('anne@example.com')
<Member: Anne Person <anne@example.com>
@@ -180,12 +167,7 @@ Joining a second list
>>> print(join.process(mlist_2, msg, {}, (), Results()))
ContinueProcessing.yes
-Anne of course, is still registered.
-
- >>> print(user_manager.get_user('anne@example.com'))
- <User "Anne Person" (...) at ...>
-
-But she is not a member of the mailing list.
+Anne is not a member of the mailing list.
>>> print(mlist_2.members.get_member('anne@example.com'))
None
@@ -257,7 +239,9 @@ subscribe with. Any of her registered, linked, and validated email addresses
will do.
::
- >>> anne = user_manager.get_user('anne@example.com')
+ >>> from mailman.interfaces.usermanager import IUserManager
+ >>> from zope.component import getUtility
+ >>> anne = getUtility(IUserManager).get_user('anne@example.com')
>>> address = anne.register('anne.person@example.org')
>>> results = Results()
@@ -333,11 +317,6 @@ message.
... raise AssertionError('No confirmation message')
>>> token = extract_token(item.msg)
-Bart is still not a user.
-
- >>> print(user_manager.get_user('bart@example.com'))
- None
-
Bart replies to the original message, specifically keeping the Subject header
intact except for any prefix. Mailman matches the token and confirms Bart as
a user of the system.
@@ -360,12 +339,7 @@ a user of the system.
Confirmed
<BLANKLINE>
-Now Bart is a user...
-
- >>> print(user_manager.get_user('bart@example.com'))
- <User "Bart Person" (...) at ...>
-
-...and a member of the mailing list.
+Now Bart is now a member of the mailing list.
>>> print(mlist.members.get_member('bart@example.com'))
<Member: Bart Person <bart@example.com>
diff --git a/src/mailman/commands/eml_confirm.py b/src/mailman/commands/eml_confirm.py
index a28a3f728..077fab9a6 100644
--- a/src/mailman/commands/eml_confirm.py
+++ b/src/mailman/commands/eml_confirm.py
@@ -25,7 +25,6 @@ __all__ = [
from mailman.core.i18n import _
from mailman.interfaces.command import ContinueProcessing, IEmailCommand
from mailman.interfaces.registrar import IRegistrar
-from zope.component import getUtility
from zope.interface import implementer
@@ -53,7 +52,11 @@ class Confirm:
return ContinueProcessing.yes
tokens.add(token)
results.confirms = tokens
- succeeded = getUtility(IRegistrar).confirm(token)
+ try:
+ succeeded = (IRegistrar(mlist).confirm(token) is None)
+ except LookupError:
+ # The token must not exist in the database.
+ succeeded = False
if succeeded:
print(_('Confirmed'), file=results)
return ContinueProcessing.yes
diff --git a/src/mailman/commands/eml_membership.py b/src/mailman/commands/eml_membership.py
index 059b9b634..970fd4429 100644
--- a/src/mailman/commands/eml_membership.py
+++ b/src/mailman/commands/eml_membership.py
@@ -37,6 +37,28 @@ from zope.interface import implementer
+def match_subscriber(email, display_name):
+ # Return something matching the email which should be used as the
+ # subscriber by the IRegistrar interface.
+ manager = getUtility(IUserManager)
+ # Is there a user with a preferred address matching the email?
+ user = manager.get_user(email)
+ if user is not None:
+ preferred = user.preferred_address
+ if preferred is not None and preferred.email == email.lower():
+ return user
+ # Is there an address matching the email?
+ address = manager.get_address(email)
+ if address is not None:
+ return address
+ # Make a new user and subscribe their first (and only) address. We can't
+ # make the first address their preferred address because it hasn't been
+ # verified yet.
+ user = manager.make_user(email, display_name)
+ return list(user.addresses)[0]
+
+
+
@implementer(IEmailCommand)
class Join:
"""The email 'join' command."""
@@ -60,35 +82,35 @@ used.
delivery_mode = self._parse_arguments(arguments, results)
if delivery_mode is ContinueProcessing.no:
return ContinueProcessing.no
- display_name, address = parseaddr(msg['from'])
+ display_name, email = parseaddr(msg['from'])
# Address could be None or the empty string.
- if not address:
- address = msg.sender
- if not address:
+ if not email:
+ email = msg.sender
+ if not email:
print(_('$self.name: No valid address found to subscribe'),
file=results)
return ContinueProcessing.no
- if isinstance(address, bytes):
- address = address.decode('ascii')
+ if isinstance(email, bytes):
+ email = email.decode('ascii')
# Have we already seen one join request from this user during the
# processing of this email?
joins = getattr(results, 'joins', set())
- if address in joins:
+ if email in joins:
# Do not register this join.
return ContinueProcessing.yes
- joins.add(address)
+ joins.add(email)
results.joins = joins
- person = formataddr((display_name, address))
+ person = formataddr((display_name, email))
# Is this person already a member of the list? Search for all
# matching memberships.
members = getUtility(ISubscriptionService).find_members(
- address, mlist.list_id, MemberRole.member)
+ email, mlist.list_id, MemberRole.member)
if len(members) > 0:
print(_('$person is already a member'), file=results)
- else:
- getUtility(IRegistrar).register(mlist, address,
- display_name, delivery_mode)
- print(_('Confirmation email sent to $person'), file=results)
+ return ContinueProcessing.yes
+ subscriber = match_subscriber(email, display_name)
+ IRegistrar(mlist).register(subscriber)
+ print(_('Confirmation email sent to $person'), file=results)
return ContinueProcessing.yes
def _parse_arguments(self, arguments, results):
diff --git a/src/mailman/commands/tests/test_confirm.py b/src/mailman/commands/tests/test_confirm.py
index dd168454f..98a26bf7d 100644
--- a/src/mailman/commands/tests/test_confirm.py
+++ b/src/mailman/commands/tests/test_confirm.py
@@ -29,8 +29,9 @@ from mailman.commands.eml_confirm import Confirm
from mailman.email.message import Message
from mailman.interfaces.command import ContinueProcessing
from mailman.interfaces.registrar import IRegistrar
+from mailman.interfaces.usermanager import IUserManager
from mailman.runners.command import Results
-from mailman.testing.helpers import get_queue_messages, reset_the_world
+from mailman.testing.helpers import get_queue_messages
from mailman.testing.layers import ConfigLayer
from zope.component import getUtility
@@ -43,15 +44,13 @@ class TestConfirm(unittest.TestCase):
def setUp(self):
self._mlist = create_list('test@example.com')
- self._token = getUtility(IRegistrar).register(
- self._mlist, 'anne@example.com', 'Anne Person')
+ anne = getUtility(IUserManager).create_address(
+ 'anne@example.com', 'Anne Person')
+ self._token = IRegistrar(self._mlist).register(anne)
self._command = Confirm()
# Clear the virgin queue.
get_queue_messages('virgin')
- def tearDown(self):
- reset_the_world()
-
def test_welcome_message(self):
# A confirmation causes a welcome message to be sent to the member, if
# enabled by the mailing list.