1 # Copyright (C) 2007-2016 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """Implementation of the IRegistrar interface."""
22 from mailman
import public
23 from mailman
.app
.subscriptions
import SubscriptionWorkflow
24 from mailman
.core
.i18n
import _
25 from mailman
.database
.transaction
import flush
26 from mailman
.email
.message
import UserNotification
27 from mailman
.interfaces
.pending
import IPendable
, IPendings
28 from mailman
.interfaces
.registrar
import ConfirmationNeededEvent
, IRegistrar
29 from mailman
.interfaces
.templates
import ITemplateLoader
30 from mailman
.interfaces
.workflow
import IWorkflowStateManager
31 from zope
.component
import getUtility
32 from zope
.interface
import implementer
35 log
= logging
.getLogger('mailman.error')
38 @implementer(IPendable
)
39 class PendableRegistration(dict):
40 PEND_TYPE
= 'registration'
44 @implementer(IRegistrar
)
46 """Handle registrations and confirmations for subscriptions."""
48 def __init__(self
, mlist
):
51 def register(self
, subscriber
=None, *,
52 pre_verified
=False, pre_confirmed
=False, pre_approved
=False):
53 """See `IRegistrar`."""
54 workflow
= SubscriptionWorkflow(
55 self
._mlist
, subscriber
,
56 pre_verified
=pre_verified
,
57 pre_confirmed
=pre_confirmed
,
58 pre_approved
=pre_approved
)
60 return workflow
.token
, workflow
.token_owner
, workflow
.member
62 def confirm(self
, token
):
63 """See `IRegistrar`."""
64 workflow
= SubscriptionWorkflow(self
._mlist
)
65 workflow
.token
= token
68 return workflow
.token
, workflow
.token_owner
, workflow
.member
70 def discard(self
, token
):
71 """See `IRegistrar`."""
73 getUtility(IPendings
).confirm(token
)
74 getUtility(IWorkflowStateManager
).discard(
75 SubscriptionWorkflow
.__name
__, token
)
79 def handle_ConfirmationNeededEvent(event
):
80 if not isinstance(event
, ConfirmationNeededEvent
):
82 # There are three ways for a user to confirm their subscription. They
83 # can reply to the original message and let the VERP'd return address
84 # encode the token, they can reply to the robot and keep the token in
85 # the Subject header, or they can click on the URL in the body of the
86 # message and confirm through the web.
87 subject
= 'confirm ' + event
.token
88 confirm_address
= event
.mlist
.confirm_address(event
.token
)
89 # For i18n interpolation.
90 confirm_url
= event
.mlist
.domain
.confirm_url(event
.token
) # flake8: noqa
91 email_address
= event
.email
92 domain_name
= event
.mlist
.domain
.mail_host
# flake8: noqa
93 contact_address
= event
.mlist
.owner_address
# flake8: noqa
94 # Send a verification email to the address.
95 template
= getUtility(ITemplateLoader
).get(
96 'mailman:///{}/{}/confirm.txt'.format(
97 event
.mlist
.fqdn_listname
,
98 event
.mlist
.preferred_language
.code
))
100 msg
= UserNotification(email_address
, confirm_address
, subject
, text
)
101 msg
.send(event
.mlist
, add_precedence
=False)