# Copyright (C) 2001-2017 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, # USA. """MailList mixin class managing the privacy options.""" import os import re from Mailman import mm_cfg from Mailman import Utils from Mailman.i18n import _ from Mailman.Gui.GUIBase import GUIBase try: True, False except NameError: True = 1 False = 0 class Privacy(GUIBase): def GetConfigCategory(self): return 'privacy', _('Privacy options...') def GetConfigSubCategories(self, category): if category == 'privacy': return [('subscribing', _('Subscription rules')), ('sender', _('Sender filters')), ('recipient', _('Recipient filters')), ('spam', _('Spam filters')), ] return None def GetConfigInfo(self, mlist, category, subcat=None): if category <> 'privacy': return None # Pre-calculate some stuff. Technically, we shouldn't do the # sub_cfentry calculation here, but it's too ugly to indent it any # further, and besides, that'll mess up i18n catalogs. WIDTH = mm_cfg.TEXTFIELDWIDTH if mm_cfg.ALLOW_OPEN_SUBSCRIBE: sub_cfentry = ('subscribe_policy', mm_cfg.Radio, # choices (_('None'), _('Confirm'), _('Require approval'), _('Confirm and approve')), 0, _('What steps are required for subscription?
'), _("""None - no verification steps (Not Recommended )
Confirm (*) - email confirmation step required
Require approval - require list administrator Approval for subscriptions
Confirm and approve - both confirm and approve

(*) when someone requests a subscription, Mailman sends them a notice with a unique subscription request number that they must reply to in order to subscribe.
This prevents mischievous (or malicious) people from creating subscriptions for others without their consent.""")) else: sub_cfentry = ('subscribe_policy', mm_cfg.Radio, # choices (_('Confirm'), _('Require approval'), _('Confirm and approve')), 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

(*) when someone requests a subscription, Mailman sends them a notice with a unique subscription request number that they must reply to in order to subscribe.
This prevents mischievous (or malicious) people from creating subscriptions for others without their consent.""")) # some helpful values admin = mlist.GetScriptURL('admin') subscribing_rtn = [ _("""This section allows you to configure subscription and membership exposure policy. You can also control whether this list is public or not. See also the Archival Options section for separate archive-related privacy settings."""), _('Subscribing'), ('advertised', mm_cfg.Radio, (_('No'), _('Yes')), 0, _("""Advertise this list when people ask what lists are on this machine?""")), sub_cfentry, ('subscribe_auto_approval', mm_cfg.EmailListEx, (10, WIDTH), 1, _("""List of addresses (or regexps) whose subscriptions do not require approval."""), (_("""When subscription requires approval, addresses in this list are allowed to subscribe without administrator approval. Add addresses one per line. You may begin a line with a ^ character to designate a (case insensitive) regular expression match.""") + ' ' + _("""You may also use the @listname notation to designate the members of another list in this installation."""))), ('unsubscribe_policy', mm_cfg.Radio, (_('No'), _('Yes')), 0, _("""Is the list moderator's approval required for unsubscription requests? (No is recommended)"""), _("""When members want to leave a list, they will make an unsubscription request, either via the web or via email. Normally it is best for you to allow open unsubscriptions so that users can easily remove themselves from mailing lists (they get really upset if they can't get off lists!).

For some lists though, you may want to impose moderator approval before an unsubscription request is processed. Examples of such lists include a corporate mailing list that all employees are required to be members of.""")), _('Ban list'), ('ban_list', mm_cfg.EmailListEx, (10, WIDTH), 1, _("""List of addresses which are banned from membership in this mailing list."""), _("""Addresses in this list are banned outright from subscribing to this mailing list, with no further moderation required. Add addresses one per line; start the line with a ^ character to designate a regular expression match.""")), _("Membership exposure"), ('private_roster', mm_cfg.Radio, (_('Anyone'), _('List members'), _('List admin only')), 0, _('Who can view subscription list?'), _("""When set, the list of subscribers is protected by member or admin password authentication.""")), ('obscure_addresses', mm_cfg.Radio, (_('No'), _('Yes')), 0, _("""Show member addresses so they're not directly recognizable as email addresses?"""), _("""Setting this option causes member email addresses to be transformed when they are presented on list web pages (both in text and as links), so they're not trivially recognizable as email addresses. The intention is to prevent the addresses from being snarfed up by automated web scanners for use by spammers.""")), ] adminurl = mlist.GetScriptURL('admin', absolute=1) if mlist.dmarc_quarantine_moderation_action: quarantine = _('/Quarantine') else: quarantine = '' sender_rtn = [ _("""When a message is posted to the list, a series of moderation steps are taken to decide whether a moderator must first approve the message or not. This section contains the controls for moderation of both member and non-member postings.

Member postings are held for moderation if their moderation flag is turned on. You can control whether member postings are moderated by default or not.

Non-member postings can be automatically accepted, held for moderation, rejected (bounced), or discarded, either individually or as a group. Any posting from a non-member who is not explicitly accepted, rejected, or discarded, will have their posting filtered by the general non-member rules.

In the text boxes below, add one address per line; start the line with a ^ character to designate a Python regular expression. When entering backslashes, do so as if you were using Python raw strings (i.e. you generally just use a single backslash).

Note that non-regexp matches are always done first."""), _('Member filters'), ('default_member_moderation', mm_cfg.Radio, (_('No'), _('Yes')), 0, _('By default, should new list member postings be moderated?'), _("""Each list member has a moderation flag which says whether messages from the list member can be posted directly to the list, or must first be approved by the list moderator. When the moderation flag is turned on, list member postings must be approved first. You, the list administrator can decide whether a specific individual's postings will be moderated or not.

When a new member is subscribed, their initial moderation flag takes its value from this option. Turn this option off to accept member postings by default. Turn this option on to, by default, moderate member postings first. You can always manually set an individual member's moderation bit by using the membership management screens.""")), ('member_verbosity_threshold', mm_cfg.Number, 5, 0, _("""Ceiling on acceptable number of member posts, per interval, before automatic moderation."""), _("""If a member posts this many times, within a period of time the member is automatically moderated. Use 0 to disable. See member_verbosity_interval for details on the time period.

This is intended to stop people who join a list or lists and then use a bot to send many spam messages in a short interval.

Be careful when using this setting. If it is set too low, this can be triggered by a single post cross-posted to multiple lists or by a single post to an umbrella list.""")), ('member_verbosity_interval', mm_cfg.Number, 5, 0, _("""Number of seconds to remember posts to this list to determine member_verbosity_threshold for automatic moderation of a member."""), _("""If a member's total posts to all lists in this installation with member_verbosity_threshold enabled reaches this list's member_verbosity_threshold, the member is automatically moderated on this list.

Posts which are counted towards this list's member_verbosity_threshold are all posts to any list with member_verbosity_threshold enabled that arrived within that list's member_verbosity_interval.""")), ('member_moderation_action', mm_cfg.Radio, (_('Hold'), _('Reject'), _('Discard')), 0, _("""Action to take when a moderated member posts to the list."""), _("""

""")), ('member_moderation_notice', mm_cfg.Text, (10, WIDTH), 1, _("""Text to include in any rejection notice to be sent to moderated members who post to this list.""")), ('dmarc_moderation_action', mm_cfg.Radio, (_('Accept'), _('Munge From'), _('Wrap Message'), _('Reject'), _('Discard')), 0, _("""Action to take when anyone posts to the list from a domain with a DMARC Reject%(quarantine)s Policy."""), _("""

This setting takes precedence over the from_is_list setting if the message is From: an affected domain and the setting is other than Accept.""")), ('dmarc_quarantine_moderation_action', mm_cfg.Radio, (_('No'), _('Yes')), 0, _("""Shall the above dmarc_moderation_action apply to messages From: domains with DMARC p=quarantine as well as p=reject"""), _("""

If a message is From: a domain with DMARC p=quarantine and dmarc_moderation_action is not applied (this set to No) the message will likely not bounce, but will be delivered to recipients' spam folders or other hard to find places.""")), ('dmarc_none_moderation_action', mm_cfg.Radio, (_('No'), _('Yes')), 0, _("""Shall the above dmarc_moderation_action apply to messages From: domains with DMARC p=none as well as p=quarantine and p=reject"""), _("""