diff options
| author | Barry Warsaw | 2015-04-13 12:16:28 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2015-04-13 12:16:28 -0400 |
| commit | c595c3d907f111d80852837c686b23aea9ee40c1 (patch) | |
| tree | c28571aebb3642a1b6f33572855374d30c8085e4 /src/mailman/app/subscriptions.py | |
| parent | 9806f9c751f85b6ad6e9dea58d9e3dde36c7f2bc (diff) | |
| download | mailman-c595c3d907f111d80852837c686b23aea9ee40c1.tar.gz mailman-c595c3d907f111d80852837c686b23aea9ee40c1.tar.zst mailman-c595c3d907f111d80852837c686b23aea9ee40c1.zip | |
Diffstat (limited to 'src/mailman/app/subscriptions.py')
| -rw-r--r-- | src/mailman/app/subscriptions.py | 56 |
1 files changed, 48 insertions, 8 deletions
diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py index 22f4bdf56..982c04547 100644 --- a/src/mailman/app/subscriptions.py +++ b/src/mailman/app/subscriptions.py @@ -26,24 +26,30 @@ __all__ = [ import uuid +import logging +from email.utils import formataddr from enum import Enum +from datetime import timedelta from mailman.app.membership import add_member, delete_member -from mailman.app.moderator import hold_subscription from mailman.app.workflow import Workflow from mailman.core.constants import system_preferences +from mailman.core.i18n import _ from mailman.database.transaction import dbconnection +from mailman.email.message import UserNotification from mailman.interfaces.address import IAddress from mailman.interfaces.listmanager import ( IListManager, ListDeletingEvent, NoSuchListError) from mailman.interfaces.mailinglist import SubscriptionPolicy from mailman.interfaces.member import DeliveryMode, MemberRole +from mailman.interfaces.pending import IPendable, IPendings from mailman.interfaces.subscriptions import ( ISubscriptionService, MissingUserError, RequestRecord) from mailman.interfaces.user import IUser from mailman.interfaces.usermanager import IUserManager from mailman.model.member import Member from mailman.utilities.datetime import now +from mailman.utilities.i18n import make from operator import attrgetter from sqlalchemy import and_, or_ from uuid import UUID @@ -51,6 +57,9 @@ from zope.component import getUtility from zope.interface import implementer +log = logging.getLogger('mailman.subscribe') + + def _membership_sort_key(member): """Sort function for find_members(). @@ -66,6 +75,11 @@ class WhichSubscriber(Enum): user = 2 +@implementer(IPendable) +class Pendable(dict): + pass + + class SubscriptionWorkflow(Workflow): """Workflow of a subscription request.""" @@ -201,18 +215,44 @@ class SubscriptionWorkflow(Workflow): self.mlist.subscribe(self.subscriber) def _step_get_moderator_approval(self): - # In order to get the moderator's approval, we need to hold the - # subscription request in the database - request = RequestRecord( - self.address.email, self.subscriber.display_name, - # XXX Need to get these last to into the constructor. - DeliveryMode.regular, 'en') - self.token = hold_subscription(self.mlist, request) + # Getting the moderator's approval requires several steps. We'll need + # to suspend this workflow for an indeterminate amount of time while + # we wait for that approval. We need a unique token for this + # suspended workflow, so we'll create a minimal pending record. We + # also might need to send an email notification to the list + # moderators. + # + # Start by creating the pending record. This will give us a hash + # token we can use to uniquely name this workflow. It only needs to + # contain the current date, which we'll use to expire requests from + # the database, say if the moderator never approves the request. + pendable = Pendable(when=now().isoformat()) + self.token = getUtility(IPendings).add(pendable, timedelta(days=3650)) # Here's the next step in the workflow, assuming the moderator # approves of the subscription. If they don't, the workflow and # subscription request will just be thrown away. self.push('subscribe_from_restored') self.save() + log.info('{}: held subscription request from {}'.format( + self.mlist.fqdn_listname, self.address.email)) + # Possibly send a notification to the list moderators. + if self.mlist.admin_immed_notify: + subject = _( + 'New subscription request to $self.mlist.display_name ' + 'from $self.address.email') + username = formataddr( + (self.subscriber.display_name, self.address.email)) + text = make('subauth.txt', + mailing_list=self.mlist, + username=username, + listname=self.mlist.fqdn_listname, + ) + # This message should appear to come from the <list>-owner so as + # to avoid any useless bounce processing. + msg = UserNotification( + self.mlist.owner_address, self.mlist.owner_address, + subject, text, self.mlist.preferred_language) + msg.send(self.mlist, tomoderators=True) # The workflow must stop running here. raise StopIteration |
