Yasuhito FUTATSUKI at POEM has proposed merging
lp:~futatuki/mailman/2.1-forbid-subscription into lp:mailman/2.1.
Commit message:
Add new value for MailList.subscribe_policy 4 as forbid
Requested reviews:
Mailman Coders (mailman-coders)
For more details, see:
https://code.launchpad.net/~futatuki/mailman/2.1-forbid-subscription/+merge/347305
This extends MailList.subscribe_policy with new value '4', forbid subscribe
request via E-mail and via Web UI (except list owners operation).
With MailList.subscribe_policy == 4,
* For Web UI
- reject all subscribe request (Mailman/Cgi/subscribe.py,
Mailman/HTMLFormatter.py)
- hide subscription form from listinfo page
(Mailman/Cgi/listinfo.py, new template
templates/en/listinfo_nosubscribe.html)
* For request via E-mail, reject all subscribe command
(Mailman/Command/cmd_subscribe.py)
* foolproof: MailList.AddMember() raise new exception
Errors.MembershipIsRejectedByPolicy()
(Mailman/Errors.py, Mailman/MailList.py)
To set new value to MailList.subscribe_policy,
* For Web UI, add new radio button and description (Mailman/Gui/Privacy.py)
For new template
* Add menu new item for new template file (Mailman/Cgi/edithtml.py)
For description
* Add description for new value (Mailman/Defauilts.py.in, misc/sitelist.cfg)
Please revise not only code logic but also identifiers, words, messages to be
suitable.
--
Your team Mailman Coders is requested to review the proposed merge of
lp:~futatuki/mailman/2.1-forbid-subscription into lp:mailman/2.1.
=== modified file 'Mailman/Cgi/edithtml.py'
--- Mailman/Cgi/edithtml.py 2017-06-06 05:47:05 +0000
+++ Mailman/Cgi/edithtml.py 2018-06-01 16:42:47 +0000
@@ -46,6 +46,8 @@
template_data = (
('listinfo.html', _('General list information page')),
+ ('listinfo_nosubscribe.html',
+ _('General list information page(no subscription form)')),
('subscribe.html', _('Subscribe results page')),
('options.html', _('User specific options page')),
('subscribeack.txt', _('Welcome email text file')),
=== modified file 'Mailman/Cgi/listinfo.py'
--- Mailman/Cgi/listinfo.py 2018-05-26 16:22:35 +0000
+++ Mailman/Cgi/listinfo.py 2018-06-01 16:42:47 +0000
@@ -180,51 +180,59 @@
replacements = mlist.GetStandardReplacements(lang)
- if not mlist.digestable or not mlist.nondigestable:
- replacements['<mm-digest-radio-button>'] = ""
- replacements['<mm-undigest-radio-button>'] = ""
- replacements['<mm-digest-question-start>'] = '<!-- '
- replacements['<mm-digest-question-end>'] = ' -->'
- else:
- replacements['<mm-digest-radio-button>'] = mlist.FormatDigestButton()
- replacements['<mm-undigest-radio-button>'] = \
- mlist.FormatUndigestButton()
- replacements['<mm-digest-question-start>'] = ''
- replacements['<mm-digest-question-end>'] = ''
- replacements['<mm-plain-digests-button>'] = \
- mlist.FormatPlainDigestsButton()
- replacements['<mm-mime-digests-button>'] = mlist.FormatMimeDigestsButton()
- replacements['<mm-subscribe-box>'] = mlist.FormatBox('email', size=30)
- replacements['<mm-subscribe-button>'] = mlist.FormatButton(
- 'email-button', text=_('Subscribe'))
- replacements['<mm-new-password-box>'] = mlist.FormatSecureBox('pw')
- replacements['<mm-confirm-password>'] = mlist.FormatSecureBox('pw-conf')
- replacements['<mm-subscribe-form-start>'] = mlist.FormatFormStart(
- 'subscribe')
- if mm_cfg.SUBSCRIBE_FORM_SECRET:
- now = str(int(time.time()))
- remote = os.environ.get('HTTP_FORWARDED_FOR',
- os.environ.get('HTTP_X_FORWARDED_FOR',
- os.environ.get('REMOTE_ADDR',
- 'w.x.y.z')))
- # Try to accept a range in case of load balancers, etc. (LP: #1447445)
- if remote.find('.') >= 0:
- # ipv4 - drop last octet
- remote = remote.rsplit('.', 1)[0]
+ if mlist.subscribe_policy != 4:
+ htmlbase = 'listinfo.html'
+ if not mlist.digestable or not mlist.nondigestable:
+ replacements['<mm-digest-radio-button>'] = ""
+ replacements['<mm-undigest-radio-button>'] = ""
+ replacements['<mm-digest-question-start>'] = '<!-- '
+ replacements['<mm-digest-question-end>'] = ' -->'
else:
- # ipv6 - drop last 16 (could end with :: in which case we just
- # drop one : resulting in an invalid format, but it's only
- # for our hash so it doesn't matter.
- remote = remote.rsplit(':', 1)[0]
- replacements['<mm-subscribe-form-start>'] += (
+ replacements['<mm-digest-radio-button>'] = \
+ mlist.FormatDigestButton()
+ replacements['<mm-undigest-radio-button>'] = \
+ mlist.FormatUndigestButton()
+ replacements['<mm-digest-question-start>'] = ''
+ replacements['<mm-digest-question-end>'] = ''
+ replacements['<mm-plain-digests-button>'] = \
+ mlist.FormatPlainDigestsButton()
+ replacements['<mm-mime-digests-button>'] = \
+ mlist.FormatMimeDigestsButton()
+ replacements['<mm-subscribe-box>'] = mlist.FormatBox('email', size=30)
+ replacements['<mm-subscribe-button>'] = mlist.FormatButton(
+ 'email-button', text=_('Subscribe'))
+ replacements['<mm-new-password-box>'] = mlist.FormatSecureBox('pw')
+ replacements['<mm-confirm-password>'] = \
+ mlist.FormatSecureBox('pw-conf')
+ replacements['<mm-subscribe-form-start>'] = mlist.FormatFormStart(
+ 'subscribe')
+ if mm_cfg.SUBSCRIBE_FORM_SECRET:
+ now = str(int(time.time()))
+ remote = os.environ.get('HTTP_FORWARDED_FOR',
+ os.environ.get('HTTP_X_FORWARDED_FOR',
+ os.environ.get('REMOTE_ADDR',
+ 'w.x.y.z')))
+ # Try to accept a range in case of load balancers, etc.
+ # (LP: #1447445)
+ if remote.find('.') >= 0:
+ # ipv4 - drop last octet
+ remote = remote.rsplit('.', 1)[0]
+ else:
+ # ipv6 - drop last 16 (could end with :: in which case we just
+ # drop one : resulting in an invalid format, but it's
+ # only for our hash so it doesn't matter.
+ remote = remote.rsplit(':', 1)[0]
+ replacements['<mm-subscribe-form-start>'] += (
'<input type="hidden" name="sub_form_token" value="%s:%s">\n'
% (now, Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET +
- now +
- mlist.internal_name() +
- remote
- ).hexdigest()
+ now +
+ mlist.internal_name() +
+ remote
+ ).hexdigest()
)
)
+ else:
+ htmlbase = 'listinfo_nosubscribe.html'
# Roster form substitutions
replacements['<mm-roster-form-start>'] = mlist.FormatFormStart('roster')
replacements['<mm-roster-option>'] = mlist.FormatRosterOptionForUser(lang)
@@ -258,7 +266,7 @@
replacements['<mm-recaptcha-ui>'] = ''
# Do the expansion.
- doc.AddItem(mlist.ParseTags('listinfo.html', replacements, lang))
+ doc.AddItem(mlist.ParseTags(htmlbase, replacements, lang))
print doc.Format()
=== modified file 'Mailman/Cgi/subscribe.py'
--- Mailman/Cgi/subscribe.py 2018-04-11 09:36:40 +0000
+++ Mailman/Cgi/subscribe.py 2018-06-01 16:42:47 +0000
@@ -118,6 +118,12 @@
def process_form(mlist, doc, cgidata, lang):
+ # short cut
+ if mlist.subscribe_policy == 4:
+ results = _(""" Your subscription is not allowed because the list
+ don't accept any new subscriptions by policy.""")
+ print_results(mlist, results, doc, lang)
+ return
listowner = mlist.GetOwnerEmail()
realname = mlist.real_name
results = []
@@ -253,6 +259,10 @@
results = _("""The email address you supplied is banned from this
mailing list. If you think this restriction is erroneous, please
contact the list owners at %(listowner)s.""")
+ # foolproof
+ except Errors.MembershipIsRejectedByPolicy:
+ results = _(""" Your subscription is not allowed because the list
+ don't accept any new subscriptions by policy.""")
except Errors.MMBadEmailError:
results = _("""\
The email address you supplied is not valid. (E.g. it must contain an
=== modified file 'Mailman/Commands/cmd_subscribe.py'
--- Mailman/Commands/cmd_subscribe.py 2008-04-27 00:59:18 +0000
+++ Mailman/Commands/cmd_subscribe.py 2018-06-01 16:42:47 +0000
@@ -46,6 +46,10 @@
def process(res, args):
mlist = res.mlist
+ # short cut
+ if mlist.subscribe_policy == 4:
+ res.results.append(_('New subscription is forbided by policy'))
+ return STOP
digest = None
password = None
address = None
@@ -115,6 +119,11 @@
If you think this restriction is erroneous, please contact the list
owners at %(listowner)s."""))
return STOP
+ # foolproof
+ except Errors.MembershipIsRejectedByPolicy:
+ results = _(""" Your subscription is not allowed because the list
+ don't accept any new subscriptions by policy.""")
+ return STOP
except Errors.MMBadEmailError:
res.results.append(_("""\
Mailman won't accept the given email address as a valid address.
=== modified file 'Mailman/Defaults.py.in'
--- Mailman/Defaults.py.in 2018-01-30 04:06:24 +0000
+++ Mailman/Defaults.py.in 2018-06-01 16:42:47 +0000
@@ -1310,6 +1310,7 @@
# 1 - confirmation required for subscribes
# 2 - admin approval required for subscribes
# 3 - both confirmation and admin approval required
+# 4 - forbid new subscription
#
# ** please do not choose option 0 if you are not allowing open
# subscribes (next variable)
=== modified file 'Mailman/Errors.py'
--- Mailman/Errors.py 2009-01-20 20:22:08 +0000
+++ Mailman/Errors.py 2018-06-01 16:42:47 +0000
@@ -40,6 +40,7 @@
class CantDigestError(MemberError): pass
class MustDigestError(MemberError): pass
class MembershipIsBanned(MemberError): pass
+class MembershipIsRejectedByPolicy(MemberError): pass
# Exception hierarchy for various authentication failures, can be
# raised from functions in SecurityManager.py
=== modified file 'Mailman/Gui/Privacy.py'
--- Mailman/Gui/Privacy.py 2017-06-06 05:47:05 +0000
+++ Mailman/Gui/Privacy.py 2018-06-01 16:42:47 +0000
@@ -59,7 +59,8 @@
(_('None'),
_('Confirm'),
_('Require approval'),
- _('Confirm and approve')),
+ _('Confirm and approve'),
+ _('Forbid')),
0,
_('What steps are required for subscription?<br>'),
_("""None - no verification steps (<em>Not
@@ -67,7 +68,8 @@
Confirm (*) - email confirmation step required <br>
Require approval - require list administrator
Approval for subscriptions <br>
- Confirm and approve - both confirm and approve
+ Confirm and approve - both confirm and approve <br>
+ Forbid - reject all new subscription request
<p>(*) when someone requests a subscription,
Mailman sends them a notice with a unique
@@ -82,13 +84,15 @@
# choices
(_('Confirm'),
_('Require approval'),
- _('Confirm and approve')),
+ _('Confirm and approve'),
+ _('Forbid')),
1,
_('What steps are required for subscription?<br>'),
_("""Confirm (*) - email confirmation required <br>
Require approval - require list administrator
approval for subscriptions <br>
- Confirm and approve - both confirm and approve
+ Confirm and approve - both confirm and approve <br>
+ Forbid - reject all new subscription request
<p>(*) when someone requests a subscription,
Mailman sends them a notice with a unique
=== modified file 'Mailman/HTMLFormatter.py'
--- Mailman/HTMLFormatter.py 2017-07-31 00:37:30 +0000
+++ Mailman/HTMLFormatter.py 2018-06-01 16:42:47 +0000
@@ -202,6 +202,10 @@
by the list moderator. You will be notified of the moderator's
decision by email.""")
also = _("also ")
+ elif self.subscribe_policy == 4:
+ msg += _("""This is a closed list which don't accept any new
+ subscription request.""")
+ also = _("also ")
if msg:
msg += ' '
if self.private_roster == 1:
=== modified file 'Mailman/MailList.py'
--- Mailman/MailList.py 2018-04-11 09:36:40 +0000
+++ Mailman/MailList.py 2018-06-01 16:42:47 +0000
@@ -898,6 +898,15 @@
# Trying to subscribe the list to itself!
raise Errors.MMBadEmailError
realname = self.real_name
+ # Is the list allow new subscription?
+ if self.subscribe_policy == 4:
+ if remote:
+ whence = ' from %s' % remote
+ else:
+ whence = ''
+ syslog('vette', '%s reject subscription: %s%s (by policy)',
+ realname, email, whence)
+ raise Errors.MembershipIsRejectedByPolicy
# Is the subscribing address banned from this list?
pattern = self.GetBannedPattern(email)
if pattern:
=== modified file 'misc/sitelist.cfg'
--- misc/sitelist.cfg 2009-01-11 16:06:13 +0000
+++ misc/sitelist.cfg 2018-06-01 16:42:47 +0000
@@ -178,6 +178,7 @@
# 1 = "Confirm"
# 2 = "Require approval"
# 3 = "Confirm and approve"
+# 4 = "Forbid"
subscribe_policy = 2
# When members want to leave a list, they will make an unsubscription
=== added file 'templates/en/listinfo_nosubscribe.html'
--- templates/en/listinfo_nosubscribe.html 1970-01-01 00:00:00 +0000
+++ templates/en/listinfo_nosubscribe.html 2018-06-01 16:42:47 +0000
@@ -0,0 +1,76 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- $Revision: 5865 $ -->
+<HTML>
+ <HEAD>
+ <TITLE><MM-List-Name> Info Page</TITLE>
+
+ </HEAD>
+ <BODY BGCOLOR="#ffffff">
+
+ <P>
+ <TABLE BORDER="0" CELLSPACING="4" CELLPADDING="5">
+ <TR>
+ <TD COLSPAN="2" WIDTH="100%" BGCOLOR="#99CCFF" ALIGN="CENTER">
+ <B><FONT COLOR="#000000" SIZE="+1"><MM-List-Name> --
+ <MM-List-Description></FONT></B>
+ </TD>
+ </TR>
+ <tr>
+ <td colspan="2">
+ <p>
+ </td>
+ </tr>
+ <tr>
+ <TD COLSPAN="1" WIDTH="100%" BGCOLOR="#FFF0D0">
+ <B><FONT COLOR="#000000">About <MM-List-Name></FONT></B>
+ </TD>
+ <TD COLSPAN="1" WIDTH="100%" BGCOLOR="#FFF0D0">
+ <MM-lang-form-start><MM-displang-box> <MM-list-langs>
+ <MM-form-end>
+ </TD>
+ </TR>
+ <tr>
+ <td colspan="2">
+ <P><MM-List-Info></P>
+ <p> To see the collection of prior postings to the list,
+ visit the <MM-Archive><MM-List-Name>
+ Archives</MM-Archive>.
+ <MM-Restricted-List-Message>
+ </p>
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN="2" WIDTH="100%" BGCOLOR="#FFF0D0">
+ <B><FONT COLOR="#000000">Using <MM-List-Name></FONT></B>
+ </TD>
+ </TR>
+ <tr>
+ <td colspan="2">
+ To post a message to all the list members, send email to
+ <A HREF="mailto:<MM-Posting-Addr>"><MM-Posting-Addr></A>.
+
+ <p>You can change your existing
+ subscription, in the sections below.
+ </td>
+ </tr>
+ <TR>
+ <TD COLSPAN="2" WIDTH="100%" BGCOLOR="#FFF0D0">
+ <a name="subscribers">
+ <B><FONT COLOR="#000000"><MM-List-Name> Subscribers</FONT></B></a>
+ </TD>
+ </TR>
+ <tr>
+ <TD COLSPAN="2" WIDTH="100%">
+ <MM-Roster-Form-Start>
+ <MM-Roster-Option>
+ <MM-Form-End>
+ <p>
+ <MM-Options-Form-Start>
+ <MM-Editing-Options>
+ <MM-Form-End>
+ </td>
+ </tr>
+ </table>
+<MM-Mailman-Footer>
+</BODY>
+</HTML>
=== added file 'templates/ja/listinfo_nosubscribe.html'
--- templates/ja/listinfo_nosubscribe.html 1970-01-01 00:00:00 +0000
+++ templates/ja/listinfo_nosubscribe.html 2018-06-01 16:42:47 +0000
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- $Revision: 6837 $ -->
+<HTML>
+ <HEAD>
+ <TITLE><MM-List-Name> ����ڡ���</TITLE>
+
+ </HEAD>
+ <BODY BGCOLOR="#ffffff">
+
+ <P>
+ <TABLE BORDER="0" CELLSPACING="4" CELLPADDING="5">
+ <TR>
+ <TD COLSPAN="2" WIDTH="100%" BGCOLOR="#99CCFF" ALIGN="CENTER">
+ <B><FONT COLOR="#000000" SIZE="+1"><MM-List-Name> --
+ <MM-List-Description></FONT></B>
+ </TD>
+ </TR>
+ <tr>
+ <td colspan="2">
+ <p>
+ </td>
+ </tr>
+ <tr>
+ <TD COLSPAN="1" WIDTH="70%" BGCOLOR="#FFF0D0">
+ <B><FONT COLOR="#000000"><MM-List-Name>�ˤĤ���</FONT></B>
+ </TD>
+ <TD COLSPAN="1" WIDTH="30%" BGCOLOR="#FFF0D0">
+ <MM-lang-form-start> <MM-displang-box> <MM-list-langs>
+ <MM-form-end>
+ </TD>
+
+ </TR>
+ <tr>
+ <td colspan="2">
+ <P><MM-List-Info></P>
+ <p> ���Υ��ꥹ�Ȥ���Ƥ��줿���Υ���,
+ <MM-Archive><MM-List-Name>
+ ��¸���</MM-Archive>����������.
+ <MM-Restricted-List-Message>
+ </p>
+ </TD>
+ </TR>
+ <TR>
+ <TD COLSPAN="2" WIDTH="100%" BGCOLOR="#FFF0D0">
+ <B><FONT COLOR="#000000"><MM-List-Name> ������ˡ</FONT></B>
+ </TD>
+ </TR>
+ <tr>
+ <td colspan="2">
+ ���ꥹ�Ȥ���������������,
+ <A HREF="mailto:<MM-Posting-Addr>"><MM-Posting-Addr></A>
+ �Υ��ɥ쥹�����������Ƥ�������.
+
+ <p>���ꥹ�Ȥθ��ߤβ�����ץ������ѹ���,
+ �ʲ��Υե���������Ѥ�������.
+ </td>
+ </tr>
+ <TR>
+ <TD COLSPAN="2" WIDTH="100%" BGCOLOR="#FFF0D0">
+ <a name="subscribers">
+ <B><FONT COLOR="#000000"><MM-List-Name> ���������</FONT></B></a>
+ </TD>
+ </TR>
+ <tr>
+ <TD COLSPAN="2" WIDTH="100%">
+ <MM-Roster-Form-Start>
+ <MM-Roster-Option>
+ <MM-Form-End>
+ <p>
+ <MM-Options-Form-Start>
+ <MM-Editing-Options>
+ <MM-Form-End>
+ </td>
+ </tr>
+ </table>
+<MM-Mailman-Footer>
+</BODY>
+</HTML>
_______________________________________________
Mailman-coders mailing list
[email protected]
https://mail.python.org/mailman/listinfo/mailman-coders