summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBarry Warsaw2016-09-11 07:15:12 +1200
committerBarry Warsaw2016-09-11 07:15:12 +1200
commit1db20c856fa192664d09f93caa1045036b4336dd (patch)
treed826d304ff5e10de8a5c1a0faa2caf8f2104bf16
parent45c8aa0d44affe4b93aee57e985da099b05d801b (diff)
downloadmailman-1db20c856fa192664d09f93caa1045036b4336dd.tar.gz
mailman-1db20c856fa192664d09f93caa1045036b4336dd.tar.zst
mailman-1db20c856fa192664d09f93caa1045036b4336dd.zip
-rw-r--r--src/mailman/app/subscriptions.py1
-rw-r--r--src/mailman/model/docs/registration.rst100
-rw-r--r--src/mailman/model/docs/subscriptions.rst153
3 files changed, 149 insertions, 105 deletions
diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py
index 7dea6c9cf..cfd1b59a7 100644
--- a/src/mailman/app/subscriptions.py
+++ b/src/mailman/app/subscriptions.py
@@ -615,6 +615,7 @@ class UnsubscriptionManager(BaseSubscriptionManager):
pre_confirmed=pre_confirmed,
pre_approved=pre_approved)
list(workflow)
+ return workflow.token, workflow.token_owner, workflow.member
@public
diff --git a/src/mailman/model/docs/registration.rst b/src/mailman/model/docs/registration.rst
deleted file mode 100644
index 4b1e13520..000000000
--- a/src/mailman/model/docs/registration.rst
+++ /dev/null
@@ -1,100 +0,0 @@
-============
-Registration
-============
-
-When a user wants to join a mailing list, they must register and verify their
-email address. Then depending on how the mailing list is configured, they may
-need to confirm their subscription and have it approved by the list
-moderator. The ``IRegistrar`` interface manages this work flow.
-
- >>> from mailman.interfaces.registrar import IRegistrar
-
-Registrars adapt mailing lists.
-
- >>> from mailman.interfaces.mailinglist import SubscriptionPolicy
- >>> mlist = create_list('ant@example.com')
- >>> mlist.send_welcome_message = False
- >>> mlist.subscription_policy = SubscriptionPolicy.open
- >>> registrar = IRegistrar(mlist)
-
-Usually, addresses are registered, but users with preferred addresses can be
-registered too.
-
- >>> from mailman.interfaces.usermanager import IUserManager
- >>> from zope.component import getUtility
- >>> anne = getUtility(IUserManager).create_address(
- ... 'anne@example.com', 'Anne Person')
-
-
-Register an email address
-=========================
-
-When the registration steps involve confirmation or moderator approval, the
-process will pause until these steps are completed. A unique token is created
-which represents this work flow.
-
-Anne attempts to join the mailing list.
-
- >>> token, token_owner, member = registrar.register(anne)
-
-Because her email address has not yet been verified, she has not yet become a
-member of the mailing list.
-
- >>> print(member)
- None
- >>> print(mlist.members.get_member('anne@example.com'))
- None
-
-Once she verifies her email address, she will become a member of the mailing
-list. In this case, verifying implies that she also confirms her wish to join
-the mailing list.
-
- >>> token, token_owner, member = registrar.confirm(token)
- >>> member
- <Member: Anne Person <anne@example.com> on ant@example.com
- as MemberRole.member>
- >>> mlist.members.get_member('anne@example.com')
- <Member: Anne Person <anne@example.com> on ant@example.com
- as MemberRole.member>
-
-
-Register a user
-===============
-
-Users can also register, but they must have a preferred address. The mailing
-list will deliver messages to this preferred address.
-
- >>> bart = getUtility(IUserManager).make_user(
- ... 'bart@example.com', 'Bart Person')
-
-Bart verifies his address and makes it his preferred address.
-
- >>> from mailman.utilities.datetime import now
- >>> preferred = list(bart.addresses)[0]
- >>> preferred.verified_on = now()
- >>> bart.preferred_address = preferred
-
-The mailing list's subscription policy does not require Bart to confirm his
-subscription, but the moderate does want to approve all subscriptions.
-
- >>> mlist.subscription_policy = SubscriptionPolicy.moderate
-
-Now when Bart registers as a user for the mailing list, a token will still be
-generated, but this is only used by the moderator. At first, Bart is not
-subscribed to the mailing list.
-
- >>> token, token_owner, member = registrar.register(bart)
- >>> print(member)
- None
- >>> print(mlist.members.get_member('bart@example.com'))
- None
-
-When the moderator confirms Bart's subscription, he joins the mailing list.
-
- >>> token, token_owner, member = registrar.confirm(token)
- >>> member
- <Member: Bart Person <bart@example.com> on ant@example.com
- as MemberRole.member>
- >>> mlist.members.get_member('bart@example.com')
- <Member: Bart Person <bart@example.com> on ant@example.com
- as MemberRole.member>
diff --git a/src/mailman/model/docs/subscriptions.rst b/src/mailman/model/docs/subscriptions.rst
index 14cb36b71..4c079d542 100644
--- a/src/mailman/model/docs/subscriptions.rst
+++ b/src/mailman/model/docs/subscriptions.rst
@@ -1,14 +1,157 @@
-=====================
+===============
+ Subscriptions
+===============
+
+When a user wants to join a mailing list, they must register and verify their
+email address. Then depending on how the mailing list is configured, they may
+need to confirm their subscription and have it approved by the list moderator.
+The ``ISubscriptionManager`` interface manages this work flow.
+
+ >>> from mailman.interfaces.subscriptions import ISubscriptionManager
+
+To begin, adapt a mailing list to an ``ISubscriptionManager``. This is a
+named interface because the same interface manages both subscriptions and
+unsubscriptions.
+
+ >>> from zope.component import getAdapter
+ >>> mlist = create_list('ant@example.com')
+ >>> manager = getAdapter(mlist, ISubscriptionManager, 'subscribe')
+
+Either addresses or users with a preferred address can be registered.
+
+ >>> from mailman.interfaces.usermanager import IUserManager
+ >>> from zope.component import getUtility
+ >>> anne = getUtility(IUserManager).create_address(
+ ... 'anne@example.com', 'Anne Person')
+
+
+Subscribing an email address
+============================
+
+The subscription process requires that the email address be verified. It may
+also require confirmation or moderator approval depending on the mailing
+list's subscription policy. For example, an open subscription policy does not
+require confirmation or approval, but the email address must still be
+verified, and the process will pause until these steps are completed.
+
+ >>> from mailman.interfaces.mailinglist import SubscriptionPolicy
+ >>> mlist.subscription_policy = SubscriptionPolicy.open
+
+Anne attempts to join the mailing list. A unique token is created which
+represents this work flow.
+
+ >>> token, token_owner, member = manager.register(anne)
+
+Because her email address has not yet been verified, she has not yet become a
+member of the mailing list.
+
+ >>> print(member)
+ None
+ >>> print(mlist.members.get_member('anne@example.com'))
+ None
+
+Once she verifies her email address, she will become a member of the mailing
+list. When the subscription policy requires confirmation, the verification
+process implies that she also confirms her wish to join the mailing list.
+
+ >>> token, token_owner, member = manager.confirm(token)
+ >>> member
+ <Member: Anne Person <anne@example.com> on ant@example.com
+ as MemberRole.member>
+ >>> mlist.members.get_member('anne@example.com')
+ <Member: Anne Person <anne@example.com> on ant@example.com
+ as MemberRole.member>
+
+
+Subscribing a user
+==================
+
+Users can also register, but they must have a preferred address. The mailing
+list will deliver messages to this preferred address.
+
+ >>> bart = getUtility(IUserManager).make_user(
+ ... 'bart@example.com', 'Bart Person')
+
+Bart verifies his address and makes it his preferred address.
+
+ >>> from mailman.utilities.datetime import now
+ >>> preferred = list(bart.addresses)[0]
+ >>> preferred.verified_on = now()
+ >>> bart.preferred_address = preferred
+
+The mailing list's subscription policy does not require Bart to confirm his
+subscription, but the moderate does want to approve all subscriptions.
+
+ >>> mlist.subscription_policy = SubscriptionPolicy.moderate
+
+Now when Bart registers as a user for the mailing list, a token will still be
+generated, but this is only used by the moderator. At first, Bart is not
+subscribed to the mailing list.
+
+ >>> token, token_owner, member = manager.register(bart)
+ >>> print(member)
+ None
+ >>> print(mlist.members.get_member('bart@example.com'))
+ None
+
+When the moderator confirms Bart's subscription, he joins the mailing list.
+
+ >>> token, token_owner, member = manager.confirm(token)
+ >>> member
+ <Member: Bart Person <bart@example.com> on ant@example.com
+ as MemberRole.member>
+ >>> mlist.members.get_member('bart@example.com')
+ <Member: Bart Person <bart@example.com> on ant@example.com
+ as MemberRole.member>
+
+
+Unsubscribing
+=============
+
+Similarly, unsubscribing a user depends on the mailing list's unsubscription
+policy. Of course, since the address or user is already subscribed, implying
+that their email address is already verified, that step is not required. To
+begin with unsubscribing, you need to adapt the mailing list to the same
+interface, but with a different name.
+
+ >>> manager = getAdapter(mlist, ISubscriptionManager, 'unsubscribe')
+
+If the mailing list's unsubscription policy is open, unregistering the
+subscription takes effect immediately.
+
+ >>> mlist.unsubscription_policy = SubscriptionPolicy.open
+ >>> token, token_owner, member = manager.unregister(anne)
+ >>> print(mlist.members.get_member('anne@example.com'))
+ None
+
+Usually though, the member must confirm their unsubscription request, to
+prevent an attacker from unsubscribing them from the list without their
+knowledge.
+
+ >>> mlist.unsubscription_policy = SubscriptionPolicy.confirm
+ >>> token, token_owner, member = manager.unregister(bart)
+
+Bart hasn't confirmed yet, so he's still a member of the list.
+
+ >>> mlist.members.get_member('bart@example.com')
+ <Member: Bart Person <bart@example.com> on ant@example.com
+ as MemberRole.member>
+
+Once Bart confirms, he's unsubscribed from the mailing list.
+
+ >>> token, token_owner, member = manager.confirm(token)
+ >>> print(mlist.members.get_member('bart@example.com'))
+ None
+
+
Subscription services
=====================
The ``ISubscriptionService`` utility provides higher level convenience methods
useful for searching, retrieving, iterating, and removing memberships across
-all mailing lists on th esystem. Adding new users is handled by the
-``IRegistrar`` interface.
+all mailing lists on the system.
>>> from mailman.interfaces.subscriptions import ISubscriptionService
- >>> from zope.component import getUtility
>>> service = getUtility(ISubscriptionService)
You can use the service to get all members of all mailing lists, for any
@@ -30,7 +173,7 @@ When there are some members, of any role on any mailing list, they can be
retrieved through the subscription service.
>>> from mailman.app.lifecycle import create_list
- >>> ant = create_list('ant@example.com')
+ >>> ant = mlist
>>> bee = create_list('bee@example.com')
>>> cat = create_list('cat@example.com')