=== modified file 'Mailman/Cgi/edithtml.py' --- Mailman/Cgi/edithtml.py 2018-07-11 06:52:22 +0000 +++ Mailman/Cgi/edithtml.py 2020-09-01 00:48:41 +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 2019-06-19 23:56:49 +0000 +++ Mailman/Cgi/listinfo.py 2020-09-01 03:39:22 +0000 @@ -180,69 +180,77 @@ replacements = mlist.GetStandardReplacements(lang) - if not mlist.digestable or not mlist.nondigestable: - replacements[''] = "" - replacements[''] = "" - replacements[''] = '' - else: - replacements[''] = mlist.FormatDigestButton() - replacements[''] = \ - mlist.FormatUndigestButton() - replacements[''] = '' - replacements[''] = '' - replacements[''] = \ - mlist.FormatPlainDigestsButton() - replacements[''] = mlist.FormatMimeDigestsButton() - replacements[''] = mlist.FormatBox('email', size=30) - replacements[''] = mlist.FormatButton( - 'email-button', text=_('Subscribe')) - replacements[''] = mlist.FormatSecureBox('pw') - replacements[''] = mlist.FormatSecureBox('pw-conf') - replacements[''] = 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[''] = "" + replacements[''] = "" + replacements[''] = '' 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] - # render CAPTCHA, if configured - if isinstance(mm_cfg.CAPTCHAS, dict) and 'en' in mm_cfg.CAPTCHAS: - (captcha_question, captcha_box, captcha_idx) = \ - Utils.captcha_display(mlist, lang, mm_cfg.CAPTCHAS) - pre_question = _( + replacements[''] = \ + mlist.FormatDigestButton() + replacements[''] = \ + mlist.FormatUndigestButton() + replacements[''] = '' + replacements[''] = '' + replacements[''] = \ + mlist.FormatPlainDigestsButton() + replacements[''] = \ + mlist.FormatMimeDigestsButton() + replacements[''] = mlist.FormatBox('email', size=30) + replacements[''] = mlist.FormatButton( + 'email-button', text=_('Subscribe')) + replacements[''] = mlist.FormatSecureBox('pw') + replacements[''] = \ + mlist.FormatSecureBox('pw-conf') + replacements[''] = 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] + # render CAPTCHA, if configured + if isinstance(mm_cfg.CAPTCHAS, dict) and 'en' in mm_cfg.CAPTCHAS: + (captcha_question, captcha_box, captcha_idx) = \ + Utils.captcha_display(mlist, lang, mm_cfg.CAPTCHAS) + pre_question = _( """Please answer the following question to prove that you are not a bot:""" - ) - replacements[''] = ( - """%s
%s%s""" - % (pre_question, captcha_question, captcha_box)) - else: - # just to have something to include in the hash below - captcha_idx = '' - # fill form - replacements[''] += ( + ) + replacements[''] = ( + '%s
%s%s' + % (pre_question, captcha_question, captcha_box)) + else: + # just to have something to include in the hash below + captcha_idx = '' + # fill form + replacements[''] += ( '\n' % (now, captcha_idx, - Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET + ":" + - now + ":" + - captcha_idx + ":" + - mlist.internal_name() + ":" + - remote - ).hexdigest() + Utils.sha_new(mm_cfg.SUBSCRIBE_FORM_SECRET + ":" + + now + ":" + + captcha_idx + ":" + + mlist.internal_name() + ":" + + remote + ).hexdigest() ) ) + else: + htmlbase = 'listinfo_nosubscribe.html' # Roster form substitutions replacements[''] = mlist.FormatFormStart('roster') replacements[''] = mlist.FormatRosterOptionForUser(lang) @@ -276,7 +284,7 @@ replacements[''] = '' # 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 2020-06-10 22:04:26 +0000 +++ Mailman/Cgi/subscribe.py 2020-09-01 00:48:41 +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 = [] @@ -262,6 +268,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 2020-01-10 01:00:40 +0000 +++ Mailman/Commands/cmd_subscribe.py 2020-09-01 00:48:41 +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 forbidden 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 2020-06-10 22:04:26 +0000 +++ Mailman/Defaults.py.in 2020-09-01 00:48:41 +0000 @@ -1363,6 +1363,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 2020-01-10 01:00:40 +0000 +++ Mailman/Errors.py 2020-09-01 00:48:41 +0000 @@ -41,6 +41,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 2018-12-15 18:07:41 +0000 +++ Mailman/Gui/Privacy.py 2020-09-01 00:48:41 +0000 @@ -59,7 +59,8 @@ (_('None'), _('Confirm'), _('Require approval'), - _('Confirm and approve')), + _('Confirm and approve'), + _('Forbid')), 0, _('What steps are required for subscription?
'), _("""None - no verification steps (Not @@ -67,7 +68,8 @@ Confirm (*) - email confirmation step required
Require approval - require list administrator Approval for subscriptions
- Confirm and approve - both confirm and approve + Confirm and approve - both confirm and approve
+ Forbid - reject all new subscription request

(*) 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?
'), _("""Confirm (*) - email confirmation required
Require approval - require list administrator approval for subscriptions
- Confirm and approve - both confirm and approve + Confirm and approve - both confirm and approve
+ Forbid - reject all new subscription request

(*) when someone requests a subscription, Mailman sends them a notice with a unique === modified file 'Mailman/HTMLFormatter.py' --- Mailman/HTMLFormatter.py 2018-06-22 00:34:52 +0000 +++ Mailman/HTMLFormatter.py 2020-09-01 00:48:41 +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 2020-05-18 17:01:51 +0000 +++ Mailman/MailList.py 2020-09-01 00:48:41 +0000 @@ -946,6 +946,15 @@ # Trying to subscribe the list to itself! raise Errors.MMBadEmailError realname = self.real_name + # Does 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: === added file 'README-forbid-subscription' --- README-forbid-subscription 1970-01-01 00:00:00 +0000 +++ README-forbid-subscription 2020-09-01 02:18:03 +0000 @@ -0,0 +1,53 @@ +This extends MailList.subscribe_policy with new value 4 ... 'forbid', +rejecting all subscribe request via E-mail and via Web UI(except by +list owners operation). + +With 'forbid' subscribe_policy, + + * it hide subscription form on list's listinfo page + (by using new template listinfo_nosubscribe.html). + * it reject all subscription request from users via Web UI and via email. + * following operations are still allowed, inspite of ban_lists rule to + prevent any email address to subscribe doesn't allow them. + - changing email address of users already subscribing both + by users themselves operations and by list owners. + - adding new member via operations by list owner or site owner. + +On the other hand, the things to be worse, + + * this breaks translations of some conpicious messages by modification. + * it also is needed to prepare new translated template for listinfo page + without subscription form, for all languages used by lists + (otherwise, fall back to English template if 'forbid' policy is choosed) + * new value for subscribe_policy 4 as 'forbid' may conflict with future + release of mailman 2.1 and already this value is incompatible with current + version. (to migrate list config data files from modified version + to upstream, make sure their subscribe_policy should be other than + 'forbid') + +[Technical detail] +This introduce a new value 4 as 'Forbid' to MailList.subscribe_policy. +Modification I made is below. + +* 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 by switching template file + to listinfo_nosubscribe.html + (Mailman/Cgi/listinfo.py, templates/en/listinfo_nosubscribe.html(new)) + + For request via E-mail, reject all subscribe command + (Mailman/Command/cmd_subscribe.py) + + Foolproof: MailList.AddMember() raise new exception + Errors.MembershipIsRejectedByPolicy() (if this happens, it is a bug...) + (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) + === modified file 'messages/ja/LC_MESSAGES/mailman.po' --- messages/ja/LC_MESSAGES/mailman.po 2020-06-27 00:12:17 +0000 +++ messages/ja/LC_MESSAGES/mailman.po 2020-09-01 03:55:23 +0000 @@ -3,14 +3,15 @@ # SATOH Fumiyasu , 2013 # Tokio Kikuchi , 2002-2011 # Yukihiro Yasuda , 2004 +# Yasuhito FUTATSUKI 2014-2020 # msgid "" msgstr "" -"Project-Id-Version: Mailman 2.1.30rc1\n" -"POT-Creation-Date: Fri Jun 26 17:05:40 2020\n" -"PO-Revision-Date: 2020-01-13 09:16+09:00\n" +"Project-Id-Version: Mailman 2.1.34(forbid subscription patch)\n" +"POT-Creation-Date: Tue Sep 1 12:09:38 2020\n" +"PO-Revision-Date: 2020-09-01 11:13+09:00\n" "Last-Translator: Yasuhito FUTATSUKI at POEM \n" -"Language-Team: Japanese \n" +"Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=EUC-JP\n" @@ -2251,7 +2252,11 @@ msgid "General list information page" msgstr "リスト総合案内ページ" -#: Mailman/Cgi/edithtml.py:49 +#: Mailman/Cgi/edithtml.py:50 +msgid "General list information page(no subscription form)" +msgstr "リスト総合案内ページ(入会用フォームなし)" + +#: Mailman/Cgi/edithtml.py:51 msgid "Subscribe results page" msgstr "入会の結果ページ" @@ -3010,7 +3015,16 @@ msgid "%(realname)s roster authentication failed." msgstr "%(realname)s 会員名簿 認証に失敗。" -#: Mailman/Cgi/subscribe.py:128 +#: Mailman/Cgi/subscribe.py:123 Mailman/Cgi/subscribe.py:273 +#: Mailman/Commands/cmd_subscribe.py:124 +msgid "" +" Your subscription is not allowed because the list\n" +" don't accept any new subscriptions by policy." +msgstr "" +"入会手続きの方針では新規入会は受け付けていませんので, \n" +"入会申請は受け付けられませんでした." + +#: Mailman/Cgi/subscribe.py:134 msgid "You must supply a valid email address." msgstr "有効なメールアドレスを入力してください。" @@ -3720,7 +3734,11 @@ " あれば、`address=<アドレス>' の形式で指定できます。\n" " (カッコや引用符は付けないこと!)\n" -#: Mailman/Commands/cmd_subscribe.py:62 +#: Mailman/Commands/cmd_subscribe.py:51 +msgid "New subscription is forbidden by policy" +msgstr "新規入会は方針により禁止されています" + +#: Mailman/Commands/cmd_subscribe.py:66 msgid "Bad digest specifier: %(arg)s" msgstr "「まとめ読み」の指示が違います: %(arg)s" @@ -6454,7 +6472,11 @@ msgid "Confirm and approve" msgstr "確認+承認" -#: Mailman/Gui/Privacy.py:64 Mailman/Gui/Privacy.py:87 +#: Mailman/Gui/Privacy.py:63 Mailman/Gui/Privacy.py:88 +msgid "Forbid" +msgstr "禁止" + +#: Mailman/Gui/Privacy.py:65 Mailman/Gui/Privacy.py:90 msgid "What steps are required for subscription?
" msgstr "入会にはどのような手順が必要ですか?
" @@ -6466,7 +6488,9 @@ "
\n" " Require approval - require list administrator\n" " Approval for subscriptions
\n" -" Confirm and approve - both confirm and approve\n" +" Confirm and approve - both confirm and approve " +"
\n" +" Forbid - reject all new subscription request\n" " \n" "

(*) when someone requests a subscription,\n" " Mailman sends them a notice with a unique\n" @@ -6478,10 +6502,11 @@ " from creating subscriptions for others without\n" " their consent." msgstr "" -"無し - 確認手順無し ( お勧めしません )
\n" -"確認 (*) - メールによる本人の確認が必要
\n" -"承認 - リスト管理者の承認が必要
\n" -"確認+承認 - 確認と承認の両方が必要\n" +"無し - 確認手順無し ( お勧めしません )
\n" +"確認 (*) - メールによる本人の確認が必要
\n" +"承認 - リスト管理者の承認が必要
\n" +"確認+承認 - 確認と承認の両方が必要
\n" +"禁止 - 申請を受け付けません\n" "\n" "

(*) 誰かが入会申請を出すとMailman は入会申請番号を付けて返信します。\n" " 申請者はその番号を使って返信しないと入会できません。
\n" @@ -6493,7 +6518,9 @@ "Confirm (*) - email confirmation required
\n" " Require approval - require list administrator\n" " approval for subscriptions
\n" -" Confirm and approve - both confirm and approve\n" +" Confirm and approve - both confirm and approve " +"
\n" +" Forbid - reject all new subscription request\n" " \n" "

(*) when someone requests a subscription,\n" " Mailman sends them a notice with a unique\n" @@ -6503,9 +6530,10 @@ " mischievous (or malicious) people from creating\n" " subscriptions for others without their consent." msgstr "" -"確認 (*) - メールによる本人の確認が必要
\n" -"承認 - リスト管理者の承認が必要
\n" -"確認+承認 - 確認と承認の両方が必要\n" +"確認 (*) - メールによる本人の確認が必要
\n" +"承認 - リスト管理者の承認が必要
\n" +"確認+承認 - 確認と承認の両方が必要
\n" +"禁止 - 申請を受け付けません\n" "\n" "

(*) 誰かが入会申請を出すと Mailman は入会申請番号を\n" " 付けて返信します。申請者はその番号を使って返信しないと\n" @@ -8023,7 +8052,13 @@ "会員による確認後、申請はリスト司会者の承認のため保留されます。\n" "司会者の決定はメールでお知らせします。" -#: Mailman/HTMLFormatter.py:208 +#: Mailman/HTMLFormatter.py:206 +msgid "" +"This is a closed list which don't accept any new\n" +" subscription request." +msgstr "このリストは新規入会申請を一切受け付けない閉鎖リストです。" + +#: Mailman/HTMLFormatter.py:212 msgid "" "This is %(also)sa private list, which means that the\n" " list of members is not available to non-members." === modified file 'misc/sitelist.cfg' --- misc/sitelist.cfg 2018-07-15 03:18:00 +0000 +++ misc/sitelist.cfg 2020-09-01 00:48:41 +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-05-31 06:05:16 +0000 @@ -0,0 +1,76 @@ + + + + + <MM-List-Name> Info Page + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ -- + +
+

  +

+ About + + + +
+

+

To see the collection of prior postings to the list, + visit the + Archives. + +

+
+ Using +
+ To post a message to all the list members, send email to + . + +

You can change your existing + subscription, in the sections below. +

+ + Subscribers +
+ + + +

+ + + +

+ + + === 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-05-31 16:19:12 +0000 @@ -0,0 +1,78 @@ + + + + + <MM-List-Name> 案内ページ + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ -- + +
+

  +

+ について + + + +
+

+

このメーリングリストに投稿された過去のメールは, + + 保存書庫をご覧下さい. + +

+
+ の利用法 +
+ メーリングリストの全会員に送るメールは, + + のアドレス宛に送信してください. + +

メーリングリストの現在の会員オプションの変更は, + 以下のフォームをご利用ください. +

+ + 会員の方へ +
+ + + +

+ + + +

+ + +