summaryrefslogtreecommitdiff
path: root/src/mailman/interfaces
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/interfaces')
-rw-r--r--src/mailman/interfaces/bans.py9
-rw-r--r--src/mailman/interfaces/listmanager.py10
-rw-r--r--src/mailman/interfaces/mailinglist.py18
-rw-r--r--src/mailman/interfaces/registrar.py112
-rw-r--r--src/mailman/interfaces/subscriptions.py170
-rw-r--r--src/mailman/interfaces/template.py3
-rw-r--r--src/mailman/interfaces/workflow.py14
7 files changed, 203 insertions, 133 deletions
diff --git a/src/mailman/interfaces/bans.py b/src/mailman/interfaces/bans.py
index 2e320965a..055ad69a3 100644
--- a/src/mailman/interfaces/bans.py
+++ b/src/mailman/interfaces/bans.py
@@ -46,6 +46,9 @@ class IBanManager(Interface):
to an `IBanManager`. To manage global bans, adapt ``None``.
"""
+ bans = Attribute(
+ """A `QuerySequence` over all the banned emails.""")
+
def ban(email):
"""Ban an email address from subscribing to a mailing list.
@@ -94,8 +97,6 @@ class IBanManager(Interface):
"""
def __iter__():
- """Iterate over all banned addresses.
+ """An iterator over all the banned email addresses.
- :return: The list of all banned addresses.
- :rtype: list of `IBan`
- """
+ :return: iterator over `IBan`"""
diff --git a/src/mailman/interfaces/listmanager.py b/src/mailman/interfaces/listmanager.py
index fddec06c8..2c7208496 100644
--- a/src/mailman/interfaces/listmanager.py
+++ b/src/mailman/interfaces/listmanager.py
@@ -142,3 +142,13 @@ class IListManager(Interface):
name_components = Attribute(
"""An iterator over the 2-tuple of (list_name, mail_host) for all
mailing lists managed by this list manager.""")
+
+ def find(*, advertised=None, mail_host=None):
+ """Search for mailing lists matching some criteria.
+
+ The keyword arguments are mailing list properties that will be
+ filtered upon.
+
+ :return: The list of filtered mailing lists.
+ :rtype: list of `IMailingList`
+ """
diff --git a/src/mailman/interfaces/mailinglist.py b/src/mailman/interfaces/mailinglist.py
index 19db025d1..877016f41 100644
--- a/src/mailman/interfaces/mailinglist.py
+++ b/src/mailman/interfaces/mailinglist.py
@@ -46,6 +46,7 @@ class ReplyToMunging(Enum):
@public
class SubscriptionPolicy(Enum):
+ """All subscription/unsubscription policies for a mailing list."""
# Neither confirmation, nor moderator approval is required.
open = 0
# The user must confirm the subscription.
@@ -256,6 +257,9 @@ class IMailingList(Interface):
subscription_policy = Attribute(
"""The policy for subscribing new members to the list.""")
+ unsubscription_policy = Attribute(
+ """The policy for unsubscribing members from the list.""")
+
subscribers = Attribute(
"""An iterator over all IMembers subscribed to this list, with any
role.
@@ -270,6 +274,18 @@ class IMailingList(Interface):
:rtype: Roster
"""
+ def is_subscribed(subscriber, role=MemberRole.member):
+ """Is the given address or user subscribed to the mailing list?
+
+ :param subscriber: The address or user to check.
+ :type subscriber: `IUser` or `IAddress`
+ :param role: The role being checked (e.g. a member, owner, or
+ moderator of a mailing list).
+ :type role: `MemberRole`
+ :return: A flag indicating whether the subscriber is already
+ subscribed to the mailing list or not.
+ """
+
def subscribe(subscriber, role=MemberRole.member):
"""Subscribe the given address or user to the mailing list.
@@ -278,7 +294,7 @@ class IMailingList(Interface):
has one, otherwise no address for the user appears in the rosters.
:type subscriber: `IUser` or `IAddress`
:param role: The role being subscribed to (e.g. a member, owner, or
- moderator of a mailing list.
+ moderator of a mailing list).
:type role: `MemberRole`
:return: The member object representing the subscription.
:rtype: `IMember`
diff --git a/src/mailman/interfaces/registrar.py b/src/mailman/interfaces/registrar.py
deleted file mode 100644
index e2cec5fbb..000000000
--- a/src/mailman/interfaces/registrar.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright (C) 2007-2016 by the Free Software Foundation, Inc.
-#
-# This file is part of GNU Mailman.
-#
-# GNU Mailman is free software: you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-
-"""Interface describing a user registration service.
-
-This is a higher level interface to user registration, address confirmation,
-etc. than the IUserManager. The latter does no validation, syntax checking,
-or confirmation, while this interface does.
-"""
-
-from mailman import public
-from zope.interface import Interface
-
-
-@public
-class ConfirmationNeededEvent:
- """Triggered when an address needs confirmation.
-
- Addresses must be verified before they can receive messages or post
- to mailing list. The confirmation message is sent to the user when
- this event is triggered.
- """
- def __init__(self, mlist, token, email):
- self.mlist = mlist
- self.token = token
- self.email = email
-
-
-@public
-class IRegistrar(Interface):
- """Interface for subscribing addresses and users.
-
- This is a higher level interface to user registration, email address
- confirmation, etc. than the IUserManager. The latter does no validation,
- syntax checking, or confirmation, while this interface does.
-
- To use this, adapt an ``IMailingList`` to this interface.
- """
-
- def register(subscriber=None, *,
- pre_verified=False, pre_confirmed=False, pre_approved=False):
- """Subscribe an address or user according to subscription policies.
-
- The mailing list's subscription policy is used to subscribe
- `subscriber` to the given mailing list. The subscriber can be
- an ``IUser``, in which case the user must have a preferred
- address, and that preferred address will be subscribed. The
- subscriber can also be an ``IAddress``, in which case the
- address will be subscribed.
-
- The workflow may pause (i.e. be serialized, saved, and
- suspended) when some out-of-band confirmation step is required.
- For example, if the user must confirm, or the moderator must
- approve the subscription. Use the ``confirm(token)`` method to
- resume the workflow.
-
- :param subscriber: The user or address to subscribe.
- :type email: ``IUser`` or ``IAddress``
- :return: A 3-tuple is returned where the first element is the token
- hash, the second element is a ``TokenOwner`, and the third element
- is the subscribed member. If the subscriber got subscribed
- immediately, the token will be None and the member will be
- an ``IMember``. If the subscription got held, the token
- will be a hash and the member will be None.
- :rtype: (str-or-None, ``TokenOwner``, ``IMember``-or-None)
- :raises MembershipIsBannedError: when the address being subscribed
- appears in the global or list-centric bans.
- """
-
- def confirm(token):
- """Continue any paused workflow.
-
- Confirmation may occur after the user confirms their
- subscription request, or their email address must be verified,
- or the moderator must approve the subscription request.
-
- :param token: A token matching a workflow.
- :type token: string
- :return: A 3-tuple is returned where the first element is the token
- hash, the second element is a ``TokenOwner`, and the third element
- is the subscribed member. If the subscriber got subscribed
- immediately, the token will be None and the member will be
- an ``IMember``. If the subscription is still being held, the token
- will be a hash and the member will be None.
- :rtype: (str-or-None, ``TokenOwner``, ``IMember``-or-None)
- :raises LookupError: when no workflow is associated with the token.
- """
-
- def discard(token):
- """Discard the workflow matched to the given `token`.
-
- :param token: A token matching a pending event with a type of
- 'registration'.
- :raises LookupError: when no workflow is associated with the token.
- """
-
- def evict():
- """Evict all saved workflows which have expired."""
diff --git a/src/mailman/interfaces/subscriptions.py b/src/mailman/interfaces/subscriptions.py
index 382a23ac0..284261de5 100644
--- a/src/mailman/interfaces/subscriptions.py
+++ b/src/mailman/interfaces/subscriptions.py
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License along with
# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
-"""Membership interface for REST."""
+"""Subscription management."""
from collections import namedtuple
from enum import Enum
@@ -78,8 +78,35 @@ class TokenOwner(Enum):
@public
+class SubscriptionConfirmationNeededEvent:
+ """Triggered when a subscription needs confirmation.
+
+ Addresses must be verified before they can receive messages or post
+ to mailing list. The confirmation message is sent to the user when
+ this event is triggered.
+ """
+ def __init__(self, mlist, token, email):
+ self.mlist = mlist
+ self.token = token
+ self.email = email
+
+
+@public
+class UnsubscriptionConfirmationNeededEvent:
+ """Triggered when an unsubscription request needs confirmation.
+
+ The confirmation message is sent to the user when this event is
+ triggered.
+ """
+ def __init__(self, mlist, token, email):
+ self.mlist = mlist
+ self.token = token
+ self.email = email
+
+
+@public
class ISubscriptionService(Interface):
- """General Subscription services."""
+ """General subscription services."""
def get_members():
"""Return a sequence of all members of all mailing lists.
@@ -121,8 +148,8 @@ class ISubscriptionService(Interface):
:type list_id: string
:param role: The member role.
:type role: `MemberRole`
- :return: The list of all memberships, which may be empty.
- :rtype: list of `IMember`
+ :return: A sequence of all memberships, which may be empty.
+ :rtype: A `QuerySequence` of `IMember`
"""
def find_member(subscriber=None, list_id=None, role=None):
@@ -178,3 +205,138 @@ class ISubscriptionService(Interface):
:rtype: 2-tuple of (set-of-strings, set-of-strings)
:raises NoSuchListError: if the named mailing list does not exist.
"""
+
+
+@public
+class ISubscriptionManager(Interface):
+ """Handling subscription and unsubscription of addresses and users.
+
+ This is a higher level interface to user registration and
+ unregistration, email address confirmation, etc. than the
+ `IUserManager`. The latter does no validation, syntax checking, or
+ confirmation, while this interface does.
+
+ To use this, adapt an ``IMailingList`` to this interface.
+ """
+ def register(subscriber=None, *,
+ pre_verified=False, pre_confirmed=False, pre_approved=False):
+ """Subscribe an address or user according to subscription policies.
+
+ The mailing list's subscription policy is used to subscribe
+ `subscriber` to the given mailing list. The subscriber can be
+ an ``IUser``, in which case the user must have a preferred
+ address, and that preferred address will be subscribed. The
+ subscriber can also be an ``IAddress``, in which case the
+ address will be subscribed.
+
+ The workflow may pause (i.e. be serialized, saved, and
+ suspended) when some out-of-band confirmation step is required.
+ For example, if the user must confirm, or the moderator must
+ approve the subscription. Use the ``confirm(token)`` method to
+ resume the workflow.
+
+ :param subscriber: The user or address to subscribe.
+ :type email: ``IUser`` or ``IAddress``
+ :param pre_verified: A flag indicating whether the subscriber's email
+ address should be considered pre-verified. Normally a never
+ before seen email address must be verified by mail-back
+ confirmation. Setting this flag to True automatically verifies
+ such addresses without the mail-back. (A confirmation message may
+ still be sent under other conditions.)
+ :type pre_verified: bool
+ :param pre_confirmed: A flag indicating whether, when required by the
+ subscription policy, a subscription request should be considered
+ pre-confirmed. Normally in such cases, a mail-back confirmation
+ message is sent to the subscriber, which must be positively
+ acknowledged by some manner. Setting this flag to True
+ automatically confirms the subscription request. (A confirmation
+ message may still be sent under other conditions.)
+ :type pre_confirmed: bool
+ :param pre_approved: A flag indicating whether, when required by the
+ subscription policy, a subscription request should be considered
+ pre-approved. Normally in such cases, the list administrator is
+ notified that an approval is necessary, which must be positively
+ acknowledged in some manner. Setting this flag to True
+ automatically approves the subscription request.
+ :type pre_approved: bool
+ :return: A 3-tuple is returned where the first element is the token
+ hash, the second element is a ``TokenOwner`, and the third element
+ is the subscribed member. If the subscriber got subscribed
+ immediately, the token will be None and the member will be
+ an ``IMember``. If the subscription got held, the token
+ will be a hash and the member will be None.
+ :rtype: (str-or-None, ``TokenOwner``, ``IMember``-or-None)
+ :raises MembershipIsBannedError: when the address being subscribed
+ appears in the global or list-centric bans.
+ """
+
+ def unregister(subscriber=None, *,
+ pre_confirmed=False, pre_approved=False):
+ """Unsubscribe an address or user according to subscription policies.
+
+ The mailing list's unsubscription policy is used to unsubscribe
+ `subscriber` from the given mailing list. The subscriber can be
+ an ``IUser`` or an ``IAddress``, and must already be subscribed to the
+ mailing list.
+
+ The workflow may pause (i.e. be serialized, saved, and
+ suspended) when some out-of-band confirmation step is required.
+ For example, if the user must confirm, or the moderator must
+ approve the unsubscription. Use the ``confirm(token)`` method to
+ resume the workflow.
+
+ :param subscriber: The user or address to unsubscribe.
+ :type email: ``IUser`` or ``IAddress``
+ :param pre_confirmed: A flag indicating whether, when required by the
+ unsubscription policy, an unsubscription request should be
+ considered pre-confirmed. Normally in such cases, a mail-back
+ confirmation message is sent to the subscriber, which must be
+ positively acknowledged by some manner. Setting this flag to True
+ automatically confirms the unsubscription request. (A confirmation
+ message may still be sent under other conditions.)
+ :type pre_confirmed: bool
+ :param pre_approved: A flag indicating whether, when required by the
+ unsubscription policy, an unsubscription request should be
+ considered pre-approved. Normally in such cases, the list
+ administrator is notified that an approval is necessary, which
+ must be positively acknowledged in some manner. Setting this flag
+ to True automatically approves the unsubscription request.
+ :type pre_approved: bool
+ :return: A 3-tuple is returned where the first element is the token
+ hash, the second element is a ``TokenOwner`, and the third element
+ is the unsubscribing member. If the subscriber got unsubscribed
+ immediately, the token will be None and the member will be
+ an ``IMember``. If the unsubscription got held, the token
+ will be a hash and the member will be None.
+ :rtype: (str-or-None, ``TokenOwner``, ``IMember``-or-None)
+ """
+
+ def confirm(token):
+ """Continue any paused workflow.
+
+ Confirmation may occur after the user confirms their
+ subscription request, or their email address must be verified,
+ or the moderator must approve the subscription request.
+
+ :param token: A token matching a workflow.
+ :type token: string
+ :return: A 3-tuple is returned where the first element is the token
+ hash, the second element is a ``TokenOwner`, and the third element
+ is the subscribed member. If the subscriber got subscribed
+ immediately, the token will be None and the member will be
+ an ``IMember``. If the subscription is still being held, the token
+ will be a hash and the member will be None.
+ :rtype: (str-or-None, ``TokenOwner``, ``IMember``-or-None)
+ :raises LookupError: when no workflow is associated with the token.
+ """
+
+ def discard(token):
+ """Discard the workflow matched to the given `token`.
+
+ :param token: A token matching a pending event with a type of
+ 'registration'.
+ :raises LookupError: when no workflow is associated with the token.
+ """
+
+ def evict():
+ """Evict all saved workflows which have expired."""
diff --git a/src/mailman/interfaces/template.py b/src/mailman/interfaces/template.py
index 442f1eeda..24f956b78 100644
--- a/src/mailman/interfaces/template.py
+++ b/src/mailman/interfaces/template.py
@@ -157,6 +157,7 @@ class ITemplateManager(Interface):
:type context: str
"""
+
# Mapping of template names to their in-source file names. A None value means
# that there is no file in the tree for that template.
@@ -171,7 +172,7 @@ ALL_TEMPLATES = {
'list:admin:notice:unrecognized',
'list:admin:notice:unsubscribe',
'list:member:digest:masthead',
- 'list:user:action:confirm',
+ 'list:user:action:subscribe',
'list:user:action:unsubscribe',
'list:user:notice:hold',
'list:user:notice:no-more-today',
diff --git a/src/mailman/interfaces/workflow.py b/src/mailman/interfaces/workflow.py
index bf2138959..9846f4683 100644
--- a/src/mailman/interfaces/workflow.py
+++ b/src/mailman/interfaces/workflow.py
@@ -25,8 +25,6 @@ from zope.interface import Attribute, Interface
class IWorkflowState(Interface):
"""The state of a workflow."""
- name = Attribute('The name of the workflow.')
-
token = Attribute('A unique key identifying the workflow instance.')
step = Attribute("This workflow's next step.")
@@ -38,11 +36,9 @@ class IWorkflowState(Interface):
class IWorkflowStateManager(Interface):
"""The workflow states manager."""
- def save(name, token, step, data=None):
+ def save(token, step, data=None):
"""Save the state of a workflow.
- :param name: The name of the workflow.
- :type name: str
:param token: A unique token identifying this workflow instance.
:type token: str
:param step: The next step for this workflow.
@@ -51,11 +47,9 @@ class IWorkflowStateManager(Interface):
:type data: str
"""
- def restore(name, token):
+ def restore(token):
"""Get the saved state for a workflow or None if nothing was saved.
- :param name: The name of the workflow.
- :type name: str
:param token: A unique token identifying this workflow instance.
:type token: str
:return: The saved state associated with this name/token pair, or None
@@ -63,11 +57,9 @@ class IWorkflowStateManager(Interface):
:rtype: ``IWorkflowState``
"""
- def discard(name, token):
+ def discard(token):
"""Throw away the saved state for a workflow.
- :param name: The name of the workflow.
- :type name: str
:param token: A unique token identifying this workflow instance.
:type token: str
"""