diff options
| author | J08nY | 2017-07-12 18:57:01 +0200 |
|---|---|---|
| committer | J08nY | 2017-08-30 13:18:40 +0200 |
| commit | 50a51a08f067f12b3a2d72a36b4173d9d2249a69 (patch) | |
| tree | c5c51775a8e13c67dbacb8abdbc33dd148540711 | |
| parent | 4cf5a425fe1242d3ceb6a0f68d0655b2ffe05594 (diff) | |
| download | mailman-50a51a08f067f12b3a2d72a36b4173d9d2249a69.tar.gz mailman-50a51a08f067f12b3a2d72a36b4173d9d2249a69.tar.zst mailman-50a51a08f067f12b3a2d72a36b4173d9d2249a69.zip | |
| -rw-r--r-- | src/mailman/app/subscriptions.py | 15 | ||||
| -rw-r--r-- | src/mailman/rest/docs/sub-moderation.rst | 4 | ||||
| -rw-r--r-- | src/mailman/rest/sub_moderation.py | 14 | ||||
| -rw-r--r-- | src/mailman/workflows/common.py | 36 |
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) |
