diff options
| author | bwarsaw | 2001-07-29 19:14:02 +0000 |
|---|---|---|
| committer | bwarsaw | 2001-07-29 19:14:02 +0000 |
| commit | 9bb06a8080632c0bedddf8182823da8b3b24363f (patch) | |
| tree | 1d901b0a5aa94e0a8e45f242b6520f93bc8328d4 /Mailman/Cgi/confirm.py | |
| parent | 4fc1513debf661abab10b41ed76a90832bddc428 (diff) | |
| download | mailman-9bb06a8080632c0bedddf8182823da8b3b24363f.tar.gz mailman-9bb06a8080632c0bedddf8182823da8b3b24363f.tar.zst mailman-9bb06a8080632c0bedddf8182823da8b3b24363f.zip | |
Diffstat (limited to 'Mailman/Cgi/confirm.py')
| -rw-r--r-- | Mailman/Cgi/confirm.py | 439 |
1 files changed, 387 insertions, 52 deletions
diff --git a/Mailman/Cgi/confirm.py b/Mailman/Cgi/confirm.py index f2cb17661..33d143cad 100644 --- a/Mailman/Cgi/confirm.py +++ b/Mailman/Cgi/confirm.py @@ -17,12 +17,14 @@ """Confirm a pending action via URL.""" import signal +import cgi from Mailman import mm_cfg from Mailman import Errors from Mailman import i18n from Mailman import MailList from Mailman import Pending +from Mailman.UserDesc import UserDesc from Mailman.htmlformat import * from Mailman.Logging.Syslog import syslog @@ -37,7 +39,7 @@ def main(): doc.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE) parts = Utils.GetPathPieces() - if not parts: + if not parts or len(parts) < 1: bad_confirmation(doc) doc.AddItem(MailmanLogo()) print doc.Format() @@ -57,28 +59,199 @@ def main(): i18n.set_language(mlist.preferred_language) doc.set_language(mlist.preferred_language) - # See the comment in admin.py about the need for the signal handler. + # Get the form data to see if this is a second-step confirmation + cgidata = cgi.FieldStorage(keep_blank_values=1) + cookie = cgidata.getvalue('cookie') + if cookie == '': + ask_for_cookie(mlist, doc, _('Confirmation string was empty.')) + return + + if not cookie and len(parts) == 2: + cookie = parts[1] + + if len(parts) > 2: + bad_confirmation(doc) + doc.AddItem(mlist.GetMailmanFooter()) + print doc.Format() + return + + if not cookie: + ask_for_cookie(mlist, doc) + return + + days = int(mm_cfg.PENDING_REQUEST_LIFE / mm_cfg.days(1) + 0.5) + confirmurl = mlist.GetScriptURL('confirm', absolute=1) + badconfirmstr = _('''<b>Invalid confirmation string:</b> + %(cookie)s. + + <p>Note that confirmation strings expire approximately + %(days)s days after the initial subscription request. If your + confirmation has expired, please try to re-submit your subscription. + Otherwise, <a href="%(confirmurl)s">re-enter</a> your confirmation + string.''') + + content = Pending.confirm(cookie, expunge=0) + if content is None: + bad_confirmation(doc, badconfirmstr) + doc.AddItem(mlist.GetMailmanFooter()) + print doc.Format() + return + + try: + if content[0] == Pending.SUBSCRIPTION: + if cgidata.getvalue('cancel'): + subscription_cancel(mlist, doc, cookie) + elif cgidata.getvalue('submit'): + subscription_confirm(mlist, doc, cookie, cgidata) + else: + subscription_prompt(mlist, doc, cookie, *content[1:]) + elif content[0] == Pending.UNSUBSCRIPTION: + if cgidata.getvalue('cancel'): + unsubscription_cancel(mlist, doc, cookie) + elif cgidata.getvalue('submit'): + unsubscription_confirm(mlist, doc, cookie) + else: + unsubscription_prompt(mlist, doc, cookie, *content[1:]) + elif content[0] == Pending.CHANGE_OF_ADDRESS: + if cgidata.getvalue('cancel'): + addrchange_cancel(mlist, doc, cookie) + elif cgidata.getvalue('submit'): + addrchange_confirm(mlist, doc, cookie) + else: + addrchange_prompt(mlist, doc, cookie, *content[1:]) + else: + bad_confirmation(doc) + except Errors.MMBadConfirmation: + bad_confirmation(doc, badconfirmstr) + + doc.AddItem(mlist.GetMailmanFooter()) + print doc.Format() + + + +def bad_confirmation(doc, extra=''): + title = _('Bad confirmation string') + doc.SetTitle(title) + doc.AddItem(Header(3, Bold(FontAttr(title, color='#ff0000', size='+2')))) + doc.AddItem(extra) + + + +def ask_for_cookie(mlist, doc, extra=''): + title = _('Enter confirmation cookie') + doc.SetTitle(title) + form = Form(mlist.GetScriptURL('confirm', 1)) + table = Table(border=0, width='100%') + table.AddRow([Center(Bold(FontAttr(title, size='+1')))]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, + colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR) + + if extra: + table.AddRow([Bold(FontAttr(extra, size='+1'))]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + + # Add cookie entry box + table.AddRow([_("""Please enter the confirmation string + (i.e. <em>cookie</em>) that you received in your email message, in the box + below. Then hit the <em>Submit</em> button to proceed to the next + confirmation step.""")]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + table.AddRow([Label(_('Confirmation string:')), + TextBox('cookie')]) + table.AddRow([Center(SubmitButton('submit_cookie', _('Submit')))]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + form.AddItem(table) + doc.AddItem(form) + doc.AddItem(mlist.GetMailmanFooter()) + print doc.Format() + + + +def subscription_prompt(mlist, doc, cookie, + email, name, password, digest, lang): + title = _('Confirm subscription request') + doc.SetTitle(title) + form = Form(mlist.GetScriptURL('confirm', 1)) + table = Table(border=0, width='100%') + table.AddRow([Center(Bold(FontAttr(title, size='+1')))]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, + colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR) + + listname = mlist.real_name + table.AddRow([_("""Your confirmation is required in order to complete the + subscription request to the mailing list <em>%(listname)s</em>. Your + subscription settings are shown below; make any necessary changes and hit + <em>Subscribe</em> to complete the confirmation process. Once you've + confirmed your subscription request, you will be shown your account + options page which you can use to further customize your membership + options. + + <p>Or hit <em>Cancel and discard</em> to cancel this subscription + request.""") + '<p><hr>']) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + + table.AddRow([Label(_('Your email address:')), email]) + table.AddRow([Label(_('Your real name:')), + TextBox('realname', name)]) + table.AddRow([Label(_('Password:')), + PasswordBox('password', password)]) + table.AddRow([Label(_('Password (confirm):')), + PasswordBox('pwconfirm', password)]) + table.AddRow([Label(_('Receive digests?')), + RadioButtonArray('digests', (_('No'), _('Yes')), + checked=digest, values=(0, 1))]) + langs = mlist.GetAvailableLanguages() + values = [mm_cfg.LC_DESCRIPTIONS[l][0] for l in langs] + try: + selected = langs.index(lang) + except ValueError: + selected = lang.index(mlist.preferred_language) + table.AddRow([Label(_('Preferred language:')), + SelectOptions('language', langs, values, selected)]) + table.AddRow([Hidden('cookie', cookie)]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + table.AddRow([SubmitButton('submit', _('Subscribe')), + SubmitButton('cancel', _('Cancel and discard'))]) + + form.AddItem(table) + doc.AddItem(form) + + + +def subscription_cancel(mlist, doc, cookie): + # Discard this cookie + Pending.confirm(cookie, expunge=1) + doc.AddItem(_('You have canceled your subscription request.')) + + + +def subscription_confirm(mlist, doc, cookie, cgidata, badconfirmstr): + # See the comment in admin.py about the need for the signal + # handler. def sigterm_handler(signum, frame, mlist=mlist): mlist.Unlock() + sys.exit(0) - # Now dig out the cookie mlist.Lock() try: - signal.signal(signal.SIGTERM, sigterm_handler) try: - cookie = parts[1] - data = mlist.ProcessConfirmation(cookie) - success(mlist, doc, *data) - except (Errors.MMBadConfirmation, IndexError): - days = int(mm_cfg.PENDING_REQUEST_LIFE / mm_cfg.days(1) + 0.5) - bad_confirmation(doc, _('''Invalid confirmation string. Note that - confirmation strings expire approximately %(days)s days after the - initial subscription request. If your confirmation has expired, - please try to re-submit your subscription.''')) - except Errors.MMNoSuchUserError: - bad_confirmation(doc, _('''Invalid confirmation string. It is - possible that you are attempting to confirm a request for an - address that has already been unsubscribed.''')) + # Some pending values may be overridden in the form. email of + # course is hardcoded. ;) + cgipasswd = cgidata.getvalue('password') + cgiconfirm = cgidata.getvalue('pwconfirm') + if cgipasswd <> cgiconfirm: + setformpasswd = 0 + pw = None + else: + setformpasswd = 1 + pw = cgipasswd + lang = cgidata.getvalue('language') + userdesc = UserDesc(fullname=cgidata.getvalue('realname', None), + password=pw, + digest=cgidata.getvalue('digests', None), + lang=lang) + op, addr, pw, digest, lang = mlist.ProcessConfirmation( + cookie, userdesc) except Errors.MMNeedApproval: title = _('Awaiting moderator approval') doc.SetTitle(title) @@ -89,49 +262,211 @@ def main(): the list moderator before you will be subscribed. Your request has been forwarded to the list moderator, and you will be notified of the moderator's decision.""")) - doc.AddItem(mlist.GetMailmanFooter()) - print doc.Format() + except Errors.MMNoSuchUserError: + bad_confirmation(doc, _('''Invalid confirmation string. It is + possible that you are attempting to confirm a request for an + address that has already been unsubscribed.''')) + else: + # Use the user's preferred language + i18n.set_language(lang) + doc.set_language(lang) + # The response + listname = mlist.real_name + title = _('Subscription request confirmed') + optionsurl = mlist.GetOptionsURL(addr, absolute=1) + doc.SetTitle(title) + doc.AddItem(Header(3, Bold(FontAttr(title, size='+2')))) + if not setformpasswd: + doc.AddItem(_("""\ + The passwords you entered in the confirmation screen did not + match, so your original subscription password will be used + instead. Your password will have been generated by Mailman if + you left the password fields blank. In any event, your + membership password will be sent to you in a separate + acknowledgement email.<p>""")) + doc.AddItem(_('''\ + You have successfully confirmed your subscription request for + "%(addr)s" to the %(listname)s mailing list. A separate + confirmation message will be sent to your email address, along + with your password, and other useful information and links. + + <p>You can now + <a href="%(optionsurl)s">proceed to your membership login + page</a>.''')) mlist.Save() finally: mlist.Unlock() + + + +def unsubscription_cancel(mlist, doc, cookie): + # Discard this cookie + Pending.confirm(cookie, expunge=1) + doc.AddItem(_('You have canceled your unsubscription request.')) -def bad_confirmation(doc, extra=''): - title = _('Bad confirmation string') - doc.SetTitle(title) - doc.AddItem(Header(3, Bold(FontAttr(title, color='#ff0000', size='+2')))) - doc.AddItem(extra) +def unsubscription_confirm(mlist, doc, cookie): + # See the comment in admin.py about the need for the signal + # handler. + def sigterm_handler(signum, frame, mlist=mlist): + mlist.Unlock() + sys.exit(0) + + mlist.Lock() + try: + try: + # Do this in two steps so we can get the preferred language for + # the user who is unsubscribing. + op, addr = Pending.confirm(cookie, expunge=0) + lang = mlist.getMemberLanguage(addr) + i18n.set_language(lang) + doc.set_language(lang) + op, addr = mlist.ProcessConfirmation(cookie) + except Errors.MMNoSuchUserError: + bad_confirmation(doc, _('''Invalid confirmation string. It is + possible that you are attempting to confirm a request for an + address that has already been unsubscribed.''')) + else: + # The response + listname = mlist.real_name + title = _('Unsubscription request confirmed') + listinfourl = mlist.GetScriptURL('listinfo', absolute=1) + doc.SetTitle(title) + doc.AddItem(Header(3, Bold(FontAttr(title, size='+2')))) + doc.AddItem(_("""\ + You have successfully unsubscribed from the %(listname)s mailing + list. You can now <a href="%(listinfourl)s">visit the list's main + information page</a>.""")) + mlist.Save() + finally: + mlist.Unlock() -def success(mlist, doc, op, addr, password=None, digest=None, lang=None): +def unsubscription_prompt(mlist, doc, cookie, addr): + title = _('Confirm unsubscription request') + doc.SetTitle(title) + form = Form(mlist.GetScriptURL('confirm', 1)) + table = Table(border=0, width='100%') + table.AddRow([Center(Bold(FontAttr(title, size='+1')))]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, + colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR) + listname = mlist.real_name - # Different title based on operation performed - if op == Pending.SUBSCRIPTION: - title = _('Subscription request confirmed') - elif op == Pending.UNSUBSCRIPTION: - title = _('Removal request confirmed') - lang = mlist.GetPreferredLanguage(addr) - elif op == Pending.CHANGE_OF_ADDRESS: - title = _('Change of address confirmed') - # Use the user's preferred language - i18n.set_language(lang) - doc.set_language(lang) - # Now set the title and report the results + fullname = mlist.getMemberName(addr) + if fullname is None: + fullname = _('<em>Not available</em>') + table.AddRow([_("""Your confirmation is required in order to complete the + unsubscription request from the mailing list <em>%(listname)s</em>. You + are currently subscribed with + + <ul><li><b>Real name:</b> %(fullname)s + <li><b>Email address:</b> %(addr)s + </ul> + + Hit the <em>Unsubscribe</em> button below to complete the confirmation + process. + + <p>Or hit <em>Cancel and discard</em> to cancel this unsubscription + request.""") + '<p><hr>']) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + table.AddRow([Hidden('cookie', cookie)]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + table.AddRow([SubmitButton('submit', _('Unsubscribe')), + SubmitButton('cancel', _('Cancel and discard'))]) + + form.AddItem(table) + doc.AddItem(form) + + + +def addrchange_cancel(mlist, doc, cookie): + # Discard this cookie + Pending.confirm(cookie, expunge=1) + doc.AddItem(_('You have canceled your change of address request.')) + + + +def addrchange_confirm(mlist, doc, cookie): + # See the comment in admin.py about the need for the signal + # handler. + def sigterm_handler(signum, frame, mlist=mlist): + mlist.Unlock() + sys.exit(0) + + mlist.Lock() + try: + try: + # Do this in two steps so we can get the preferred language for + # the user who is unsubscribing. + op, oldaddr, newaddr, globally = Pending.confirm(cookie, expunge=0) + lang = mlist.getMemberLanguage(oldaddr) + i18n.set_language(lang) + doc.set_language(lang) + op, oldaddr, newaddr = mlist.ProcessConfirmation(cookie) + except Errors.MMNoSuchUserError: + bad_confirmation(doc, _('''Invalid confirmation string. It is + possible that you are attempting to confirm a request for an + address that has already been unsubscribed.''')) + else: + # The response + listname = mlist.real_name + title = _('Change of address request confirmed') + optionsurl = mlist.GetOptionsURL(newaddr, absolute=1) + doc.SetTitle(title) + doc.AddItem(Header(3, Bold(FontAttr(title, size='+2')))) + doc.AddItem(_("""\ + You have successfully changed your address on the %(listname)s + mailing list from <b>%(oldaddr)s</b> to <b>%(newaddr)s</b>. You + can now <a href="%(optionsurl)s">proceed to your membership + login page</a>.""")) + mlist.Save() + finally: + mlist.Unlock() + + + +def addrchange_prompt(mlist, doc, cookie, oldaddr, newaddr, globally): + title = _('Confirm change of address request') doc.SetTitle(title) - doc.AddItem(Header(3, Bold(FontAttr(title, size='+2')))) - if op == Pending.SUBSCRIPTION: - doc.AddItem(_('''\ - You have successfully confirmed your subscription request for - "%(addr)s" to the %(listname)s mailing list. A separate confirmation - message will be sent to your email address, along with your password, - and other useful information and links.''')) - elif op == Pending.UNSUBSCRIPTION: - doc.AddItem(_('''\ - You have successfully confirmed your removal request for "%(addr)s" to - the %(listname)s mailing list.''')) - elif op == Pending.CHANGE_OF_ADDRESS: - doc.AddItem(_('''\ - You have successfully confirmed your change of address to "%(addr)s" - for the %(listname)s mailing list.''')) + form = Form(mlist.GetScriptURL('confirm', 1)) + table = Table(border=0, width='100%') + table.AddRow([Center(Bold(FontAttr(title, size='+1')))]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, + colspan=2, bgcolor=mm_cfg.WEB_HEADER_COLOR) + + listname = mlist.real_name + fullname = mlist.getMemberName(oldaddr) + if fullname is None: + fullname = _('<em>Not available</em>') + if globally: + globallys = _('globally') + else: + globallys = '' + table.AddRow([_("""Your confirmation is required in order to complete the + change of address request for the mailing list <em>%(listname)s</em>. You + are currently subscribed with + + <ul><li><b>Real name:</b> %(fullname)s + <li><b>Old email address:</b> %(oldaddr)s + </ul> + + and you have requested to %(globallys)s change your email address to + + <ul><li><b>New email address:</b> %(newaddr)s + </ul> + + Hit the <em>Change address</em> button below to complete the confirmation + process. + + <p>Or hit <em>Cancel and discard</em> to cancel this change of address + request.""") + '<p><hr>']) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + table.AddRow([Hidden('cookie', cookie)]) + table.AddCellInfo(table.GetCurrentRowIndex(), 0, colspan=2) + table.AddRow([SubmitButton('submit', _('Change address')), + SubmitButton('cancel', _('Cancel and discard'))]) + + form.AddItem(table) + doc.AddItem(form) |
