summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/app/subscriptions.py15
-rw-r--r--src/mailman/rest/docs/sub-moderation.rst4
-rw-r--r--src/mailman/rest/sub_moderation.py14
-rw-r--r--src/mailman/workflows/common.py36
4 files changed, 45 insertions, 24 deletions
diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py
index cc28ea859..a0c0c8059 100644
--- a/src/mailman/app/subscriptions.py
+++ b/src/mailman/app/subscriptions.py
@@ -17,6 +17,7 @@
"""Handle subscriptions."""
+from mailman.config import config
from mailman.database.transaction import flush
from mailman.interfaces.listmanager import ListDeletingEvent
from mailman.interfaces.pending import IPendings
@@ -56,11 +57,13 @@ class SubscriptionManager:
if pendable is None:
raise LookupError
workflow_type = pendable.get('type')
- assert workflow_type in (PendableSubscription.PEND_TYPE,
- PendableUnsubscription.PEND_TYPE)
- workflow = (self._mlist.subscription_policy
- if workflow_type == PendableSubscription.PEND_TYPE
- else self._mlist.unsubscription_policy)(self._mlist)
+ if workflow_type in {PendableSubscription.PEND_TYPE,
+ PendableUnsubscription.PEND_TYPE}:
+ workflow = (self._mlist.subscription_policy
+ if workflow_type == PendableSubscription.PEND_TYPE
+ else self._mlist.unsubscription_policy)(self._mlist)
+ else:
+ workflow = config.workflows[workflow_type](self._mlist)
workflow.token = token
workflow.restore()
# In order to just run the whole workflow, all we need to do
@@ -84,6 +87,6 @@ def handle_ListDeletingEvent(event):
return
# Find all the members still associated with the mailing list.
members = getUtility(ISubscriptionService).find_members(
- list_id=event.mailing_list.list_id)
+ list_id=event.mailing_list.list_id)
for member in members:
member.unsubscribe()
diff --git a/src/mailman/rest/docs/sub-moderation.rst b/src/mailman/rest/docs/sub-moderation.rst
index 3c6f30aef..8bf95fcd2 100644
--- a/src/mailman/rest/docs/sub-moderation.rst
+++ b/src/mailman/rest/docs/sub-moderation.rst
@@ -47,7 +47,7 @@ The subscription request can be viewed in the REST API.
list_id: ant.example.com
token: 0000000000000000000000000000000000000001
token_owner: moderator
- type: subscription
+ type: sub-policy-moderate
when: 2005-08-01T07:49:23
http_etag: "..."
start: 0
@@ -68,7 +68,7 @@ You can view an individual membership change request by providing the token
list_id: ant.example.com
token: 0000000000000000000000000000000000000001
token_owner: moderator
- type: subscription
+ type: sub-policy-moderate
when: 2005-08-01T07:49:23
diff --git a/src/mailman/rest/sub_moderation.py b/src/mailman/rest/sub_moderation.py
index 47745b729..ad1c5751b 100644
--- a/src/mailman/rest/sub_moderation.py
+++ b/src/mailman/rest/sub_moderation.py
@@ -16,13 +16,16 @@
# GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
"""REST API for held subscription requests."""
+from itertools import chain
from mailman.app.moderator import send_rejection
+from mailman.config import config
from mailman.core.i18n import _
from mailman.interfaces.action import Action
from mailman.interfaces.member import AlreadySubscribedError
from mailman.interfaces.pending import IPendings
from mailman.interfaces.subscriptions import ISubscriptionManager
+from mailman.interfaces.workflows import ISubscriptionWorkflow
from mailman.rest.helpers import (
CollectionMixin, bad_request, child, conflict, etag, no_content,
not_found, okay)
@@ -122,8 +125,15 @@ class SubscriptionRequests(_ModerationBase, CollectionMixin):
self._mlist = mlist
def _get_collection(self, request):
- pendings = getUtility(IPendings).find(
- mlist=self._mlist, pend_type='subscription')
+ sub_workflows = [workflow_class
+ for workflow_class in config.workflows.values()
+ if ISubscriptionWorkflow.implementedBy(workflow_class)
+ ]
+ generators = [getUtility(IPendings).find(mlist=self._mlist,
+ pend_type=sub_workflow.name)
+ for
+ sub_workflow in sub_workflows]
+ pendings = chain.from_iterable(generators)
return [token for token, pendable in pendings]
def on_get(self, request, response):
diff --git a/src/mailman/workflows/common.py b/src/mailman/workflows/common.py
index 41733f6e5..1f63d3d1d 100644
--- a/src/mailman/workflows/common.py
+++ b/src/mailman/workflows/common.py
@@ -23,8 +23,10 @@ import logging
from datetime import timedelta
from email.utils import formataddr
from enum import Enum
+from itertools import chain
from mailman.app.membership import delete_member
+from mailman.config import config
from mailman.core.i18n import _
from mailman.email.message import UserNotification
from mailman.interfaces.address import IAddress
@@ -38,14 +40,12 @@ from mailman.interfaces.subscriptions import (SubscriptionPendingError,
from mailman.interfaces.template import ITemplateLoader
from mailman.interfaces.user import IUser
from mailman.interfaces.usermanager import IUserManager
-from mailman.interfaces.workflows import (ISubscriptionWorkflow,
- IUnsubscriptionWorkflow, IWorkflow)
+from mailman.interfaces.workflows import ISubscriptionWorkflow
from mailman.utilities.datetime import now
from mailman.utilities.string import expand, wrap
from mailman.workflows.base import Workflow
from zope.component import getUtility
from zope.interface import implementer
-from zope.interface.exceptions import DoesNotImplement
log = logging.getLogger('mailman.subscribe')
@@ -157,14 +157,7 @@ class SubscriptionWorkflowCommon(Workflow):
self.token = None
return
- if ISubscriptionWorkflow.implementedBy(self.__class__):
- pendable_class = PendableSubscription
- elif IUnsubscriptionWorkflow.implementedBy(self.__class__):
- pendable_class = PendableUnsubscription
- else:
- raise DoesNotImplement(IWorkflow)
-
- pendable = pendable_class(
+ pendable = self.pendable_class()(
list_id=self.mlist.list_id,
email=self.address.email,
display_name=self.address.display_name,
@@ -173,6 +166,13 @@ class SubscriptionWorkflowCommon(Workflow):
)
self.token = pendings.add(pendable, timedelta(days=3650))
+ @classmethod
+ def pendable_class(cls):
+ @implementer(IPendable)
+ class Pendable(dict):
+ PEND_TYPE = cls.name
+ return Pendable
+
class SubscriptionBase(SubscriptionWorkflowCommon):
@@ -219,9 +219,17 @@ class SubscriptionBase(SubscriptionWorkflowCommon):
if IBanManager(self.mlist).is_banned(self.address.email):
raise MembershipIsBannedError(self.mlist, self.address.email)
# Check if there is already a subscription request for this email.
- pendings = getUtility(IPendings).find(
- mlist=self.mlist,
- pend_type='subscription')
+ # Look at all known subscription workflows, because any pending
+ # subscription workflow is exclusive.
+ sub_workflows = [workflow_class
+ for workflow_class in config.workflows.values()
+ if ISubscriptionWorkflow.implementedBy(workflow_class)
+ ]
+ generators = [getUtility(IPendings).find(mlist=self.mlist,
+ pend_type=sub_workflow.name)
+ for
+ sub_workflow in sub_workflows]
+ pendings = chain.from_iterable(generators)
for token, pendable in pendings:
if pendable['email'] == self.address.email:
raise SubscriptionPendingError(self.mlist, self.address.email)