~barry/mailman/events-and-web

« back to all changes in this revision

Viewing changes to src/mailman/app/registrar.py

  • Committer: Barry Warsaw
  • Date: 2012-11-25 20:48:08 UTC
  • Revision ID: barry@list.org-20121125204808-g0pvuil2xq559k4p
Interim commit for refactoring out web-centric logic.

* Use SubscriptionEvent to handle the sending of the welcome message.
* Use ConfirmationNeededEvent to send the confirmation message.
* For now, hard code the adminurl and comment out the listinfo_uri.
* Pend the list-id instead of the fqdn-listname
* Use the new configuration support for Postfix settings.
* Get rid of the IDomain's url_host, base_url, and scheme attributes, as well
  as the confirm_url() method. 
* Get rid of the IMailingList's script_url() method.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
__metaclass__ = type
23
23
__all__ = [
24
24
    'Registrar',
 
25
    'handle_ConfirmationNeededEvent',
25
26
    ]
26
27
 
27
28
 
28
29
import logging
29
30
 
30
31
from zope.component import getUtility
 
32
from zope.event import notify
31
33
from zope.interface import implementer
32
34
 
33
 
from mailman.app.notifications import send_welcome_message
34
35
from mailman.core.i18n import _
35
36
from mailman.email.message import UserNotification
36
37
from mailman.interfaces.address import IEmailValidator
37
38
from mailman.interfaces.listmanager import IListManager
38
39
from mailman.interfaces.member import DeliveryMode, MemberRole
39
40
from mailman.interfaces.pending import IPendable, IPendings
40
 
from mailman.interfaces.registrar import IRegistrar
 
41
from mailman.interfaces.registrar import ConfirmationNeededEvent, IRegistrar
41
42
from mailman.interfaces.templates import ITemplateLoader
42
43
from mailman.interfaces.usermanager import IUserManager
43
44
from mailman.utilities.datetime import now
69
70
            type=PendableRegistration.PEND_KEY,
70
71
            email=email,
71
72
            display_name=display_name,
72
 
            delivery_mode=delivery_mode.name)
73
 
        pendable['list_name'] = mlist.fqdn_listname
 
73
            delivery_mode=delivery_mode.name,
 
74
            list_id=mlist.list_id)
74
75
        token = getUtility(IPendings).add(pendable)
75
 
        # There are three ways for a user to confirm their subscription.  They
76
 
        # can reply to the original message and let the VERP'd return address
77
 
        # encode the token, they can reply to the robot and keep the token in
78
 
        # the Subject header, or they can click on the URL in the body of the
79
 
        # message and confirm through the web.
80
 
        subject = 'confirm ' + token
81
 
        confirm_address = mlist.confirm_address(token)
82
 
        # For i18n interpolation.
83
 
        confirm_url = mlist.domain.confirm_url(token)
84
 
        email_address = email
85
 
        domain_name = mlist.domain.mail_host
86
 
        contact_address = mlist.domain.contact_address
87
 
        # Send a verification email to the address.
88
 
        template = getUtility(ITemplateLoader).get(
89
 
            'mailman:///{0}/{1}/confirm.txt'.format(
90
 
                mlist.fqdn_listname,
91
 
                mlist.preferred_language.code))
92
 
        text = _(template)
93
 
        msg = UserNotification(email, confirm_address, subject, text)
94
 
        msg.send(mlist)
 
76
        # We now have everything we need to begin the confirmation dance.
 
77
        # Trigger the event to start the ball rolling, and return the
 
78
        # generated token.
 
79
        notify(ConfirmationNeededEvent(mlist, pendable, token))
95
80
        return token
96
81
 
97
82
    def confirm(self, token):
103
88
        missing = object()
104
89
        email = pendable.get('email', missing)
105
90
        display_name = pendable.get('display_name', missing)
106
 
        list_name = pendable.get('list_name', missing)
107
91
        pended_delivery_mode = pendable.get('delivery_mode', 'regular')
108
92
        try:
109
93
            delivery_mode = DeliveryMode[pended_delivery_mode]
151
135
            pass
152
136
        address.verified_on = now()
153
137
        # If this registration is tied to a mailing list, subscribe the person
154
 
        # to the list right now, and possibly send a welcome message.
155
 
        list_name = pendable.get('list_name')
156
 
        if list_name is not None:
157
 
            mlist = getUtility(IListManager).get(list_name)
158
 
            if mlist:
 
138
        # to the list right now.  That will generate a SubscriptionEvent,
 
139
        # which can be used to send a welcome message.
 
140
        list_id = pendable.get('list_id')
 
141
        if list_id is not None:
 
142
            mlist = getUtility(IListManager).get_by_list_id(list_id)
 
143
            if mlist is not None:
159
144
                member = mlist.subscribe(address, MemberRole.member)
160
145
                member.preferences.delivery_mode = delivery_mode
161
 
                if mlist.send_welcome_message:
162
 
                    send_welcome_message(mlist,
163
 
                                         address.email,
164
 
                                         mlist.preferred_language,
165
 
                                         delivery_mode)
166
146
        return True
167
147
 
168
148
    def discard(self, token):
169
149
        # Throw the record away.
170
150
        getUtility(IPendings).confirm(token)
 
151
 
 
152
 
 
153
 
 
154
def handle_ConfirmationNeededEvent(event):
 
155
    if not isinstance(event, ConfirmationNeededEvent):
 
156
        return
 
157
    # Send a mail-back confirmation message to the user trying to verify their
 
158
    # address.  The default version of this does not include any click-through
 
159
    # link; you must reply to the original message.
 
160
    subject = 'confirm ' + event.token
 
161
    mlist = getUtility(IListManager).get_by_list_id(event.pendable['list_id'])
 
162
    confirm_address = mlist.confirm_address(event.token)
 
163
    # For i18n interpolation.
 
164
    email_address = event.pendable['email']
 
165
    domain_name = mlist.domain.mail_host
 
166
    contact_address = mlist.domain.contact_address
 
167
    # Send a verification email to the address.
 
168
    template = getUtility(ITemplateLoader).get(
 
169
        'mailman:///{0}/{1}/confirm.txt'.format(
 
170
            mlist.fqdn_listname,
 
171
            mlist.preferred_language.code))
 
172
    text = _(template)
 
173
    msg = UserNotification(email_address, confirm_address, subject, text)
 
174
    msg.send(mlist)