aboutsummaryrefslogtreecommitdiffstats
path: root/Mailman
diff options
context:
space:
mode:
Diffstat (limited to 'Mailman')
-rw-r--r--Mailman/Cgi/options.py3
-rw-r--r--Mailman/Commands/cmd_unsubscribe.py11
-rwxr-xr-xMailman/Defaults.py.in2
-rw-r--r--Mailman/MailList.py13
4 files changed, 21 insertions, 8 deletions
diff --git a/Mailman/Cgi/options.py b/Mailman/Cgi/options.py
index ee2293e2..1037f8f9 100644
--- a/Mailman/Cgi/options.py
+++ b/Mailman/Cgi/options.py
@@ -206,6 +206,7 @@ def main():
# Are we processing an unsubscription request from the login screen?
msgc = _('If you are a list member, a confirmation email has been sent.')
+ msgb = _('You already have a subscription pending confirmation')
msga = _("""If you are a list member, your unsubscription request has been
forwarded to the list administrator for approval.""")
if cgidata.has_key('login-unsub'):
@@ -228,6 +229,8 @@ def main():
mlist.ConfirmUnsubscription(user, userlang, remote=ip)
doc.addError(msgc, tag='')
mlist.Save()
+ except Errors.MMAlreadyPending:
+ doc.addError(msgb)
finally:
mlist.Unlock()
else:
diff --git a/Mailman/Commands/cmd_unsubscribe.py b/Mailman/Commands/cmd_unsubscribe.py
index 9ffa80cd..3a156536 100644
--- a/Mailman/Commands/cmd_unsubscribe.py
+++ b/Mailman/Commands/cmd_unsubscribe.py
@@ -73,9 +73,14 @@ approval."""))
# No password was given, so we need to do a mailback confirmation
# instead of unsubscribing them here.
cpaddr = mlist.getMemberCPAddress(address)
- mlist.ConfirmUnsubscription(cpaddr)
- # We don't also need to send a confirmation to this command
- res.respond = 0
+ try:
+ mlist.ConfirmUnsubscription(cpaddr)
+ except Errors.MMAlreadyPending:
+ res.results.append(
+ _('You already have a subscription pending confirmation'))
+ else:
+ # We don't also need to send a confirmation to this command
+ res.respond = 0
else:
# No admin approval is necessary, so we can just delete them if the
# passwords match.
diff --git a/Mailman/Defaults.py.in b/Mailman/Defaults.py.in
index 277e3ab0..e5d8b3cf 100755
--- a/Mailman/Defaults.py.in
+++ b/Mailman/Defaults.py.in
@@ -1128,7 +1128,7 @@ ANONYMOUS_LIST_KEEP_HEADERS = ['^(?!x-)', '^x-mailman-',
# pending a subscription confirmation when one is already pending. The down
# side to this is if a subscriber loses or doesn't receive the confirmation
# request email, she has to wait PENDING_REQUEST_LIFE (default 3 days) before
-# she can request another.
+# she can request another. This setting also applies to repeated unsubscribes.
REFUSE_SECOND_PENDING = No
diff --git a/Mailman/MailList.py b/Mailman/MailList.py
index 01a5a915..fdd47ae1 100644
--- a/Mailman/MailList.py
+++ b/Mailman/MailList.py
@@ -833,8 +833,8 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin,
#
# Membership management front-ends and assertion checks
#
- def CheckPending(self, email):
- """Check if there is already an unexpired pending subscription for
+ def CheckPending(self, email, unsub=False):
+ """Check if there is already an unexpired pending (un)subscription for
this email.
"""
if not mm_cfg.REFUSE_SECOND_PENDING:
@@ -846,8 +846,11 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin,
for k, v in pends.items():
if k in ('evictions', 'version'):
continue
- if (v[0] == Pending.SUBSCRIPTION and
- v[1].address.lower() == email.lower()):
+ op, data = v[:2]
+ if (op == Pending.SUBSCRIPTION and not unsub and
+ data.address.lower() == email.lower() or
+ op == Pending.UNSUBSCRIPTION and unsub and
+ data.lower() == email.lower()):
return True
return False
@@ -1476,6 +1479,8 @@ class MailList(HTMLFormatter, Deliverer, ListAdmin,
assert 0, 'Bad op: %s' % op
def ConfirmUnsubscription(self, addr, lang=None, remote=None):
+ if self.CheckPending(addr, unsub=True):
+ raise Errors.MMAlreadyPending, email
if lang is None:
lang = self.getMemberLanguage(addr)
cookie = self.pend_new(Pending.UNSUBSCRIPTION, addr)