diff options
| author | Barry Warsaw | 2014-04-14 12:14:13 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2014-04-14 12:14:13 -0400 |
| commit | 403cbf23c07839b60c85c0bc791b6437f05c8a85 (patch) | |
| tree | b36d0ecab20e01f23bcf66ab2b27633aaf3e99c3 /src | |
| parent | ff6df86000da8fcb055101c5cede36b27cb0480a (diff) | |
| parent | 3a9725b91ef822122a70170333d71b58e1788a78 (diff) | |
| download | mailman-403cbf23c07839b60c85c0bc791b6437f05c8a85.tar.gz mailman-403cbf23c07839b60c85c0bc791b6437f05c8a85.tar.zst mailman-403cbf23c07839b60c85c0bc791b6437f05c8a85.zip | |
Diffstat (limited to 'src')
326 files changed, 1575 insertions, 482 deletions
diff --git a/src/mailman/__init__.py b/src/mailman/__init__.py index 87a2a2100..4b166476d 100644 --- a/src/mailman/__init__.py +++ b/src/mailman/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/bounces.py b/src/mailman/app/bounces.py index 0cc03d9c0..101d96f2a 100644 --- a/src/mailman/app/bounces.py +++ b/src/mailman/app/bounces.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -196,7 +196,7 @@ def send_probe(member, msg): member.mailing_list.list_id) text = make('probe.txt', mlist, member.preferred_language.code, listname=mlist.fqdn_listname, - address= member.address.email, + address=member.address.email, optionsurl=member.options_url, owneraddr=mlist.owner_address, ) diff --git a/src/mailman/app/commands.py b/src/mailman/app/commands.py index 7cde4e923..8dbca8d4b 100644 --- a/src/mailman/app/commands.py +++ b/src/mailman/app/commands.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/domain.py b/src/mailman/app/domain.py index c8fad4d33..ecaa3c230 100644 --- a/src/mailman/app/domain.py +++ b/src/mailman/app/domain.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/events.py b/src/mailman/app/events.py index a81ded655..3730d5aad 100644 --- a/src/mailman/app/events.py +++ b/src/mailman/app/events.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -27,7 +27,8 @@ __all__ = [ from zope import event -from mailman.app import domain, moderator, subscriptions +from mailman.app import ( + domain, membership, moderator, registrar, subscriptions) from mailman.core import i18n, switchboard from mailman.languages import manager as language_manager from mailman.styles import manager as style_manager @@ -39,11 +40,13 @@ def initialize(): """Initialize global event subscribers.""" event.subscribers.extend([ domain.handle_DomainDeletingEvent, + i18n.handle_ConfigurationUpdatedEvent, + language_manager.handle_ConfigurationUpdatedEvent, + membership.handle_SubscriptionEvent, moderator.handle_ListDeletingEvent, passwords.handle_ConfigurationUpdatedEvent, + registrar.handle_ConfirmationNeededEvent, + style_manager.handle_ConfigurationUpdatedEvent, subscriptions.handle_ListDeletingEvent, switchboard.handle_ConfigurationUpdatedEvent, - i18n.handle_ConfigurationUpdatedEvent, - style_manager.handle_ConfigurationUpdatedEvent, - language_manager.handle_ConfigurationUpdatedEvent, ]) diff --git a/src/mailman/app/inject.py b/src/mailman/app/inject.py index e9a532252..4c182657d 100644 --- a/src/mailman/app/inject.py +++ b/src/mailman/app/inject.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/lifecycle.py b/src/mailman/app/lifecycle.py index 66e21421e..676953ebe 100644 --- a/src/mailman/app/lifecycle.py +++ b/src/mailman/app/lifecycle.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -27,6 +27,7 @@ __all__ = [ import os +import errno import shutil import logging @@ -98,27 +99,13 @@ def create_list(fqdn_listname, owners=None, style_name=None): def remove_list(mlist): """Remove the list and all associated artifacts and subscriptions.""" fqdn_listname = mlist.fqdn_listname - removeables = [] # Delete the mailing list from the database. getUtility(IListManager).delete(mlist) # Do the MTA-specific list deletion tasks call_name(config.mta.incoming).delete(mlist) - # Remove the list directory. - removeables.append(os.path.join(config.LIST_DATA_DIR, fqdn_listname)) - # Remove any stale locks associated with the list. - for filename in os.listdir(config.LOCK_DIR): - fn_listname, dot, rest = filename.partition('.') - if fn_listname == fqdn_listname: - removeables.append(os.path.join(config.LOCK_DIR, filename)) - # Now that we know what files and directories to delete, delete them. - for target in removeables: - if not os.path.exists(target): - pass - elif os.path.islink(target): - os.unlink(target) - elif os.path.isdir(target): - shutil.rmtree(target) - elif os.path.isfile(target): - os.unlink(target) - else: - log.error('Could not delete list artifact: %s', target) + # Remove the list directory, if it exists. + try: + shutil.rmtree(os.path.join(config.LIST_DATA_DIR, fqdn_listname)) + except OSError as error: + if error.errno != errno.ENOENT: + raise diff --git a/src/mailman/app/membership.py b/src/mailman/app/membership.py index fc76b00fc..fdeb6e9c4 100644 --- a/src/mailman/app/membership.py +++ b/src/mailman/app/membership.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -17,26 +17,28 @@ """Application support for membership management.""" -from __future__ import absolute_import, unicode_literals +from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ 'add_member', 'delete_member', + 'handle_SubscriptionEvent', ] from email.utils import formataddr from zope.component import getUtility -from mailman.app.notifications import send_goodbye_message +from mailman.app.notifications import ( + send_goodbye_message, send_welcome_message) from mailman.config import config from mailman.core.i18n import _ from mailman.email.message import OwnerNotification from mailman.interfaces.address import IEmailValidator from mailman.interfaces.bans import IBanManager from mailman.interfaces.member import ( - MemberRole, MembershipIsBannedError, NotAMemberError) + MemberRole, MembershipIsBannedError, NotAMemberError, SubscriptionEvent) from mailman.interfaces.usermanager import IUserManager from mailman.utilities.i18n import make @@ -156,3 +158,19 @@ def delete_member(mlist, email, admin_notif=None, userack=None): msg = OwnerNotification(mlist, subject, text, roster=mlist.administrators) msg.send(mlist) + + + +def handle_SubscriptionEvent(event): + if not isinstance(event, SubscriptionEvent): + return + # Only send a notification message if the mailing list is configured to do + # so, and the member being added is a list member (as opposed to a + # moderator, non-member, or owner). + member = event.member + if member.role is not MemberRole.member: + return + mlist = member.mailing_list + if not mlist.send_welcome_message: + return + send_welcome_message(mlist, member, member.preferred_language) diff --git a/src/mailman/app/moderator.py b/src/mailman/app/moderator.py index 59fcb0976..046450305 100644 --- a/src/mailman/app/moderator.py +++ b/src/mailman/app/moderator.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -38,8 +38,7 @@ from email.utils import formataddr, formatdate, getaddresses, make_msgid from zope.component import getUtility from mailman.app.membership import add_member, delete_member -from mailman.app.notifications import ( - send_admin_subscription_notice, send_welcome_message) +from mailman.app.notifications import send_admin_subscription_notice from mailman.config import config from mailman.core.i18n import _ from mailman.email.message import UserNotification @@ -259,8 +258,6 @@ def handle_subscription(mlist, id, action, comment=None): # request was made and accepted. pass else: - if mlist.send_welcome_message: - send_welcome_message(mlist, address, language, delivery_mode) if mlist.admin_notify_mchanges: send_admin_subscription_notice( mlist, address, display_name, language) diff --git a/src/mailman/app/notifications.py b/src/mailman/app/notifications.py index 8cbdce450..1fa1fe01e 100644 --- a/src/mailman/app/notifications.py +++ b/src/mailman/app/notifications.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -65,44 +65,36 @@ def _get_message(uri_template, mlist, language): -def send_welcome_message(mlist, address, language, delivery_mode, text=''): +def send_welcome_message(mlist, member, language, text=''): """Send a welcome message to a subscriber. Prepending to the standard welcome message template is the mailing list's welcome message, if there is one. - :param mlist: the mailing list + :param mlist: The mailing list. :type mlist: IMailingList - :param address: The address to respond to - :type address: string - :param language: the language of the response + :param member: The member to send the welcome message to. + :param address: IMember + :param language: The language of the response. :type language: ILanguage - :param delivery_mode: the type of delivery the subscriber is getting - :type delivery_mode: DeliveryMode """ - welcome_message = _get_message(mlist.welcome_message_uri, - mlist, language) - # Find the IMember object which is subscribed to the mailing list, because - # from there, we can get the member's options url. - member = mlist.members.get_member(address) - user_name = member.user.display_name + welcome_message = _get_message(mlist.welcome_message_uri, mlist, language) options_url = member.options_url # Get the text from the template. + display_name = ('' if member.user is None else member.user.display_name) text = expand(welcome_message, dict( fqdn_listname=mlist.fqdn_listname, list_name=mlist.display_name, listinfo_uri=mlist.script_url('listinfo'), list_requests=mlist.request_address, - user_name=user_name, - user_address=address, + user_name=display_name, + user_address=member.address.email, user_options_uri=options_url, )) - if delivery_mode is not DeliveryMode.regular: - digmode = _(' (Digest mode)') - else: - digmode = '' + digmode = ('' if member.delivery_mode is DeliveryMode.regular + else _(' (Digest mode)')) msg = UserNotification( - formataddr((user_name, address)), + formataddr((display_name, member.address.email)), mlist.request_address, _('Welcome to the "$mlist.display_name" mailing list${digmode}'), text, language) diff --git a/src/mailman/app/registrar.py b/src/mailman/app/registrar.py index 0f3fbee59..aa4e35483 100644 --- a/src/mailman/app/registrar.py +++ b/src/mailman/app/registrar.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -22,22 +22,23 @@ from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ 'Registrar', + 'handle_ConfirmationNeededEvent', ] import logging from zope.component import getUtility +from zope.event import notify from zope.interface import implementer -from mailman.app.notifications import send_welcome_message from mailman.core.i18n import _ from mailman.email.message import UserNotification from mailman.interfaces.address import IEmailValidator from mailman.interfaces.listmanager import IListManager from mailman.interfaces.member import DeliveryMode, MemberRole from mailman.interfaces.pending import IPendable, IPendings -from mailman.interfaces.registrar import IRegistrar +from mailman.interfaces.registrar import ConfirmationNeededEvent, IRegistrar from mailman.interfaces.templates import ITemplateLoader from mailman.interfaces.usermanager import IUserManager from mailman.utilities.datetime import now @@ -69,29 +70,13 @@ class Registrar: type=PendableRegistration.PEND_KEY, email=email, display_name=display_name, - delivery_mode=delivery_mode.name) - pendable['list_name'] = mlist.fqdn_listname + delivery_mode=delivery_mode.name, + list_id=mlist.list_id) token = getUtility(IPendings).add(pendable) - # There are three ways for a user to confirm their subscription. They - # can reply to the original message and let the VERP'd return address - # encode the token, they can reply to the robot and keep the token in - # the Subject header, or they can click on the URL in the body of the - # message and confirm through the web. - subject = 'confirm ' + token - confirm_address = mlist.confirm_address(token) - # For i18n interpolation. - confirm_url = mlist.domain.confirm_url(token) - email_address = email - domain_name = mlist.domain.mail_host - contact_address = mlist.domain.contact_address - # Send a verification email to the address. - template = getUtility(ITemplateLoader).get( - 'mailman:///{0}/{1}/confirm.txt'.format( - mlist.fqdn_listname, - mlist.preferred_language.code)) - text = _(template) - msg = UserNotification(email, confirm_address, subject, text) - msg.send(mlist) + # We now have everything we need to begin the confirmation dance. + # Trigger the event to start the ball rolling, and return the + # generated token. + notify(ConfirmationNeededEvent(mlist, pendable, token)) return token def confirm(self, token): @@ -103,7 +88,6 @@ class Registrar: missing = object() email = pendable.get('email', missing) display_name = pendable.get('display_name', missing) - list_name = pendable.get('list_name', missing) pended_delivery_mode = pendable.get('delivery_mode', 'regular') try: delivery_mode = DeliveryMode[pended_delivery_mode] @@ -151,20 +135,43 @@ class Registrar: pass address.verified_on = now() # If this registration is tied to a mailing list, subscribe the person - # to the list right now, and possibly send a welcome message. - list_name = pendable.get('list_name') - if list_name is not None: - mlist = getUtility(IListManager).get(list_name) - if mlist: + # to the list right now. That will generate a SubscriptionEvent, + # which can be used to send a welcome message. + list_id = pendable.get('list_id') + if list_id is not None: + mlist = getUtility(IListManager).get_by_list_id(list_id) + if mlist is not None: member = mlist.subscribe(address, MemberRole.member) member.preferences.delivery_mode = delivery_mode - if mlist.send_welcome_message: - send_welcome_message(mlist, - address.email, - mlist.preferred_language, - delivery_mode) return True def discard(self, token): # Throw the record away. getUtility(IPendings).confirm(token) + + + +def handle_ConfirmationNeededEvent(event): + if not isinstance(event, ConfirmationNeededEvent): + return + # There are three ways for a user to confirm their subscription. They + # can reply to the original message and let the VERP'd return address + # encode the token, they can reply to the robot and keep the token in + # the Subject header, or they can click on the URL in the body of the + # message and confirm through the web. + subject = 'confirm ' + event.token + mlist = getUtility(IListManager).get_by_list_id(event.pendable['list_id']) + confirm_address = mlist.confirm_address(event.token) + # For i18n interpolation. + confirm_url = mlist.domain.confirm_url(event.token) + email_address = event.pendable['email'] + domain_name = mlist.domain.mail_host + contact_address = mlist.domain.contact_address + # Send a verification email to the address. + template = getUtility(ITemplateLoader).get( + 'mailman:///{0}/{1}/confirm.txt'.format( + mlist.fqdn_listname, + mlist.preferred_language.code)) + text = _(template) + msg = UserNotification(email_address, confirm_address, subject, text) + msg.send(mlist) diff --git a/src/mailman/app/replybot.py b/src/mailman/app/replybot.py index 619b9718e..30d547d8a 100644 --- a/src/mailman/app/replybot.py +++ b/src/mailman/app/replybot.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/subscriptions.py b/src/mailman/app/subscriptions.py index 0995202b6..d80069ba5 100644 --- a/src/mailman/app/subscriptions.py +++ b/src/mailman/app/subscriptions.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/templates.py b/src/mailman/app/templates.py index f0b4222cb..742584b49 100644 --- a/src/mailman/app/templates.py +++ b/src/mailman/app/templates.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/tests/test_bounces.py b/src/mailman/app/tests/test_bounces.py index f6d5669a4..5eb518786 100644 --- a/src/mailman/app/tests/test_bounces.py +++ b/src/mailman/app/tests/test_bounces.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -198,6 +198,7 @@ class TestSendProbe(unittest.TestCase): def setUp(self): self._mlist = create_list('test@example.com') + self._mlist.send_welcome_message = False self._member = add_member(self._mlist, 'anne@example.com', 'Anne Person', 'xxx', DeliveryMode.regular, 'en') @@ -355,6 +356,7 @@ class TestProbe(unittest.TestCase): def setUp(self): self._mlist = create_list('test@example.com') + self._mlist.send_welcome_message = False self._member = add_member(self._mlist, 'anne@example.com', 'Anne Person', 'xxx', DeliveryMode.regular, 'en') @@ -395,6 +397,7 @@ class TestMaybeForward(unittest.TestCase): site_owner: postmaster@example.com """) self._mlist = create_list('test@example.com') + self._mlist.send_welcome_message = False self._msg = mfs("""\ From: bouncer@example.com To: test-bounces@example.com diff --git a/src/mailman/app/tests/test_inject.py b/src/mailman/app/tests/test_inject.py index 78204aae3..f7f750662 100644 --- a/src/mailman/app/tests/test_inject.py +++ b/src/mailman/app/tests/test_inject.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/tests/test_lifecycle.py b/src/mailman/app/tests/test_lifecycle.py index cea06359d..0fb54f193 100644 --- a/src/mailman/app/tests/test_lifecycle.py +++ b/src/mailman/app/tests/test_lifecycle.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -25,11 +25,14 @@ __all__ = [ ] +import os +import shutil import unittest +from mailman.config import config from mailman.interfaces.address import InvalidEmailAddressError from mailman.interfaces.domain import BadDomainSpecificationError -from mailman.app.lifecycle import create_list +from mailman.app.lifecycle import create_list, remove_list from mailman.testing.layers import ConfigLayer @@ -48,3 +51,12 @@ class TestLifecycle(unittest.TestCase): # Creating a list with an unregistered domain raises an exception. self.assertRaises(BadDomainSpecificationError, create_list, 'test@nodomain.example.org') + + def test_remove_list_error(self): + # An error occurs while deleting the list's data directory. + mlist = create_list('test@example.com') + data_dir = os.path.join(config.LIST_DATA_DIR, mlist.fqdn_listname) + os.chmod(data_dir, 0) + self.addCleanup(shutil.rmtree, data_dir) + self.assertRaises(OSError, remove_list, mlist) + os.chmod(data_dir, 0o777) diff --git a/src/mailman/app/tests/test_membership.py b/src/mailman/app/tests/test_membership.py index 07994f34d..95e8de1d0 100644 --- a/src/mailman/app/tests/test_membership.py +++ b/src/mailman/app/tests/test_membership.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -17,10 +17,13 @@ """Tests of application level membership functions.""" -from __future__ import absolute_import, unicode_literals +from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ + 'TestAddMember', + 'TestAddMemberPassword', + 'TestDeleteMember', ] @@ -29,17 +32,18 @@ import unittest from zope.component import getUtility from mailman.app.lifecycle import create_list -from mailman.app.membership import add_member +from mailman.app.membership import add_member, delete_member from mailman.core.constants import system_preferences from mailman.interfaces.bans import IBanManager from mailman.interfaces.member import ( - AlreadySubscribedError, DeliveryMode, MemberRole, MembershipIsBannedError) + AlreadySubscribedError, DeliveryMode, MemberRole, MembershipIsBannedError, + NotAMemberError) from mailman.interfaces.usermanager import IUserManager from mailman.testing.layers import ConfigLayer -class AddMemberTest(unittest.TestCase): +class TestAddMember(unittest.TestCase): layer = ConfigLayer def setUp(self): @@ -70,10 +74,13 @@ class AddMemberTest(unittest.TestCase): # Test that members who are banned by specific address cannot # subscribe to the mailing list. IBanManager(self._mlist).ban('anne@example.com') - self.assertRaises( - MembershipIsBannedError, - add_member, self._mlist, 'anne@example.com', 'Anne Person', - '123', DeliveryMode.regular, system_preferences.preferred_language) + with self.assertRaises(MembershipIsBannedError) as cm: + add_member(self._mlist, 'anne@example.com', 'Anne Person', + '123', DeliveryMode.regular, + system_preferences.preferred_language) + self.assertEqual( + str(cm.exception), + 'anne@example.com is not allowed to subscribe to test@example.com') def test_add_member_globally_banned(self): # Test that members who are banned by specific address cannot @@ -165,7 +172,7 @@ class AddMemberTest(unittest.TestCase): -class AddMemberPasswordTest(unittest.TestCase): +class TestAddMemberPassword(unittest.TestCase): layer = ConfigLayer def setUp(self): @@ -177,3 +184,19 @@ class AddMemberPasswordTest(unittest.TestCase): 'Anne Person', 'abc', DeliveryMode.regular, system_preferences.preferred_language) self.assertEqual(member.user.password, '{plaintext}abc') + + + +class TestDeleteMember(unittest.TestCase): + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('test@example.com') + + def test_delete_member_not_a_member(self): + # Try to delete an address which is not a member of the mailing list. + with self.assertRaises(NotAMemberError) as cm: + delete_member(self._mlist, 'noperson@example.com') + self.assertEqual( + str(cm.exception), + 'noperson@example.com is not a member of test@example.com') diff --git a/src/mailman/app/tests/test_moderation.py b/src/mailman/app/tests/test_moderation.py index 529116d35..edb6b8c28 100644 --- a/src/mailman/app/tests/test_moderation.py +++ b/src/mailman/app/tests/test_moderation.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/tests/test_notifications.py b/src/mailman/app/tests/test_notifications.py index e49228d0a..4cdc1c01c 100644 --- a/src/mailman/app/tests/test_notifications.py +++ b/src/mailman/app/tests/test_notifications.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -33,10 +33,9 @@ from zope.component import getUtility from mailman.app.lifecycle import create_list from mailman.app.membership import add_member -from mailman.app.notifications import send_welcome_message from mailman.config import config from mailman.interfaces.languages import ILanguageManager -from mailman.interfaces.member import DeliveryMode +from mailman.interfaces.member import DeliveryMode, MemberRole from mailman.testing.helpers import get_queue_messages from mailman.testing.layers import ConfigLayer @@ -82,11 +81,8 @@ Welcome to the $list_name mailing list. shutil.rmtree(self.var_dir) def test_welcome_message(self): - en = getUtility(ILanguageManager).get('en') add_member(self._mlist, 'anne@example.com', 'Anne Person', 'password', DeliveryMode.regular, 'en') - send_welcome_message(self._mlist, 'anne@example.com', en, - DeliveryMode.regular) # Now there's one message in the virgin queue. messages = get_queue_messages('virgin') self.assertEqual(len(messages), 1) @@ -110,16 +106,42 @@ Welcome to the Test List mailing list. 'mailman:///$listname/$language/welcome.txt') # Add the xx language and subscribe Anne using it. manager = getUtility(ILanguageManager) - xx = manager.add('xx', 'us-ascii', 'Xlandia') + manager.add('xx', 'us-ascii', 'Xlandia') add_member(self._mlist, 'anne@example.com', 'Anne Person', 'password', DeliveryMode.regular, 'xx') - send_welcome_message(self._mlist, 'anne@example.com', xx, - DeliveryMode.regular) # Now there's one message in the virgin queue. messages = get_queue_messages('virgin') self.assertEqual(len(messages), 1) message = messages[0].msg self.assertEqual(str(message['subject']), 'Welcome to the "Test List" mailing list') - self.assertEqual(message.get_payload(), - 'You just joined the Test List mailing list!') + self.assertMultiLineEqual( + message.get_payload(), + 'You just joined the Test List mailing list!') + + def test_no_welcome_message_to_owners(self): + # Welcome messages go only to mailing list members, not to owners. + add_member(self._mlist, 'anne@example.com', 'Anne Person', + 'password', DeliveryMode.regular, 'xx', + MemberRole.owner) + # There is no welcome message in the virgin queue. + messages = get_queue_messages('virgin') + self.assertEqual(len(messages), 0) + + def test_no_welcome_message_to_nonmembers(self): + # Welcome messages go only to mailing list members, not to nonmembers. + add_member(self._mlist, 'anne@example.com', 'Anne Person', + 'password', DeliveryMode.regular, 'xx', + MemberRole.nonmember) + # There is no welcome message in the virgin queue. + messages = get_queue_messages('virgin') + self.assertEqual(len(messages), 0) + + def test_no_welcome_message_to_moderators(self): + # Welcome messages go only to mailing list members, not to moderators. + add_member(self._mlist, 'anne@example.com', 'Anne Person', + 'password', DeliveryMode.regular, 'xx', + MemberRole.moderator) + # There is no welcome message in the virgin queue. + messages = get_queue_messages('virgin') + self.assertEqual(len(messages), 0) diff --git a/src/mailman/app/tests/test_registration.py b/src/mailman/app/tests/test_registration.py new file mode 100644 index 000000000..ff128ae6f --- /dev/null +++ b/src/mailman/app/tests/test_registration.py @@ -0,0 +1,132 @@ +# Copyright (C) 2012 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Test email address registration.""" + +from __future__ import absolute_import, print_function, unicode_literals + +__metaclass__ = type +__all__ = [ + 'TestEmailValidation', + 'TestRegistration', + ] + + +import unittest + +from zope.component import getUtility + +from mailman.app.lifecycle import create_list +from mailman.interfaces.address import InvalidEmailAddressError +from mailman.interfaces.pending import IPendings +from mailman.interfaces.registrar import ConfirmationNeededEvent, IRegistrar +from mailman.testing.helpers import event_subscribers +from mailman.testing.layers import ConfigLayer + + + +class TestEmailValidation(unittest.TestCase): + """Test basic email validation.""" + + layer = ConfigLayer + + def setUp(self): + self.registrar = getUtility(IRegistrar) + self.mlist = create_list('alpha@example.com') + + def test_empty_string_is_invalid(self): + self.assertRaises(InvalidEmailAddressError, + self.registrar.register, self.mlist, + '') + + def test_no_spaces_allowed(self): + self.assertRaises(InvalidEmailAddressError, + self.registrar.register, self.mlist, + 'some name@example.com') + + def test_no_angle_brackets(self): + self.assertRaises(InvalidEmailAddressError, + self.registrar.register, self.mlist, + '<script>@example.com') + + def test_ascii_only(self): + self.assertRaises(InvalidEmailAddressError, + self.registrar.register, self.mlist, + '\xa0@example.com') + + def test_domain_required(self): + self.assertRaises(InvalidEmailAddressError, + self.registrar.register, self.mlist, + 'noatsign') + + def test_full_domain_required(self): + self.assertRaises(InvalidEmailAddressError, + self.registrar.register, self.mlist, + 'nodom@ain') + + + +class TestRegistration(unittest.TestCase): + """Test registration.""" + + layer = ConfigLayer + + def setUp(self): + self.registrar = getUtility(IRegistrar) + self.mlist = create_list('alpha@example.com') + + def test_confirmation_event_received(self): + # Registering an email address generates an event. + def capture_event(event): + self.assertIsInstance(event, ConfirmationNeededEvent) + with event_subscribers(capture_event): + self.registrar.register(self.mlist, 'anne@example.com') + + def test_event_mlist(self): + # The event has a reference to the mailing list being subscribed to. + def capture_event(event): + self.assertIs(event.mlist, self.mlist) + with event_subscribers(capture_event): + self.registrar.register(self.mlist, 'anne@example.com') + + def test_event_pendable(self): + # The event has an IPendable which contains additional information. + def capture_event(event): + pendable = event.pendable + self.assertEqual(pendable['type'], 'registration') + self.assertEqual(pendable['email'], 'anne@example.com') + # The key is present, but the value is None. + self.assertIsNone(pendable['display_name']) + # The default is regular delivery. + self.assertEqual(pendable['delivery_mode'], 'regular') + self.assertEqual(pendable['list_id'], 'alpha.example.com') + with event_subscribers(capture_event): + self.registrar.register(self.mlist, 'anne@example.com') + + def test_token(self): + # Registering the email address returns a token, and this token links + # back to the pendable. + captured_events = [] + def capture_event(event): + captured_events.append(event) + with event_subscribers(capture_event): + token = self.registrar.register(self.mlist, 'anne@example.com') + self.assertEqual(len(captured_events), 1) + event = captured_events[0] + self.assertEqual(event.token, token) + pending = getUtility(IPendings).confirm(token) + self.assertEqual(pending, event.pendable) diff --git a/src/mailman/app/tests/test_subscriptions.py b/src/mailman/app/tests/test_subscriptions.py index 6d269ffac..e5aad18bc 100644 --- a/src/mailman/app/tests/test_subscriptions.py +++ b/src/mailman/app/tests/test_subscriptions.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/app/tests/test_templates.py b/src/mailman/app/tests/test_templates.py index 59c9a05df..afde68647 100644 --- a/src/mailman/app/tests/test_templates.py +++ b/src/mailman/app/tests/test_templates.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/archiving/mailarchive.py b/src/mailman/archiving/mailarchive.py index 34a10fd25..421d65cbd 100644 --- a/src/mailman/archiving/mailarchive.py +++ b/src/mailman/archiving/mailarchive.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -43,6 +43,7 @@ class MailArchive: """ name = 'mail-archive' + is_enabled = False def __init__(self): # Read our specific configuration file diff --git a/src/mailman/archiving/mhonarc.py b/src/mailman/archiving/mhonarc.py index 6f8f3e168..4606925e0 100644 --- a/src/mailman/archiving/mhonarc.py +++ b/src/mailman/archiving/mhonarc.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -46,6 +46,7 @@ class MHonArc: """Local MHonArc archiver.""" name = 'mhonarc' + is_enabled = False def __init__(self): # Read our specific configuration file diff --git a/src/mailman/archiving/prototype.py b/src/mailman/archiving/prototype.py index df215a0da..153c44b69 100644 --- a/src/mailman/archiving/prototype.py +++ b/src/mailman/archiving/prototype.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -52,6 +52,7 @@ class Prototype: """ name = 'prototype' + is_enabled = False @staticmethod def list_url(mlist): @@ -77,7 +78,7 @@ class Prototype: """ archive_dir = os.path.join(config.ARCHIVE_DIR, 'prototype') try: - os.makedirs(archive_dir, 0775) + os.makedirs(archive_dir, 0o775) except OSError as error: # If this already exists, then we're fine if error.errno != errno.EEXIST: @@ -90,7 +91,6 @@ class Prototype: mailbox = Maildir(list_dir, create=True, factory=None) lock_file = os.path.join( config.LOCK_DIR, '{0}-maildir.lock'.format(mlist.fqdn_listname)) - # Lock the maildir as Maildir.add() is not threadsafe. Don't use the # context manager because it's not an error if we can't acquire the # archiver lock. We'll just log the problem and continue. diff --git a/src/mailman/archiving/tests/test_prototype.py b/src/mailman/archiving/tests/test_prototype.py index 930a3159b..fba46ea4b 100644 --- a/src/mailman/archiving/tests/test_prototype.py +++ b/src/mailman/archiving/tests/test_prototype.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/bumpdigests.py b/src/mailman/bin/bumpdigests.py index 380b07124..25fbe7739 100644 --- a/src/mailman/bin/bumpdigests.py +++ b/src/mailman/bin/bumpdigests.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/checkdbs.py b/src/mailman/bin/checkdbs.py index bc8e9cde4..3a5ad736e 100644 --- a/src/mailman/bin/checkdbs.py +++ b/src/mailman/bin/checkdbs.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/config_list.py b/src/mailman/bin/config_list.py index 1d52882ab..e8a5d193e 100644 --- a/src/mailman/bin/config_list.py +++ b/src/mailman/bin/config_list.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/disabled.py b/src/mailman/bin/disabled.py index 81dc5dcf5..28d5107f7 100644 --- a/src/mailman/bin/disabled.py +++ b/src/mailman/bin/disabled.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/export.py b/src/mailman/bin/export.py index 6dce2321d..a5400a9bc 100644 --- a/src/mailman/bin/export.py +++ b/src/mailman/bin/export.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/find_member.py b/src/mailman/bin/find_member.py index a42e4f9a7..3deace8fc 100644 --- a/src/mailman/bin/find_member.py +++ b/src/mailman/bin/find_member.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/gate_news.py b/src/mailman/bin/gate_news.py index 7d239fccd..b9d76cb38 100644 --- a/src/mailman/bin/gate_news.py +++ b/src/mailman/bin/gate_news.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/list_owners.py b/src/mailman/bin/list_owners.py index a57e7c99b..777018b47 100644 --- a/src/mailman/bin/list_owners.py +++ b/src/mailman/bin/list_owners.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2002-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/mailman.py b/src/mailman/bin/mailman.py index c2e2af89c..67f4d0910 100644 --- a/src/mailman/bin/mailman.py +++ b/src/mailman/bin/mailman.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -44,7 +44,7 @@ def main(): parser = argparse.ArgumentParser( description=_("""\ The GNU Mailman mailing list management system - Copyright 1998-2013 by the Free Software Foundation, Inc. + Copyright 1998-2014 by the Free Software Foundation, Inc. http://www.list.org """), formatter_class=argparse.RawDescriptionHelpFormatter) diff --git a/src/mailman/bin/master.py b/src/mailman/bin/master.py index 65737ad75..29d5401f6 100644 --- a/src/mailman/bin/master.py +++ b/src/mailman/bin/master.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/onebounce.py b/src/mailman/bin/onebounce.py index 811272bfb..32f56cb9d 100644 --- a/src/mailman/bin/onebounce.py +++ b/src/mailman/bin/onebounce.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2002-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/runner.py b/src/mailman/bin/runner.py index d6a1dd6db..c5040e3e3 100644 --- a/src/mailman/bin/runner.py +++ b/src/mailman/bin/runner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -160,7 +160,7 @@ def main(): help=_('List the available runner names and exit.')) parser.add_argument( '-v', '--verbose', - default=False, action='store_true', help=_("""\ + default=None, action='store_true', help=_("""\ Display more debugging information to the log file.""")) args = parser.parse_args() diff --git a/src/mailman/bin/senddigests.py b/src/mailman/bin/senddigests.py index 1a71bd10b..6ac8af0b7 100644 --- a/src/mailman/bin/senddigests.py +++ b/src/mailman/bin/senddigests.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/show_config.py b/src/mailman/bin/show_config.py index b874c24dc..8ee53e131 100644 --- a/src/mailman/bin/show_config.py +++ b/src/mailman/bin/show_config.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/bin/tests/test_master.py b/src/mailman/bin/tests/test_master.py index b8f34a684..6d859b44b 100644 --- a/src/mailman/bin/tests/test_master.py +++ b/src/mailman/bin/tests/test_master.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/accept.py b/src/mailman/chains/accept.py index e599aca0d..97b6019a8 100644 --- a/src/mailman/chains/accept.py +++ b/src/mailman/chains/accept.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/base.py b/src/mailman/chains/base.py index 3e3eadf06..45f890517 100644 --- a/src/mailman/chains/base.py +++ b/src/mailman/chains/base.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/builtin.py b/src/mailman/chains/builtin.py index 6482a484f..bce9349a1 100644 --- a/src/mailman/chains/builtin.py +++ b/src/mailman/chains/builtin.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/discard.py b/src/mailman/chains/discard.py index 888951211..067eaa6a8 100644 --- a/src/mailman/chains/discard.py +++ b/src/mailman/chains/discard.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/headers.py b/src/mailman/chains/headers.py index be50af34e..7628c8b7c 100644 --- a/src/mailman/chains/headers.py +++ b/src/mailman/chains/headers.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/hold.py b/src/mailman/chains/hold.py index 21b7584bf..1293ea266 100644 --- a/src/mailman/chains/hold.py +++ b/src/mailman/chains/hold.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/moderation.py b/src/mailman/chains/moderation.py index 7d58514d1..9b34f6389 100644 --- a/src/mailman/chains/moderation.py +++ b/src/mailman/chains/moderation.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/owner.py b/src/mailman/chains/owner.py index 3002337ed..8e9aac154 100644 --- a/src/mailman/chains/owner.py +++ b/src/mailman/chains/owner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/reject.py b/src/mailman/chains/reject.py index ca64770f6..c229761a6 100644 --- a/src/mailman/chains/reject.py +++ b/src/mailman/chains/reject.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/tests/test_headers.py b/src/mailman/chains/tests/test_headers.py index 59b58e999..adfc0ecb6 100644 --- a/src/mailman/chains/tests/test_headers.py +++ b/src/mailman/chains/tests/test_headers.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/tests/test_hold.py b/src/mailman/chains/tests/test_hold.py index 4d28229a8..a261a8860 100644 --- a/src/mailman/chains/tests/test_hold.py +++ b/src/mailman/chains/tests/test_hold.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/chains/tests/test_owner.py b/src/mailman/chains/tests/test_owner.py index 2dedc964b..96b858317 100644 --- a/src/mailman/chains/tests/test_owner.py +++ b/src/mailman/chains/tests/test_owner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_aliases.py b/src/mailman/commands/cli_aliases.py index 13b970d4b..7c85ad9e0 100644 --- a/src/mailman/commands/cli_aliases.py +++ b/src/mailman/commands/cli_aliases.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_conf.py b/src/mailman/commands/cli_conf.py index dfa741e3a..55f63c712 100644 --- a/src/mailman/commands/cli_conf.py +++ b/src/mailman/commands/cli_conf.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 by the Free Software Foundation, Inc. +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_control.py b/src/mailman/commands/cli_control.py index 7b8d17723..b0afc1337 100644 --- a/src/mailman/commands/cli_control.py +++ b/src/mailman/commands/cli_control.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_help.py b/src/mailman/commands/cli_help.py index c8fd2c458..ce39eeda5 100644 --- a/src/mailman/commands/cli_help.py +++ b/src/mailman/commands/cli_help.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_import.py b/src/mailman/commands/cli_import.py index 7d6cb2825..5e25cd4fe 100644 --- a/src/mailman/commands/cli_import.py +++ b/src/mailman/commands/cli_import.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_info.py b/src/mailman/commands/cli_info.py index cc4f6fe5e..4304e0ddb 100644 --- a/src/mailman/commands/cli_info.py +++ b/src/mailman/commands/cli_info.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_inject.py b/src/mailman/commands/cli_inject.py index a0cb1f8a5..07ef0ec6c 100644 --- a/src/mailman/commands/cli_inject.py +++ b/src/mailman/commands/cli_inject.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_lists.py b/src/mailman/commands/cli_lists.py index a9408bd45..79845ad57 100644 --- a/src/mailman/commands/cli_lists.py +++ b/src/mailman/commands/cli_lists.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_members.py b/src/mailman/commands/cli_members.py index 37df55cd4..291fda3b7 100644 --- a/src/mailman/commands/cli_members.py +++ b/src/mailman/commands/cli_members.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_qfile.py b/src/mailman/commands/cli_qfile.py index 5e58782f9..986898bee 100644 --- a/src/mailman/commands/cli_qfile.py +++ b/src/mailman/commands/cli_qfile.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_status.py b/src/mailman/commands/cli_status.py index 8a5cf9bde..207b44e04 100644 --- a/src/mailman/commands/cli_status.py +++ b/src/mailman/commands/cli_status.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_unshunt.py b/src/mailman/commands/cli_unshunt.py index e7c59d233..77196565b 100644 --- a/src/mailman/commands/cli_unshunt.py +++ b/src/mailman/commands/cli_unshunt.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_version.py b/src/mailman/commands/cli_version.py index a89e3fc4c..86ce9ab68 100644 --- a/src/mailman/commands/cli_version.py +++ b/src/mailman/commands/cli_version.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/cli_withlist.py b/src/mailman/commands/cli_withlist.py index beaaff398..fc2363816 100644 --- a/src/mailman/commands/cli_withlist.py +++ b/src/mailman/commands/cli_withlist.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/eml_confirm.py b/src/mailman/commands/eml_confirm.py index 8612dbdc6..0239e0f25 100644 --- a/src/mailman/commands/eml_confirm.py +++ b/src/mailman/commands/eml_confirm.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/eml_echo.py b/src/mailman/commands/eml_echo.py index 4c47b2a84..eb476dc7d 100644 --- a/src/mailman/commands/eml_echo.py +++ b/src/mailman/commands/eml_echo.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2002-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/eml_end.py b/src/mailman/commands/eml_end.py index e5301acc8..447d4066b 100644 --- a/src/mailman/commands/eml_end.py +++ b/src/mailman/commands/eml_end.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2002-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/eml_help.py b/src/mailman/commands/eml_help.py index a8d5ab7e0..139d484fb 100644 --- a/src/mailman/commands/eml_help.py +++ b/src/mailman/commands/eml_help.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/eml_membership.py b/src/mailman/commands/eml_membership.py index 8534dd0fc..617807783 100644 --- a/src/mailman/commands/eml_membership.py +++ b/src/mailman/commands/eml_membership.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2002-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/tests/test_conf.py b/src/mailman/commands/tests/test_conf.py index 04ce4c9b5..12ed5c537 100644 --- a/src/mailman/commands/tests/test_conf.py +++ b/src/mailman/commands/tests/test_conf.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 by the Free Software Foundation, Inc. +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/tests/test_confirm.py b/src/mailman/commands/tests/test_confirm.py index 32f253762..19a9068bc 100644 --- a/src/mailman/commands/tests/test_confirm.py +++ b/src/mailman/commands/tests/test_confirm.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -55,11 +55,10 @@ class TestConfirm(unittest.TestCase): def tearDown(self): reset_the_world() - + def test_welcome_message(self): # A confirmation causes a welcome message to be sent to the member, if # enabled by the mailing list. - # status = self._command.process( self._mlist, Message(), {}, (self._token,), Results()) self.assertEqual(status, ContinueProcessing.yes) @@ -68,7 +67,7 @@ class TestConfirm(unittest.TestCase): self.assertEqual(len(messages), 1) # Grab the welcome message. welcome = messages[0].msg - self.assertEqual(welcome['subject'], + self.assertEqual(welcome['subject'], 'Welcome to the "Test" mailing list') self.assertEqual(welcome['to'], 'Anne Person <anne@example.com>') diff --git a/src/mailman/commands/tests/test_control.py b/src/mailman/commands/tests/test_control.py index 5cd07d415..df61edccf 100644 --- a/src/mailman/commands/tests/test_control.py +++ b/src/mailman/commands/tests/test_control.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/tests/test_create.py b/src/mailman/commands/tests/test_create.py index b33fe4c52..21ffd9c5b 100644 --- a/src/mailman/commands/tests/test_create.py +++ b/src/mailman/commands/tests/test_create.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/commands/tests/test_help.py b/src/mailman/commands/tests/test_help.py index 56cb1e1cb..3c7d1ae9f 100644 --- a/src/mailman/commands/tests/test_help.py +++ b/src/mailman/commands/tests/test_help.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/config/__init__.py b/src/mailman/config/__init__.py index e836e0aea..cf500bae4 100644 --- a/src/mailman/config/__init__.py +++ b/src/mailman/config/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/config/config.py b/src/mailman/config/config.py index 74931c029..e8c8ebc8b 100644 --- a/src/mailman/config/config.py +++ b/src/mailman/config/config.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -249,18 +249,14 @@ class Configuration: @property def archivers(self): - """Iterate over all the enabled archivers.""" + """Iterate over all the archivers.""" for section in self._config.getByCategory('archiver', []): - if not as_boolean(section.enable): + class_path = section['class'].strip() + if len(class_path) == 0: continue - class_path = section['class'] - yield call_name(class_path) - - @property - def style_configs(self): - """Iterate over all the style configuration sections.""" - for section in self._config.getByCategory('style', []): - yield section + archiver = call_name(class_path) + archiver.is_enabled = as_boolean(section.enable) + yield archiver @property def language_configs(self): diff --git a/src/mailman/config/configure.zcml b/src/mailman/config/configure.zcml index efb449538..f9b9cb093 100644 --- a/src/mailman/config/configure.zcml +++ b/src/mailman/config/configure.zcml @@ -30,6 +30,12 @@ <adapter for="mailman.interfaces.mailinglist.IMailingList" + provides="mailman.interfaces.mailinglist.IListArchiverSet" + factory="mailman.model.mailinglist.ListArchiverSet" + /> + + <adapter + for="mailman.interfaces.mailinglist.IMailingList" provides="mailman.interfaces.requests.IListRequests" factory="mailman.model.requests.ListRequests" /> diff --git a/src/mailman/config/exim4.cfg b/src/mailman/config/exim4.cfg new file mode 100644 index 000000000..e614ad182 --- /dev/null +++ b/src/mailman/config/exim4.cfg @@ -0,0 +1,4 @@ +[exim4] +# Additional configuration variables for the Exim MTA, version 4. + +# Exim doesn't need any additional configuration yet. diff --git a/src/mailman/config/mail_archive.cfg b/src/mailman/config/mail_archive.cfg index 2a48c48b2..ddd410ee7 100644 --- a/src/mailman/config/mail_archive.cfg +++ b/src/mailman/config/mail_archive.cfg @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/config/mailman.cfg b/src/mailman/config/mailman.cfg index 00831df46..24e81ec91 100644 --- a/src/mailman/config/mailman.cfg +++ b/src/mailman/config/mailman.cfg @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -89,5 +89,3 @@ class: mailman.runners.virgin.VirginRunner [runner.digest] class: mailman.runners.digest.DigestRunner - -[style.default] diff --git a/src/mailman/config/mhonarc.cfg b/src/mailman/config/mhonarc.cfg index e020cf961..454a68d2f 100644 --- a/src/mailman/config/mhonarc.cfg +++ b/src/mailman/config/mhonarc.cfg @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/config/schema.cfg b/src/mailman/config/schema.cfg index f132b0358..d7508a533 100644 --- a/src/mailman/config/schema.cfg +++ b/src/mailman/config/schema.cfg @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -532,7 +532,7 @@ register_bounces_every: 15m # following values. # The class implementing the IArchiver interface. -class: mailman.archiving.prototype.Prototype +class: # Set this to 'yes' to enable the archiver. enable: no diff --git a/src/mailman/config/tests/test_archivers.py b/src/mailman/config/tests/test_archivers.py new file mode 100644 index 000000000..08e466878 --- /dev/null +++ b/src/mailman/config/tests/test_archivers.py @@ -0,0 +1,56 @@ +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Site-wide archiver configuration tests.""" + +from __future__ import absolute_import, print_function, unicode_literals + +__metaclass__ = type +__all__ = [ + 'TestArchivers', + ] + + +import unittest + +from mailman.config import config +from mailman.testing.helpers import configuration +from mailman.testing.layers import ConfigLayer + + + +class TestArchivers(unittest.TestCase): + layer = ConfigLayer + + def test_enabled(self): + # By default, the testing configuration enables the archivers. + archivers = {} + for archiver in config.archivers: + archivers[archiver.name] = archiver + self.assertTrue(archivers['prototype'].is_enabled) + self.assertTrue(archivers['mail-archive'].is_enabled) + self.assertTrue(archivers['mhonarc'].is_enabled) + + @configuration('archiver.mhonarc', enable='no') + def test_disabled(self): + # We just disabled one of the archivers. + archivers = {} + for archiver in config.archivers: + archivers[archiver.name] = archiver + self.assertTrue(archivers['prototype'].is_enabled) + self.assertTrue(archivers['mail-archive'].is_enabled) + self.assertFalse(archivers['mhonarc'].is_enabled) diff --git a/src/mailman/config/tests/test_configuration.py b/src/mailman/config/tests/test_configuration.py index 3a4e94913..3c623c005 100644 --- a/src/mailman/config/tests/test_configuration.py +++ b/src/mailman/config/tests/test_configuration.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -22,19 +22,22 @@ from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ 'TestConfiguration', + 'TestConfigurationErrors', 'TestExternal', ] +import os +import tempfile import unittest -from pkg_resources import resource_filename - -from mailman.config.config import external_configuration, load_external +from mailman.config.config import ( + Configuration, external_configuration, load_external) from mailman.interfaces.configuration import ( ConfigurationUpdatedEvent, MissingConfigurationFileError) from mailman.testing.helpers import configuration, event_subscribers from mailman.testing.layers import ConfigLayer +from pkg_resources import resource_filename @@ -99,3 +102,41 @@ class TestExternal(unittest.TestCase): with self.assertRaises(MissingConfigurationFileError) as cm: external_configuration('path:mailman.config.missing') self.assertEqual(cm.exception.path, 'path:mailman.config.missing') + + + +class TestConfigurationErrors(unittest.TestCase): + layer = ConfigLayer + + def test_bad_path_layout_specifier(self): + # Using a [mailman]layout name that doesn't exist is a fatal error. + fd, filename = tempfile.mkstemp() + self.addCleanup(os.remove, filename) + os.close(fd) + with open(filename, 'w') as fp: + print("""\ +[mailman] +layout: nonesuch +""", file=fp) + # Use a fake sys.exit() function that records that it was called, and + # that prevents further processing. + config = Configuration() + with self.assertRaises(SystemExit) as cm: + config.load(filename) + self.assertEqual(cm.exception.args, (1,)) + + def test_path_expansion_infloop(self): + # A path expansion never completes because it references a + # non-existent substitution variable. + fd, filename = tempfile.mkstemp() + self.addCleanup(os.remove, filename) + os.close(fd) + with open(filename, 'w') as fp: + print("""\ +[paths.dev] +log_dir: $nopath/log_dir +""", file=fp) + config = Configuration() + with self.assertRaises(SystemExit) as cm: + config.load(filename) + self.assertEqual(cm.exception.args, (1,)) diff --git a/src/mailman/core/chains.py b/src/mailman/core/chains.py index 7435e346f..ac6f5a50a 100644 --- a/src/mailman/core/chains.py +++ b/src/mailman/core/chains.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/constants.py b/src/mailman/core/constants.py index 327bbc96f..f8e354199 100644 --- a/src/mailman/core/constants.py +++ b/src/mailman/core/constants.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/errors.py b/src/mailman/core/errors.py index 5df156907..56f9948ce 100644 --- a/src/mailman/core/errors.py +++ b/src/mailman/core/errors.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/i18n.py b/src/mailman/core/i18n.py index b61cf7590..80f1a6448 100644 --- a/src/mailman/core/i18n.py +++ b/src/mailman/core/i18n.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/initialize.py b/src/mailman/core/initialize.py index 2e5a4238f..6f1e10068 100644 --- a/src/mailman/core/initialize.py +++ b/src/mailman/core/initialize.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -115,7 +115,7 @@ def initialize_1(config_path=None): # write our files. Specifically we must have g+rw and we probably want # o-rwx although I think in most cases it doesn't hurt if other can read # or write the files. - os.umask(007) + os.umask(0o007) # Initialize configuration event subscribers. This must be done before # setting up the configuration system. from mailman.app.events import initialize as initialize_events diff --git a/src/mailman/core/logging.py b/src/mailman/core/logging.py index c80535fc1..27799a641 100644 --- a/src/mailman/core/logging.py +++ b/src/mailman/core/logging.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/pipelines.py b/src/mailman/core/pipelines.py index db57150cb..e164169a4 100644 --- a/src/mailman/core/pipelines.py +++ b/src/mailman/core/pipelines.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/rules.py b/src/mailman/core/rules.py index bdcdbfe69..d527c62ea 100644 --- a/src/mailman/core/rules.py +++ b/src/mailman/core/rules.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/runner.py b/src/mailman/core/runner.py index 347726b85..81a2ea3d1 100644 --- a/src/mailman/core/runner.py +++ b/src/mailman/core/runner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/switchboard.py b/src/mailman/core/switchboard.py index ec0231ed7..8a94588fa 100644 --- a/src/mailman/core/switchboard.py +++ b/src/mailman/core/switchboard.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/system.py b/src/mailman/core/system.py index baee7202f..495cc37ee 100644 --- a/src/mailman/core/system.py +++ b/src/mailman/core/system.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/tests/test_pipelines.py b/src/mailman/core/tests/test_pipelines.py index 76b997307..67e6af36e 100644 --- a/src/mailman/core/tests/test_pipelines.py +++ b/src/mailman/core/tests/test_pipelines.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/core/tests/test_runner.py b/src/mailman/core/tests/test_runner.py index 2a4f7f8f7..2875b3b10 100644 --- a/src/mailman/core/tests/test_runner.py +++ b/src/mailman/core/tests/test_runner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/base.py b/src/mailman/database/base.py index 0b23c8adc..cbf88a4ff 100644 --- a/src/mailman/database/base.py +++ b/src/mailman/database/base.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/factory.py b/src/mailman/database/factory.py index f02354c11..db453ea41 100644 --- a/src/mailman/database/factory.py +++ b/src/mailman/database/factory.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/model.py b/src/mailman/database/model.py index 435e910fd..ba2d39213 100644 --- a/src/mailman/database/model.py +++ b/src/mailman/database/model.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/postgresql.py b/src/mailman/database/postgresql.py index 8586df068..48c68a937 100644 --- a/src/mailman/database/postgresql.py +++ b/src/mailman/database/postgresql.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/schema/helpers.py b/src/mailman/database/schema/helpers.py index c8638a12a..827e6cc96 100644 --- a/src/mailman/database/schema/helpers.py +++ b/src/mailman/database/schema/helpers.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 by the Free Software Foundation, Inc. +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/schema/mm_00000000000000_base.py b/src/mailman/database/schema/mm_00000000000000_base.py index 41e85d057..ad085427f 100644 --- a/src/mailman/database/schema/mm_00000000000000_base.py +++ b/src/mailman/database/schema/mm_00000000000000_base.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/schema/mm_20120407000000.py b/src/mailman/database/schema/mm_20120407000000.py index c1045fa91..1d798ea96 100644 --- a/src/mailman/database/schema/mm_20120407000000.py +++ b/src/mailman/database/schema/mm_20120407000000.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/schema/mm_20121015000000.py b/src/mailman/database/schema/mm_20121015000000.py index da3671998..84510ff57 100644 --- a/src/mailman/database/schema/mm_20121015000000.py +++ b/src/mailman/database/schema/mm_20121015000000.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/schema/mm_20130406000000.py b/src/mailman/database/schema/mm_20130406000000.py index 11ba70869..8d38dbab0 100644 --- a/src/mailman/database/schema/mm_20130406000000.py +++ b/src/mailman/database/schema/mm_20130406000000.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 by the Free Software Foundation, Inc. +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/schema/sqlite_20130406000000_01.sql b/src/mailman/database/schema/sqlite_20130406000000_01.sql index 9bdc2aae0..fe30ed247 100644 --- a/src/mailman/database/schema/sqlite_20130406000000_01.sql +++ b/src/mailman/database/schema/sqlite_20130406000000_01.sql @@ -6,12 +6,17 @@ -- For SQLite3 migration strategy, see -- http://sqlite.org/faq.html#q11 --- REMOVALS from the bounceevent table: +-- ADD listarchiver table. + +-- REMOVALs from the bounceevent table: -- REM list_name --- ADDS to the ban bounceevent table: +-- ADDs to the bounceevent table: -- ADD list_id +-- ADDs to the mailinglist table: +-- ADD archiver_id + CREATE TABLE bounceevent_backup ( id INTEGER NOT NULL, email TEXT, @@ -28,3 +33,14 @@ INSERT INTO bounceevent_backup SELECT FROM bounceevent; ALTER TABLE bounceevent_backup ADD COLUMN list_id TEXT; + +CREATE TABLE listarchiver ( + id INTEGER NOT NULL, + mailing_list_id INTEGER NOT NULL, + name TEXT NOT NULL, + _is_enabled BOOLEAN, + PRIMARY KEY (id) + ); + +CREATE INDEX ix_listarchiver_mailing_list_id + ON listarchiver(mailing_list_id); diff --git a/src/mailman/database/sqlite.py b/src/mailman/database/sqlite.py index 8fe170cda..15629615f 100644 --- a/src/mailman/database/sqlite.py +++ b/src/mailman/database/sqlite.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/tests/test_migrations.py b/src/mailman/database/tests/test_migrations.py index d983f9891..9619b80a4 100644 --- a/src/mailman/database/tests/test_migrations.py +++ b/src/mailman/database/tests/test_migrations.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -36,6 +36,7 @@ import unittest from datetime import datetime from operator import attrgetter from pkg_resources import resource_string +from sqlite3 import OperationalError from storm.exceptions import DatabaseError from zope.component import getUtility @@ -65,6 +66,23 @@ class MigrationTestBase(unittest.TestCase): def tearDown(self): self._database._cleanup() + def _table_missing_present(self, migrations, missing, present): + """The appropriate migrations leave some tables missing and present. + + :param migrations: Sequence of migrations to load. + :param missing: Tables which should be missing. + :param present: Tables which should be present. + """ + for migration in migrations: + self._database.load_migrations(migration) + self._database.store.commit() + for table in missing: + self.assertRaises(OperationalError, + self._database.store.execute, + 'select * from {};'.format(table)) + for table in present: + self._database.store.execute('select * from {};'.format(table)) + def _missing_present(self, table, migrations, missing, present): """The appropriate migrations leave columns missing and present. @@ -450,6 +468,15 @@ class TestMigration20130406Schema(MigrationTestBase): ('list_name',), ('list_id',)) + def test_pre_listarchiver_table(self): + self._table_missing_present(['20130405999999'], ('listarchiver',), ()) + + def test_post_listarchiver_table(self): + self._table_missing_present(['20130405999999', + '20130406000000'], + (), + ('listarchiver',)) + class TestMigration20130406MigratedData(MigrationTestBase): diff --git a/src/mailman/database/transaction.py b/src/mailman/database/transaction.py index dc2411915..3e156cfb8 100644 --- a/src/mailman/database/transaction.py +++ b/src/mailman/database/transaction.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/database/types.py b/src/mailman/database/types.py index 86d504ca3..eb3a4d357 100644 --- a/src/mailman/database/types.py +++ b/src/mailman/database/types.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/docs/ACKNOWLEDGMENTS.rst b/src/mailman/docs/ACKNOWLEDGMENTS.rst index 55a746ac7..8e6987265 100644 --- a/src/mailman/docs/ACKNOWLEDGMENTS.rst +++ b/src/mailman/docs/ACKNOWLEDGMENTS.rst @@ -4,7 +4,7 @@ GNU Mailman Acknowledgments =========================== -Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +Copyright (C) 1998-2014 by the Free Software Foundation, Inc. Core Developers diff --git a/src/mailman/docs/INTRODUCTION.rst b/src/mailman/docs/INTRODUCTION.rst index e7128e756..ac77d0e72 100644 --- a/src/mailman/docs/INTRODUCTION.rst +++ b/src/mailman/docs/INTRODUCTION.rst @@ -18,7 +18,7 @@ Learn more about GNU Mailman in the `Getting Started`_ documentation. Copyright ========= -Copyright 1998-2013 by the Free Software Foundation, Inc. +Copyright 1998-2014 by the Free Software Foundation, Inc. This file is part of GNU Mailman. diff --git a/src/mailman/docs/MTA.rst b/src/mailman/docs/MTA.rst index 7165c30b9..feec21106 100644 --- a/src/mailman/docs/MTA.rst +++ b/src/mailman/docs/MTA.rst @@ -22,10 +22,10 @@ Transfer Protocol`_ (SMTP_). Cooperation between Mailman and the MTA requires some configuration of both. MTA configuration differs for each of the available MTAs, and -there is a section for each one. Instructions for Postfix are given -below. We would really appreciate contributions of configurations for -Exim and Sendmail, and welcome information about other popular open -source mail servers. +there is a section for each one. Instructions for Postfix and Exim (v4) +are given below. We would really appreciate a contribution of a +configuration for Sendmail, and welcome information about other popular +open source mail servers. Configuring Mailman to communicate with the MTA is straightforward, and basically the same for all MTAs. In your ``mailman.cfg`` file, @@ -38,15 +38,24 @@ add (or edit) a section like the following:: lmtp_port: 8024 smtp_host: localhost smtp_port: 25 + configuration: python:mailman.config.postfix This configuration is for a system where Mailman and the MTA are on the same host. -The ``incoming`` and ``outgoing`` parameters identify the Python -objects used to communicate with the MTA. The ``deliver`` module used -in ``outgoing`` is pretty standard across all MTAs. The ``postfix`` -module in ``incoming`` is specific to Postfix. See the section for -your MTA below for details on these parameters. +Note that the modules that configure the communication protocol (especially +``incoming``) are full-fledged Python modules, and may use these configuration +parameters to automatically configure the MTA to recognize the list addresses +and other attributes of the communication channel. This is why some +constraints on the format of attributes arise (e.g., ``lmtp_host``), even +though Mailman itself has no problem with them. + +The ``incoming`` and ``outgoing`` parameters identify the Python objects used +to communicate with the MTA. The ``python:`` scheme indicates that the paths +should be a dotted Python module specification. The ``deliver`` module used +in ``outgoing`` should be satisfactory for most MTAs. The ``postfix`` module +in ``incoming`` is specific to the Postfix MTA. See the section for your MTA +below for details on these parameters. ``lmtp_host`` and ``lmtp_port`` are parameters which are used by Mailman, but also will be passed to the MTA to identify the Mailman @@ -175,7 +184,118 @@ the Postfix documentation at: Exim ==== -Contributions are welcome! +`Exim 4`_ is an MTA maintained by the `University of Cambridge`_ and +distributed by most open source OS distributions. + +Mailman settings +---------------- + +Add or edit a stanza like this in mailman.cfg:: + + [mta] + # For all Exim4 installations. + incoming: mailman.mta.exim4.LMTP + outgoing: mailman.mta.deliver.deliver + # Typical single host with MTA and Mailman configuration. + # Adjust to your system's configuration. + # Exim happily works with the "localhost" alias rather than IP address. + lmtp_host: localhost + smtp_host: localhost + # Mailman should not be run as root. + # Use any convenient port > 1024. 8024 is a convention, but can be + # changed if there is a conflict with other software using that port. + lmtp_port: 8024 + # smtp_port rarely needs to be set. + smtp_port: 25 + # Exim4-specific configuration parameter defaults. Currently empty. + configuration: python:mailman.config.exim4 + +For further information about these settings, see +``mailman/config/schema.cfg``. + +Exim4 configuration +------------------- + +The configuration presented below is mostly boilerplate that allows Exim to +automatically discover your list addresses, and route both posts and +administrative messages to the right Mailman services. For this reason, the +`mailman.mta.exim4` module ends up with all methods being no-ops. + +This configuration is field-tested in a Debian "conf.d"-style Exim +installation, with multiple configuration files that are assembled by a +Debian-specific script. If your Exim v4 installation is structured +differently, ignore the comments indicating location in the Debian +installation. +:: + + # /etc/exim4/conf.d/main/25_mm3_macros + # The colon-separated list of domains served by Mailman. + domainlist mm_domains=list.example.net + + MM3_LMTP_PORT=8024 + + # Assuming a typical source installation in /usr/local, with + # links to the Mailman bin directory and so on from MM3_HOME. + MM3_HOME=/usr/local/var/mailman + MM3_UID=list + MM3_GID=list + + ################################################################ + # The configuration below is boilerplate: + # you should not need to change it. + + # The path to the list receipt (used as the required file when + # matching list addresses) + MM3_LISTCHK=MM3_HOME/lists/${local_part}@${domain} + + # /etc/exim4/conf.d/main/455_mm3_router + mailman3_router: + driver = accept + domains = +mm_domains + require_files = MM3_LISTCHK + local_part_suffix_optional + local_part_suffix = -admin : \ + -bounces : -bounces+* : \ + -confirm : -confirm+* : \ + -join : -leave : \ + -owner : -request : \ + -subscribe : -unsubscribe + transport = mailman3_transport + + # /etc/exim4/conf.d/main/55_mm3_transport + mailman3_transport: + driver = smtp + protocol = lmtp + allow_localhost + hosts = localhost + port = MM3_LMTP_PORT + +Troubleshooting +--------------- + +The most likely causes of failure to deliver to Mailman are typos in the +configuration, and errors in the ``MM3_HOME`` macro or the ``mm_domains`` +list. Mismatches in the LMTP port could be a cause. Finally, Exim's router +configuration is order-sensitive. Especially if you are being tricky and +supporting Mailman 2 and Mailman 3 at the same time, you could have one shadow +the other. + +Exim 4 documentation +-------------------- + +There is `copious documentation for Exim`_. The parts most relevant to +configuring communication with Mailman 3 are the chapters on the `accept +router`_ and the `LMTP transport`_. Unless you are already familiar +with Exim configuration, you probably want to start with the chapter on +`how Exim receives and delivers mail`. + +.. _`Exim 4`: http://www.exim.org/ +.. _`University of Cambridge`: http://www.cam.ac.uk/ +.. _`copious documentation for Exim`: http://www.exim.org/docs.html +.. _`accept router`: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_accept_router.html +.. _`LMTP transport`: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-the_lmtp_transport.html +.. _`how Exim receives and delivers mail`: http://www.exim.org/exim-html-current/doc/html/spec_html/ch-how_exim_receives_and_delivers_mail.html + Sendmail diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst index 37a05c3ed..05e29d2c6 100644 --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -2,7 +2,7 @@ Mailman - The GNU Mailing List Management System ================================================ -Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +Copyright (C) 1998-2014 by the Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA Here is a history of user visible changes to Mailman. @@ -10,7 +10,7 @@ Here is a history of user visible changes to Mailman. 3.0 beta 4 -- "Time and Motion" =============================== -(2013-XX-XX) +(2014-XX-XX) Development ----------- @@ -28,6 +28,8 @@ REST Given by Florian Fuchs. (LP: #1156529) * Expose ``hide_address`` to the ``.../preferences`` REST API. Contributed by Sneha Priscilla. + * Mailing lists can now individually enable or disable any archiver available + site-wide. Contributed by Joanna Skrzeszewska. (LP: #1158040) Commands -------- @@ -37,6 +39,7 @@ Commands Configuration ------------- + * Add support for the Exim 4 MTA. Contributed by Stephen Turnbull. * When creating the initial file system layout in ``var``, e.g. via ``bin/mailman info``, add an ``var/etc/mailman.cfg`` file if one does not already exist. Also, when initializing the system, look for that file as @@ -47,6 +50,7 @@ Database -------- * The `bounceevent` table now uses list-ids to cross-reference the mailing list, to match other tables. Similarly for the `IBounceEvent` interface. + * Added a `listarchiver` table to support list-specific archivers. Bugs ---- @@ -60,6 +64,11 @@ Bugs docstring for `display_name`. (LP: #1181498) * Fix importation from MM2.1 to MM3 of the archive policy. Given by Aurélien Bompard. (LP: #1227658) + * Fix non-member moderation rule to prefer a member sender if both members + and non-members are in the message's sender list. Given by Aurélien + Bompard. (LP: #1291452) + * Fix IntegrityError (against PostgreSQL) when deleting a list with content + filters. Given by Aurélien Bompard. (LP: #1117174) 3.0 beta 3 -- "Here Again" diff --git a/src/mailman/docs/START.rst b/src/mailman/docs/START.rst index a50deabf9..570f84570 100644 --- a/src/mailman/docs/START.rst +++ b/src/mailman/docs/START.rst @@ -4,7 +4,7 @@ Getting started with GNU Mailman ================================ -Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +Copyright (C) 2008-2014 by the Free Software Foundation, Inc. Beta Release diff --git a/src/mailman/docs/STYLEGUIDE.rst b/src/mailman/docs/STYLEGUIDE.rst index 5a7d04fdb..13fb0cdf1 100644 --- a/src/mailman/docs/STYLEGUIDE.rst +++ b/src/mailman/docs/STYLEGUIDE.rst @@ -2,7 +2,7 @@ GNU Mailman Coding Style Guide ============================== -Copyright (C) 2002-2013 Barry A. Warsaw +Copyright (C) 2002-2014 Barry A. Warsaw Python coding style guide for GNU Mailman diff --git a/src/mailman/docs/__init__.py b/src/mailman/docs/__init__.py index a7be8f186..b094a1e3d 100644 --- a/src/mailman/docs/__init__.py +++ b/src/mailman/docs/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/email/message.py b/src/mailman/email/message.py index 17ade4520..81185b8d1 100644 --- a/src/mailman/email/message.py +++ b/src/mailman/email/message.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/email/tests/test_message.py b/src/mailman/email/tests/test_message.py index 84f2a54cd..e281c0d06 100644 --- a/src/mailman/email/tests/test_message.py +++ b/src/mailman/email/tests/test_message.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/email/validate.py b/src/mailman/email/validate.py index 0b1866eca..b4cf8b5e2 100644 --- a/src/mailman/email/validate.py +++ b/src/mailman/email/validate.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/acknowledge.py b/src/mailman/handlers/acknowledge.py index 789d1f654..c3af9ab27 100644 --- a/src/mailman/handlers/acknowledge.py +++ b/src/mailman/handlers/acknowledge.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/after_delivery.py b/src/mailman/handlers/after_delivery.py index 67627c51c..7fa7a4554 100644 --- a/src/mailman/handlers/after_delivery.py +++ b/src/mailman/handlers/after_delivery.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/avoid_duplicates.py b/src/mailman/handlers/avoid_duplicates.py index d1685240c..529a99f68 100644 --- a/src/mailman/handlers/avoid_duplicates.py +++ b/src/mailman/handlers/avoid_duplicates.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2002-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/cleanse.py b/src/mailman/handlers/cleanse.py index 3e02d977c..6b653bb34 100644 --- a/src/mailman/handlers/cleanse.py +++ b/src/mailman/handlers/cleanse.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/cleanse_dkim.py b/src/mailman/handlers/cleanse_dkim.py index 943a21868..225666bf1 100644 --- a/src/mailman/handlers/cleanse_dkim.py +++ b/src/mailman/handlers/cleanse_dkim.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/cook_headers.py b/src/mailman/handlers/cook_headers.py index 6269f4c45..2ce3f653e 100644 --- a/src/mailman/handlers/cook_headers.py +++ b/src/mailman/handlers/cook_headers.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/decorate.py b/src/mailman/handlers/decorate.py index 183135d9a..bf8454232 100644 --- a/src/mailman/handlers/decorate.py +++ b/src/mailman/handlers/decorate.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/docs/acknowledge.rst b/src/mailman/handlers/docs/acknowledge.rst index 479aa4ea6..2235985ad 100644 --- a/src/mailman/handlers/docs/acknowledge.rst +++ b/src/mailman/handlers/docs/acknowledge.rst @@ -10,6 +10,7 @@ acknowledgment. >>> mlist = create_list('test@example.com') >>> mlist.display_name = 'Test' >>> mlist.preferred_language = 'en' + >>> mlist.send_welcome_message = False >>> # XXX This will almost certainly change once we've worked out the web >>> # space layout for mailing lists now. diff --git a/src/mailman/handlers/file_recipients.py b/src/mailman/handlers/file_recipients.py index 2441491c8..ec8868649 100644 --- a/src/mailman/handlers/file_recipients.py +++ b/src/mailman/handlers/file_recipients.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/member_recipients.py b/src/mailman/handlers/member_recipients.py index 50d496934..0f99bf709 100644 --- a/src/mailman/handlers/member_recipients.py +++ b/src/mailman/handlers/member_recipients.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/mime_delete.py b/src/mailman/handlers/mime_delete.py index abf229f7d..ff6c19ce2 100644 --- a/src/mailman/handlers/mime_delete.py +++ b/src/mailman/handlers/mime_delete.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2002-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/owner_recipients.py b/src/mailman/handlers/owner_recipients.py index d57769777..de6d575e1 100644 --- a/src/mailman/handlers/owner_recipients.py +++ b/src/mailman/handlers/owner_recipients.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/replybot.py b/src/mailman/handlers/replybot.py index 3855daa40..63f3ca4cf 100644 --- a/src/mailman/handlers/replybot.py +++ b/src/mailman/handlers/replybot.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/rfc_2369.py b/src/mailman/handlers/rfc_2369.py index d203f747a..3ac721d19 100644 --- a/src/mailman/handlers/rfc_2369.py +++ b/src/mailman/handlers/rfc_2369.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -28,10 +28,10 @@ __all__ = [ from email.utils import formataddr from zope.interface import implementer -from mailman.config import config from mailman.core.i18n import _ from mailman.handlers.cook_headers import uheader from mailman.interfaces.archiver import ArchivePolicy +from mailman.interfaces.mailinglist import IListArchiverSet from mailman.interfaces.handler import IHandler @@ -84,10 +84,13 @@ def process(mlist, msg, msgdata): headers['List-Post'] = list_post # Add RFC 2369 and 5064 archiving headers, if archiving is enabled. if mlist.archive_policy is not ArchivePolicy.never: - for archiver in config.archivers: + archiver_set = IListArchiverSet(mlist) + for archiver in archiver_set.archivers: + if not archiver.is_enabled: + continue headers['List-Archive'] = '<{0}>'.format( - archiver.list_url(mlist)) - permalink = archiver.permalink(mlist, msg) + archiver.system_archiver.list_url(mlist)) + permalink = archiver.system_archiver.permalink(mlist, msg) if permalink is not None: headers['Archived-At'] = permalink # XXX RFC 2369 also defines a List-Owner header which we are not currently diff --git a/src/mailman/handlers/tagger.py b/src/mailman/handlers/tagger.py index c1d30a63d..803cc6d11 100644 --- a/src/mailman/handlers/tagger.py +++ b/src/mailman/handlers/tagger.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/tests/test_mimedel.py b/src/mailman/handlers/tests/test_mimedel.py index 26023e732..c7c37152f 100644 --- a/src/mailman/handlers/tests/test_mimedel.py +++ b/src/mailman/handlers/tests/test_mimedel.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/tests/test_recipients.py b/src/mailman/handlers/tests/test_recipients.py index 25ac6cc99..04789c281 100644 --- a/src/mailman/handlers/tests/test_recipients.py +++ b/src/mailman/handlers/tests/test_recipients.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/to_archive.py b/src/mailman/handlers/to_archive.py index cdb0f0906..d18742f3c 100644 --- a/src/mailman/handlers/to_archive.py +++ b/src/mailman/handlers/to_archive.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/to_digest.py b/src/mailman/handlers/to_digest.py index 85325799c..9eb5818bb 100644 --- a/src/mailman/handlers/to_digest.py +++ b/src/mailman/handlers/to_digest.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/to_outgoing.py b/src/mailman/handlers/to_outgoing.py index b65971f4e..6dfbe88c0 100644 --- a/src/mailman/handlers/to_outgoing.py +++ b/src/mailman/handlers/to_outgoing.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/handlers/to_usenet.py b/src/mailman/handlers/to_usenet.py index 1c655d15f..d5a946644 100644 --- a/src/mailman/handlers/to_usenet.py +++ b/src/mailman/handlers/to_usenet.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/action.py b/src/mailman/interfaces/action.py index 22a65d5e1..5d4b150a3 100644 --- a/src/mailman/interfaces/action.py +++ b/src/mailman/interfaces/action.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/address.py b/src/mailman/interfaces/address.py index 450afaae6..28a9e8ef4 100644 --- a/src/mailman/interfaces/address.py +++ b/src/mailman/interfaces/address.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/archiver.py b/src/mailman/interfaces/archiver.py index 5f074503e..8b843bc60 100644 --- a/src/mailman/interfaces/archiver.py +++ b/src/mailman/interfaces/archiver.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -50,6 +50,8 @@ class IArchiver(Interface): """An interface to the archiver.""" name = Attribute('The name of this archiver') + is_enabled = Attribute( + 'A flag indicating whether this archiver is enabled site-wide.') def list_url(mlist): """Return the url to the top of the list's archive. diff --git a/src/mailman/interfaces/autorespond.py b/src/mailman/interfaces/autorespond.py index acad717f1..de0ff3348 100644 --- a/src/mailman/interfaces/autorespond.py +++ b/src/mailman/interfaces/autorespond.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/bans.py b/src/mailman/interfaces/bans.py index 9cb188b79..48b3415c8 100644 --- a/src/mailman/interfaces/bans.py +++ b/src/mailman/interfaces/bans.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/bounce.py b/src/mailman/interfaces/bounce.py index ff7a47732..0cee88b6a 100644 --- a/src/mailman/interfaces/bounce.py +++ b/src/mailman/interfaces/bounce.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/chain.py b/src/mailman/interfaces/chain.py index 9fffc2760..1b6531d2e 100644 --- a/src/mailman/interfaces/chain.py +++ b/src/mailman/interfaces/chain.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/command.py b/src/mailman/interfaces/command.py index 18a8024a8..2a0656841 100644 --- a/src/mailman/interfaces/command.py +++ b/src/mailman/interfaces/command.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/configuration.py b/src/mailman/interfaces/configuration.py index c9a438e2d..65547d44d 100644 --- a/src/mailman/interfaces/configuration.py +++ b/src/mailman/interfaces/configuration.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/database.py b/src/mailman/interfaces/database.py index 96465d4f2..21f2f71d0 100644 --- a/src/mailman/interfaces/database.py +++ b/src/mailman/interfaces/database.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/digests.py b/src/mailman/interfaces/digests.py index 416e18f13..3abb5e57b 100644 --- a/src/mailman/interfaces/digests.py +++ b/src/mailman/interfaces/digests.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/domain.py b/src/mailman/interfaces/domain.py index f0f1099c5..d8f8ec100 100644 --- a/src/mailman/interfaces/domain.py +++ b/src/mailman/interfaces/domain.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/errors.py b/src/mailman/interfaces/errors.py index 654b1ae17..0d3eef7e8 100644 --- a/src/mailman/interfaces/errors.py +++ b/src/mailman/interfaces/errors.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/handler.py b/src/mailman/interfaces/handler.py index fbd882603..2e6c3fa20 100644 --- a/src/mailman/interfaces/handler.py +++ b/src/mailman/interfaces/handler.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/languages.py b/src/mailman/interfaces/languages.py index 6b8f52fc5..32c18fb7a 100644 --- a/src/mailman/interfaces/languages.py +++ b/src/mailman/interfaces/languages.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/listmanager.py b/src/mailman/interfaces/listmanager.py index 45b12af53..068fe82dc 100644 --- a/src/mailman/interfaces/listmanager.py +++ b/src/mailman/interfaces/listmanager.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -97,9 +97,9 @@ class IListManager(Interface): def create(fqdn_listname): """Create a mailing list with the given name. - :type fqdn_listname: Unicode :param fqdn_listname: The fully qualified name of the mailing list, e.g. `mylist@example.com`. + :type fqdn_listname: Unicode :return: The newly created `IMailingList`. :raise `ListAlreadyExistsError` if the named list already exists. """ @@ -107,8 +107,8 @@ class IListManager(Interface): def get(fqdn_listname): """Return the mailing list with the given name, if it exists. - :type fqdn_listname: Unicode. :param fqdn_listname: The fully qualified name of the mailing list. + :type fqdn_listname: Unicode. :return: the matching `IMailingList` or None if the named list does not exist. """ @@ -116,8 +116,8 @@ class IListManager(Interface): def get_by_list_id(list_id): """Return the mailing list with the given list id, if it exists. - :type fqdn_listname: Unicode. :param fqdn_listname: The fully qualified name of the mailing list. + :type fqdn_listname: Unicode. :return: the matching `IMailingList` or None if the named list does not exist. """ @@ -125,8 +125,8 @@ class IListManager(Interface): def delete(mlist): """Remove the mailing list from the database. - :type mlist: `IMailingList` :param mlist: The mailing list to delete. + :type mlist: `IMailingList` """ mailing_lists = Attribute( diff --git a/src/mailman/interfaces/mailinglist.py b/src/mailman/interfaces/mailinglist.py index 0615ad239..3900e3349 100644 --- a/src/mailman/interfaces/mailinglist.py +++ b/src/mailman/interfaces/mailinglist.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -23,6 +23,8 @@ __metaclass__ = type __all__ = [ 'IAcceptableAlias', 'IAcceptableAliasSet', + 'IListArchiver', + 'IListArchiverSet', 'IMailingList', 'Personalization', 'ReplyToMunging', @@ -791,3 +793,37 @@ class IAcceptableAliasSet(Interface): aliases = Attribute( """An iterator over all the acceptable aliases.""") + + + +class IListArchiver(Interface): + """An archiver for a mailing list. + + The named archiver must be enabled site-wide in order for a mailing list + to be able to enable it. + """ + + mailing_list = Attribute('The associated mailing list.') + + name = Attribute('The name of the archiver.') + + is_enabled = Attribute('Is this archiver enabled for this mailing list?') + + system_archiver = Attribute( + 'The associated system-wide IArchiver instance.') + + +class IListArchiverSet(Interface): + """The set of archivers (enabled or disabled) for a mailing list.""" + + archivers = Attribute( + """An iterator over all the archivers for this mailing list.""") + + def get(archiver_name): + """Return the `IListArchiver` with the given name, if it exists. + + :param archiver_name: The name of the archiver. + :type archiver_name: unicode. + :return: the matching `IListArchiver` or None if the named archiver + does not exist. + """ diff --git a/src/mailman/interfaces/member.py b/src/mailman/interfaces/member.py index b561a7571..f5fe9438e 100644 --- a/src/mailman/interfaces/member.py +++ b/src/mailman/interfaces/member.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/messages.py b/src/mailman/interfaces/messages.py index f29fac317..6b9db67d2 100644 --- a/src/mailman/interfaces/messages.py +++ b/src/mailman/interfaces/messages.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/mime.py b/src/mailman/interfaces/mime.py index 549e6c3db..502fbca4e 100644 --- a/src/mailman/interfaces/mime.py +++ b/src/mailman/interfaces/mime.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/mlistrequest.py b/src/mailman/interfaces/mlistrequest.py index b130303c6..dc6a9463e 100644 --- a/src/mailman/interfaces/mlistrequest.py +++ b/src/mailman/interfaces/mlistrequest.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/mta.py b/src/mailman/interfaces/mta.py index c67e4f822..ccbef04cb 100644 --- a/src/mailman/interfaces/mta.py +++ b/src/mailman/interfaces/mta.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/nntp.py b/src/mailman/interfaces/nntp.py index 03be8f11d..8e73c2c50 100644 --- a/src/mailman/interfaces/nntp.py +++ b/src/mailman/interfaces/nntp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/pending.py b/src/mailman/interfaces/pending.py index f0cb07d65..77045aafe 100644 --- a/src/mailman/interfaces/pending.py +++ b/src/mailman/interfaces/pending.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/permissions.py b/src/mailman/interfaces/permissions.py index cf2e563ab..8e403e89c 100644 --- a/src/mailman/interfaces/permissions.py +++ b/src/mailman/interfaces/permissions.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/pipeline.py b/src/mailman/interfaces/pipeline.py index 5a2d56aec..b7c933cac 100644 --- a/src/mailman/interfaces/pipeline.py +++ b/src/mailman/interfaces/pipeline.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/preferences.py b/src/mailman/interfaces/preferences.py index cf6a1b459..4d9ef683f 100644 --- a/src/mailman/interfaces/preferences.py +++ b/src/mailman/interfaces/preferences.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/registrar.py b/src/mailman/interfaces/registrar.py index 51150dbf2..8a77ca8f6 100644 --- a/src/mailman/interfaces/registrar.py +++ b/src/mailman/interfaces/registrar.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -26,6 +26,7 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ + 'ConfirmationNeededEvent', 'IRegistrar', ] @@ -34,6 +35,29 @@ from zope.interface import Interface +class ConfirmationNeededEvent: + """Triggered when an address needs confirmation. + + Addresses must be verified before they can receive messages or post to + mailing list. When an address is registered with Mailman, via the + `IRegistrar` interface, an `IPendable` is created which represents the + pending registration. This pending registration is stored in the + database, keyed by a token. Then this event is triggered. + + There may be several ways to confirm an email address. On some sites, + registration may immediately produce a verification, e.g. because it is on + a known intranet. Or verification may occur via external database lookup + (e.g. LDAP). On most public mailing lists, a mail-back confirmation is + sent to the address, and only if they reply to the mail-back, or click on + an embedded link, is the registered address confirmed. + """ + def __init__(self, mlist, pendable, token): + self.mlist = mlist + self.pendable = pendable + self.token = token + + + class IRegistrar(Interface): """Interface for registering and verifying email addresses and users. diff --git a/src/mailman/interfaces/requests.py b/src/mailman/interfaces/requests.py index 35de05100..2df1b20fd 100644 --- a/src/mailman/interfaces/requests.py +++ b/src/mailman/interfaces/requests.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/roster.py b/src/mailman/interfaces/roster.py index 9b293829c..6a3e5c579 100644 --- a/src/mailman/interfaces/roster.py +++ b/src/mailman/interfaces/roster.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/rules.py b/src/mailman/interfaces/rules.py index a9d6145a2..7de70dee3 100644 --- a/src/mailman/interfaces/rules.py +++ b/src/mailman/interfaces/rules.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/runner.py b/src/mailman/interfaces/runner.py index a8b76652c..8ad9000ce 100644 --- a/src/mailman/interfaces/runner.py +++ b/src/mailman/interfaces/runner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/styles.py b/src/mailman/interfaces/styles.py index c75c81f75..f4c185cd2 100644 --- a/src/mailman/interfaces/styles.py +++ b/src/mailman/interfaces/styles.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/subscriptions.py b/src/mailman/interfaces/subscriptions.py index ea49331b5..456ae7be1 100644 --- a/src/mailman/interfaces/subscriptions.py +++ b/src/mailman/interfaces/subscriptions.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/switchboard.py b/src/mailman/interfaces/switchboard.py index b3adcfe50..36f0644be 100644 --- a/src/mailman/interfaces/switchboard.py +++ b/src/mailman/interfaces/switchboard.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/system.py b/src/mailman/interfaces/system.py index 17ef9193a..999878aa0 100644 --- a/src/mailman/interfaces/system.py +++ b/src/mailman/interfaces/system.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/templates.py b/src/mailman/interfaces/templates.py index aec4e8d24..de5fa11a9 100644 --- a/src/mailman/interfaces/templates.py +++ b/src/mailman/interfaces/templates.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/user.py b/src/mailman/interfaces/user.py index 10d91a2e9..e1c1df243 100644 --- a/src/mailman/interfaces/user.py +++ b/src/mailman/interfaces/user.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/interfaces/usermanager.py b/src/mailman/interfaces/usermanager.py index 2994a1afc..b06043c78 100644 --- a/src/mailman/interfaces/usermanager.py +++ b/src/mailman/interfaces/usermanager.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/languages/language.py b/src/mailman/languages/language.py index 503e7fa88..35e142559 100644 --- a/src/mailman/languages/language.py +++ b/src/mailman/languages/language.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/languages/manager.py b/src/mailman/languages/manager.py index 2be551346..7e73c11b0 100644 --- a/src/mailman/languages/manager.py +++ b/src/mailman/languages/manager.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/address.py b/src/mailman/model/address.py index 9f3d2d355..f5e7ddbfd 100644 --- a/src/mailman/model/address.py +++ b/src/mailman/model/address.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/autorespond.py b/src/mailman/model/autorespond.py index 048354193..c5e736613 100644 --- a/src/mailman/model/autorespond.py +++ b/src/mailman/model/autorespond.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/bans.py b/src/mailman/model/bans.py index f5cbae9ba..673e8e0c1 100644 --- a/src/mailman/model/bans.py +++ b/src/mailman/model/bans.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/bounce.py b/src/mailman/model/bounce.py index 9ae2b585d..134c51263 100644 --- a/src/mailman/model/bounce.py +++ b/src/mailman/model/bounce.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/digests.py b/src/mailman/model/digests.py index 6341d6987..5d9f3ddd1 100644 --- a/src/mailman/model/digests.py +++ b/src/mailman/model/digests.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/docs/registration.rst b/src/mailman/model/docs/registration.rst index 58e9d7a86..77cb75890 100644 --- a/src/mailman/model/docs/registration.rst +++ b/src/mailman/model/docs/registration.rst @@ -104,7 +104,7 @@ But this address is waiting for confirmation. delivery_mode: regular display_name : Anne Person email : aperson@example.com - list_name : alpha@example.com + list_id : alpha.example.com type : registration diff --git a/src/mailman/model/domain.py b/src/mailman/model/domain.py index a71bd12d3..28e346022 100644 --- a/src/mailman/model/domain.py +++ b/src/mailman/model/domain.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/language.py b/src/mailman/model/language.py index 8bf4428be..14cf53f07 100644 --- a/src/mailman/model/language.py +++ b/src/mailman/model/language.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/listmanager.py b/src/mailman/model/listmanager.py index f1c2941e0..d648a5bde 100644 --- a/src/mailman/model/listmanager.py +++ b/src/mailman/model/listmanager.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/mailinglist.py b/src/mailman/model/mailinglist.py index f9d8b8488..955a76968 100644 --- a/src/mailman/model/mailinglist.py +++ b/src/mailman/model/mailinglist.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -47,8 +47,8 @@ from mailman.interfaces.digests import DigestFrequency from mailman.interfaces.domain import IDomainManager from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.mailinglist import ( - IAcceptableAlias, IAcceptableAliasSet, IMailingList, Personalization, - ReplyToMunging) + IAcceptableAlias, IAcceptableAliasSet, IListArchiver, IListArchiverSet, + IMailingList, Personalization, ReplyToMunging) from mailman.interfaces.member import ( AlreadySubscribedError, MemberRole, MissingPreferredAddressError, SubscriptionEvent) @@ -539,3 +539,69 @@ class AcceptableAliasSet: AcceptableAlias.mailing_list == self._mailing_list) for alias in aliases: yield alias.alias + + + +@implementer(IListArchiver) +class ListArchiver(Model): + """See `IListArchiver`.""" + + id = Int(primary=True) + + mailing_list_id = Int() + mailing_list = Reference(mailing_list_id, MailingList.id) + name = Unicode() + _is_enabled = Bool() + + def __init__(self, mailing_list, archiver_name, system_archiver): + self.mailing_list = mailing_list + self.name = archiver_name + self._is_enabled = system_archiver.is_enabled + + @property + def system_archiver(self): + for archiver in config.archivers: + if archiver.name == self.name: + return archiver + return None + + @property + def is_enabled(self): + return self.system_archiver.is_enabled and self._is_enabled + + @is_enabled.setter + def is_enabled(self, value): + self._is_enabled = value + + +@implementer(IListArchiverSet) +class ListArchiverSet: + def __init__(self, mailing_list): + self._mailing_list = mailing_list + system_archivers = {} + for archiver in config.archivers: + system_archivers[archiver.name] = archiver + # Add any system enabled archivers which aren't already associated + # with the mailing list. + store = Store.of(self._mailing_list) + for archiver_name in system_archivers: + exists = store.find( + ListArchiver, + And(ListArchiver.mailing_list == mailing_list, + ListArchiver.name == archiver_name)).one() + if exists is None: + store.add(ListArchiver(mailing_list, archiver_name, + system_archivers[archiver_name])) + + @property + def archivers(self): + entries = Store.of(self._mailing_list).find( + ListArchiver, ListArchiver.mailing_list == self._mailing_list) + for entry in entries: + yield entry + + def get(self, archiver_name): + return Store.of(self._mailing_list).find( + ListArchiver, + And(ListArchiver.mailing_list == self._mailing_list, + ListArchiver.name == archiver_name)).one() diff --git a/src/mailman/model/member.py b/src/mailman/model/member.py index 1789a2dc9..438796811 100644 --- a/src/mailman/model/member.py +++ b/src/mailman/model/member.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -136,7 +136,7 @@ class Member(Model): if self._address is None else getUtility(IUserManager).get_user(self._address.email)) - def _lookup(self, preference): + def _lookup(self, preference, default=None): pref = getattr(self.preferences, preference) if pref is not None: return pref @@ -147,7 +147,9 @@ class Member(Model): pref = getattr(self.address.user.preferences, preference) if pref is not None: return pref - return getattr(system_preferences, preference) + if default is None: + return getattr(system_preferences, preference) + return default @property def acknowledge_posts(self): @@ -157,7 +159,13 @@ class Member(Model): @property def preferred_language(self): """See `IMember`.""" - return self._lookup('preferred_language') + missing = object() + language = self._lookup('preferred_language', missing) + if language is missing: + language = ((self.mailing_list and + self.mailing_list.preferred_language) or + system_preferences.preferred_language) + return language @property def receive_list_copy(self): diff --git a/src/mailman/model/message.py b/src/mailman/model/message.py index a955ca865..2d697c30b 100644 --- a/src/mailman/model/message.py +++ b/src/mailman/model/message.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/messagestore.py b/src/mailman/model/messagestore.py index 8b1435ef2..a4950e8c9 100644 --- a/src/mailman/model/messagestore.py +++ b/src/mailman/model/messagestore.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/mime.py b/src/mailman/model/mime.py index 9a853a673..570112a97 100644 --- a/src/mailman/model/mime.py +++ b/src/mailman/model/mime.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/pending.py b/src/mailman/model/pending.py index 29b08f9b7..17513015c 100644 --- a/src/mailman/model/pending.py +++ b/src/mailman/model/pending.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/preferences.py b/src/mailman/model/preferences.py index 3967c0d5c..83271d7d6 100644 --- a/src/mailman/model/preferences.py +++ b/src/mailman/model/preferences.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/requests.py b/src/mailman/model/requests.py index f9e59e254..f3ad54797 100644 --- a/src/mailman/model/requests.py +++ b/src/mailman/model/requests.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/roster.py b/src/mailman/model/roster.py index 4ac1dc37e..5a6a13269 100644 --- a/src/mailman/model/roster.py +++ b/src/mailman/model/roster.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/tests/test_bounce.py b/src/mailman/model/tests/test_bounce.py index ad3467d11..a22da4416 100644 --- a/src/mailman/model/tests/test_bounce.py +++ b/src/mailman/model/tests/test_bounce.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/tests/test_domain.py b/src/mailman/model/tests/test_domain.py index 3d7f95615..0a7ef22f1 100644 --- a/src/mailman/model/tests/test_domain.py +++ b/src/mailman/model/tests/test_domain.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -21,6 +21,8 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ + 'TestDomainLifecycleEvents', + 'TestDomainManager', ] diff --git a/src/mailman/model/tests/test_listmanager.py b/src/mailman/model/tests/test_listmanager.py index 5d5cc8395..2d3a4e3dc 100644 --- a/src/mailman/model/tests/test_listmanager.py +++ b/src/mailman/model/tests/test_listmanager.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -17,10 +17,13 @@ """Test the ListManager.""" -from __future__ import absolute_import, unicode_literals +from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ + 'TestListCreation', + 'TestListLifecycleEvents', + 'TestListManager', ] @@ -133,8 +136,8 @@ Message-ID: <argon> # must be deleted first or an IntegrityError will be raised. filter_names = ('filter_types', 'pass_types', 'filter_extensions', 'pass_extensions') - for fname in filter_names: - setattr(self._ant, fname, ['test-filter-1', 'test-filter-2']) + for name in filter_names: + setattr(self._ant, name, ['test-filter-1', 'test-filter-2']) getUtility(IListManager).delete(self._ant) store = Store.of(self._ant) filters = store.find(ContentFilter, diff --git a/src/mailman/model/tests/test_mailinglist.py b/src/mailman/model/tests/test_mailinglist.py new file mode 100644 index 000000000..9d6177b54 --- /dev/null +++ b/src/mailman/model/tests/test_mailinglist.py @@ -0,0 +1,106 @@ +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Test MailingLists and related model objects..""" + +from __future__ import absolute_import, print_function, unicode_literals + +__metaclass__ = type +__all__ = [ + 'TestListArchiver', + 'TestDisabledListArchiver', + ] + + +import unittest + +from mailman.app.lifecycle import create_list +from mailman.config import config +from mailman.interfaces.mailinglist import IListArchiverSet +from mailman.testing.helpers import configuration +from mailman.testing.layers import ConfigLayer + + + +class TestListArchiver(unittest.TestCase): + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('ant@example.com') + self._set = IListArchiverSet(self._mlist) + + def test_list_archivers(self): + # Find the set of archivers registered for this mailing list. + self.assertEqual( + ['mail-archive', 'mhonarc', 'prototype'], + sorted(archiver.name for archiver in self._set.archivers)) + + def test_get_archiver(self): + # Use .get() to see if a mailing list has an archiver. + archiver = self._set.get('prototype') + self.assertEqual(archiver.name, 'prototype') + self.assertTrue(archiver.is_enabled) + self.assertEqual(archiver.mailing_list, self._mlist) + self.assertEqual(archiver.system_archiver.name, 'prototype') + + def test_get_archiver_no_such(self): + # Using .get() on a non-existing name returns None. + self.assertIsNone(self._set.get('no-such-archiver')) + + def test_site_disabled(self): + # Here the system configuration enables all the archivers in time for + # the archive set to be created with all list archivers enabled. But + # then the site-wide archiver gets disabled, so the list specific + # archiver will also be disabled. + archiver_set = IListArchiverSet(self._mlist) + archiver = archiver_set.get('prototype') + self.assertTrue(archiver.is_enabled) + # Disable the site-wide archiver. + config.push('enable prototype', """\ + [archiver.prototype] + enable: no + """) + self.assertFalse(archiver.is_enabled) + config.pop('enable prototype') + + + +class TestDisabledListArchiver(unittest.TestCase): + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('ant@example.com') + + @configuration('archiver.prototype', enable='no') + def test_enable_list_archiver(self): + # When the system configuration file disables an archiver site-wide, + # the list-specific mailing list will get initialized as not enabled. + # Create the archiver set on the fly so that it doesn't get + # initialized with a configuration that enables the prototype archiver. + archiver_set = IListArchiverSet(self._mlist) + archiver = archiver_set.get('prototype') + self.assertFalse(archiver.is_enabled) + # Enable both the list archiver and the system archiver. + archiver.is_enabled = True + config.push('enable prototype', """\ + [archiver.prototype] + enable: yes + """) + # Get the IListArchiver again. + archiver = archiver_set.get('prototype') + self.assertTrue(archiver.is_enabled) + config.pop('enable prototype') diff --git a/src/mailman/model/tests/test_member.py b/src/mailman/model/tests/test_member.py index c8ddb7f47..5bd3d1594 100644 --- a/src/mailman/model/tests/test_member.py +++ b/src/mailman/model/tests/test_member.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -17,19 +17,21 @@ """Test members.""" -from __future__ import absolute_import, unicode_literals +from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ + 'TestMember', ] import unittest from mailman.app.lifecycle import create_list -from mailman.interfaces.member import MembershipError +from mailman.interfaces.member import MemberRole, MembershipError from mailman.interfaces.user import UnverifiedAddressError from mailman.interfaces.usermanager import IUserManager +from mailman.model.member import Member from mailman.testing.layers import ConfigLayer from mailman.utilities.datetime import now @@ -94,3 +96,9 @@ class TestMember(unittest.TestCase): # The new address is not verified. self.assertRaises(MembershipError, setattr, member, 'address', bart_address) + + def test_member_ctor_value_error(self): + # ValueError when passing in anything but a user or address. + self.assertRaises(ValueError, Member, MemberRole.member, + self._mlist.list_id, + 'aperson@example.com') diff --git a/src/mailman/model/tests/test_requests.py b/src/mailman/model/tests/test_requests.py index 2c85f7340..dc1b9b849 100644 --- a/src/mailman/model/tests/test_requests.py +++ b/src/mailman/model/tests/test_requests.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/tests/test_roster.py b/src/mailman/model/tests/test_roster.py index ccc3958b9..5bd06f485 100644 --- a/src/mailman/model/tests/test_roster.py +++ b/src/mailman/model/tests/test_roster.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/tests/test_uid.py b/src/mailman/model/tests/test_uid.py index 726c91f38..f74ffed54 100644 --- a/src/mailman/model/tests/test_uid.py +++ b/src/mailman/model/tests/test_uid.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/tests/test_user.py b/src/mailman/model/tests/test_user.py index 80d3397c8..d184eb176 100644 --- a/src/mailman/model/tests/test_user.py +++ b/src/mailman/model/tests/test_user.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/uid.py b/src/mailman/model/uid.py index eb1c7e50e..c60d0f1eb 100644 --- a/src/mailman/model/uid.py +++ b/src/mailman/model/uid.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/user.py b/src/mailman/model/user.py index 082b7adcf..f2c09c626 100644 --- a/src/mailman/model/user.py +++ b/src/mailman/model/user.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/usermanager.py b/src/mailman/model/usermanager.py index 07de5dc90..6f4a7ff5c 100644 --- a/src/mailman/model/usermanager.py +++ b/src/mailman/model/usermanager.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/model/version.py b/src/mailman/model/version.py index 5d4347b8f..e99fb0d1c 100644 --- a/src/mailman/model/version.py +++ b/src/mailman/model/version.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/aliases.py b/src/mailman/mta/aliases.py index 402b9836b..1b5f37d44 100644 --- a/src/mailman/mta/aliases.py +++ b/src/mailman/mta/aliases.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/base.py b/src/mailman/mta/base.py index fbfcc1ff7..7b9180ea3 100644 --- a/src/mailman/mta/base.py +++ b/src/mailman/mta/base.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/bulk.py b/src/mailman/mta/bulk.py index 10445e167..da3026083 100644 --- a/src/mailman/mta/bulk.py +++ b/src/mailman/mta/bulk.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/connection.py b/src/mailman/mta/connection.py index afc48cf64..f5c330921 100644 --- a/src/mailman/mta/connection.py +++ b/src/mailman/mta/connection.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/decorating.py b/src/mailman/mta/decorating.py index de0384132..a23e188a1 100644 --- a/src/mailman/mta/decorating.py +++ b/src/mailman/mta/decorating.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/deliver.py b/src/mailman/mta/deliver.py index b05289e5c..de6b80a8c 100644 --- a/src/mailman/mta/deliver.py +++ b/src/mailman/mta/deliver.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/exim4.py b/src/mailman/mta/exim4.py new file mode 100644 index 000000000..1180b59eb --- /dev/null +++ b/src/mailman/mta/exim4.py @@ -0,0 +1,51 @@ +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Creation/deletion hooks for the Exim4 MTA.""" + +from __future__ import absolute_import, print_function, unicode_literals + +__metaclass__ = type +__all__ = [ + 'LMTP', + ] + + +from mailman.interfaces.mta import IMailTransportAgentLifecycle +from zope.interface import implementer + + + +@implementer(IMailTransportAgentLifecycle) +class LMTP: + """Connect Mailman to Exim4 via LMTP. + + See `IMailTransportAgentLifecycle`. + """ + + # Exim4 handles all configuration itself, by finding the list config file. + def __init__(self): + pass + + def create(self, mlist): + pass + + delete = create + + def regenerate(self, directory=None): + """See `IMailTransportAgentLifecycle`.""" + pass diff --git a/src/mailman/mta/null.py b/src/mailman/mta/null.py index 3b714b917..7a3624b31 100644 --- a/src/mailman/mta/null.py +++ b/src/mailman/mta/null.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/personalized.py b/src/mailman/mta/personalized.py index aa838a190..adc3c90a4 100644 --- a/src/mailman/mta/personalized.py +++ b/src/mailman/mta/personalized.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/postfix.py b/src/mailman/mta/postfix.py index 68c777e5b..bb709c6b4 100644 --- a/src/mailman/mta/postfix.py +++ b/src/mailman/mta/postfix.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/tests/test_aliases.py b/src/mailman/mta/tests/test_aliases.py index 9bb9c0f62..2c33c7821 100644 --- a/src/mailman/mta/tests/test_aliases.py +++ b/src/mailman/mta/tests/test_aliases.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/tests/test_delivery.py b/src/mailman/mta/tests/test_delivery.py index 0d424de75..0a910c13d 100644 --- a/src/mailman/mta/tests/test_delivery.py +++ b/src/mailman/mta/tests/test_delivery.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/mta/verp.py b/src/mailman/mta/verp.py index 499ada129..968ed58c3 100644 --- a/src/mailman/mta/verp.py +++ b/src/mailman/mta/verp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/options.py b/src/mailman/options.py index 5aaa17fac..c0b9dea97 100644 --- a/src/mailman/options.py +++ b/src/mailman/options.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/addresses.py b/src/mailman/rest/addresses.py index 2908fad57..51bbe2046 100644 --- a/src/mailman/rest/addresses.py +++ b/src/mailman/rest/addresses.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/configuration.py b/src/mailman/rest/configuration.py index c726d8a81..db0918703 100644 --- a/src/mailman/rest/configuration.py +++ b/src/mailman/rest/configuration.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/docs/__init__.py b/src/mailman/rest/docs/__init__.py index 95ce89e63..794f5f034 100644 --- a/src/mailman/rest/docs/__init__.py +++ b/src/mailman/rest/docs/__init__.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/docs/helpers.rst b/src/mailman/rest/docs/helpers.rst index 4f0b1c804..3e8092f4e 100644 --- a/src/mailman/rest/docs/helpers.rst +++ b/src/mailman/rest/docs/helpers.rst @@ -27,6 +27,7 @@ be set in the configuration file. ... use_https: yes ... api_version: 4.2 ... """) + >>> cleanups.append((config.pop, 'helpers')) >>> print path_to('system') https://geddy:2112/4.2/system diff --git a/src/mailman/rest/docs/lists.rst b/src/mailman/rest/docs/lists.rst index 295e8c0b7..27503c1c1 100644 --- a/src/mailman/rest/docs/lists.rst +++ b/src/mailman/rest/docs/lists.rst @@ -230,3 +230,61 @@ The mailing list does not exist. >>> print list_manager.get('ant@example.com') None + + +Managing mailing list archivers +=============================== + +The Mailman system has some site-wide enabled archivers, and each mailing list +can enable or disable these archivers individually. This gives list owners +control over where traffic to their list is archived. You can see which +archivers are available, and whether they are enabled for this mailing list. +:: + + >>> mlist = create_list('dog@example.com') + >>> transaction.commit() + + >>> dump_json('http://localhost:9001/3.0/lists/dog@example.com/archivers') + http_etag: "..." + mail-archive: True + mhonarc: True + prototype: True + +You can set all the archiver states by putting new state flags on the +resource. +:: + + >>> dump_json( + ... 'http://localhost:9001/3.0/lists/dog@example.com/archivers', { + ... 'mail-archive': False, + ... 'mhonarc': True, + ... 'prototype': False, + ... }, method='PUT') + content-length: 0 + date: ... + server: ... + status: 204 + + >>> dump_json('http://localhost:9001/3.0/lists/dog@example.com/archivers') + http_etag: "..." + mail-archive: False + mhonarc: True + prototype: False + +You can change the state of a subset of the list archivers. +:: + + >>> dump_json( + ... 'http://localhost:9001/3.0/lists/dog@example.com/archivers', { + ... 'mhonarc': False, + ... }, method='PATCH') + content-length: 0 + date: ... + server: ... + status: 204 + + >>> dump_json('http://localhost:9001/3.0/lists/dog@example.com/archivers') + http_etag: "..." + mail-archive: False + mhonarc: False + prototype: False diff --git a/src/mailman/rest/domains.py b/src/mailman/rest/domains.py index 4c7192a13..e9ef8e055 100644 --- a/src/mailman/rest/domains.py +++ b/src/mailman/rest/domains.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py index 7d911d42b..d05dedd90 100644 --- a/src/mailman/rest/helpers.py +++ b/src/mailman/rest/helpers.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/lists.py b/src/mailman/rest/lists.py index 32e22a76b..066b6618f 100644 --- a/src/mailman/rest/lists.py +++ b/src/mailman/rest/lists.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -23,11 +23,13 @@ __metaclass__ = type __all__ = [ 'AList', 'AllLists', + 'ListArchivers', 'ListConfiguration', 'ListsForDomain', ] +from lazr.config import as_boolean from operator import attrgetter from restish import http, resource from zope.component import getUtility @@ -36,11 +38,13 @@ from mailman.app.lifecycle import create_list, remove_list from mailman.interfaces.domain import BadDomainSpecificationError from mailman.interfaces.listmanager import ( IListManager, ListAlreadyExistsError) +from mailman.interfaces.mailinglist import IListArchiverSet from mailman.interfaces.member import MemberRole from mailman.interfaces.subscriptions import ISubscriptionService from mailman.rest.configuration import ListConfiguration from mailman.rest.helpers import ( - CollectionMixin, etag, no_content, paginate, path_to, restish_matcher) + CollectionMixin, GetterSetter, PATCH, etag, no_content, paginate, path_to, + restish_matcher) from mailman.rest.members import AMember, MemberCollection from mailman.rest.moderation import HeldMessages, SubscriptionRequests from mailman.rest.validator import Validator @@ -189,6 +193,13 @@ class AList(_ListBase): return http.not_found() return SubscriptionRequests(self._mlist) + @resource.child() + def archivers(self, request, segments): + """Return a representation of mailing list archivers.""" + if self._mlist is None: + return http.not_found() + return ListArchivers(self._mlist) + class AllLists(_ListBase): @@ -256,3 +267,59 @@ class ListsForDomain(_ListBase): def _get_collection(self, request): """See `CollectionMixin`.""" return list(self._domain.mailing_lists) + + + +class ArchiverGetterSetter(GetterSetter): + """Resource for updating archiver statuses.""" + + def __init__(self, mlist): + super(ArchiverGetterSetter, self).__init__() + self._archiver_set = IListArchiverSet(mlist) + + def put(self, mlist, attribute, value): + # attribute will contain the (bytes) name of the archiver that is + # getting a new status. value will be the representation of the new + # boolean status. + archiver = self._archiver_set.get(attribute.decode('utf-8')) + if archiver is None: + raise ValueError('No such archiver: {}'.format(attribute)) + archiver.is_enabled = as_boolean(value) + + +class ListArchivers(resource.Resource): + """The archivers for a list, with their enabled flags.""" + + def __init__(self, mlist): + self._mlist = mlist + + @resource.GET() + def statuses(self, request): + """Get all the archiver statuses.""" + archiver_set = IListArchiverSet(self._mlist) + resource = {archiver.name: archiver.is_enabled + for archiver in archiver_set.archivers} + return http.ok([], etag(resource)) + + def patch_put(self, request, is_optional): + archiver_set = IListArchiverSet(self._mlist) + kws = {archiver.name: ArchiverGetterSetter(self._mlist) + for archiver in archiver_set.archivers} + if is_optional: + # For a PUT, all attributes are optional. + kws['_optional'] = kws.keys() + try: + Validator(**kws).update(self._mlist, request) + except ValueError as error: + return http.bad_request([], str(error)) + return no_content() + + @resource.PUT() + def put_statuses(self, request): + """Update all the archiver statuses.""" + return self.patch_put(request, is_optional=False) + + @PATCH() + def patch_statuses(self, request): + """Patch some archiver statueses.""" + return self.patch_put(request, is_optional=True) diff --git a/src/mailman/rest/members.py b/src/mailman/rest/members.py index 76b2ed1a7..5be7a4525 100644 --- a/src/mailman/rest/members.py +++ b/src/mailman/rest/members.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/moderation.py b/src/mailman/rest/moderation.py index 491807f38..1a302ff3c 100644 --- a/src/mailman/rest/moderation.py +++ b/src/mailman/rest/moderation.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/preferences.py b/src/mailman/rest/preferences.py index 49db6c632..0789d39c4 100644 --- a/src/mailman/rest/preferences.py +++ b/src/mailman/rest/preferences.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/root.py b/src/mailman/rest/root.py index 0c83c51d3..f1f99daec 100644 --- a/src/mailman/rest/root.py +++ b/src/mailman/rest/root.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/templates.py b/src/mailman/rest/templates.py index 0ae49bc49..bee21d7de 100644 --- a/src/mailman/rest/templates.py +++ b/src/mailman/rest/templates.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/tests/test_addresses.py b/src/mailman/rest/tests/test_addresses.py index 833091601..9d9e44c22 100644 --- a/src/mailman/rest/tests/test_addresses.py +++ b/src/mailman/rest/tests/test_addresses.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/tests/test_domains.py b/src/mailman/rest/tests/test_domains.py index 4d696c51a..ec08b749d 100644 --- a/src/mailman/rest/tests/test_domains.py +++ b/src/mailman/rest/tests/test_domains.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/tests/test_lists.py b/src/mailman/rest/tests/test_lists.py index 7c2182c9c..f4cafa3f3 100644 --- a/src/mailman/rest/tests/test_lists.py +++ b/src/mailman/rest/tests/test_lists.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -21,6 +21,7 @@ from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ + 'TestListArchivers', 'TestLists', 'TestListsMissing', ] @@ -159,3 +160,71 @@ class TestLists(unittest.TestCase): call_api('http://localhost:9001/3.0/lists/ant.example.com', method='DELETE') self.assertEqual(cm.exception.code, 404) + + + +class TestListArchivers(unittest.TestCase): + """Test corner cases for list archivers.""" + + layer = RESTLayer + + def setUp(self): + with transaction(): + self._mlist = create_list('ant@example.com') + + def test_archiver_statuses(self): + resource, response = call_api( + 'http://localhost:9001/3.0/lists/ant.example.com/archivers') + self.assertEqual(response.status, 200) + # Remove the variable data. + resource.pop('http_etag') + self.assertEqual(resource, { + 'mail-archive': True, + 'mhonarc': True, + 'prototype': True, + }) + + def test_archiver_statuses_on_missing_lists(self): + # You cannot get the archiver statuses on a list that doesn't exist. + with self.assertRaises(HTTPError) as cm: + call_api( + 'http://localhost:9001/3.0/lists/bee.example.com/archivers') + self.assertEqual(cm.exception.code, 404) + + def test_patch_status_on_bogus_archiver(self): + # You cannot set the status on an archiver the list doesn't know about. + with self.assertRaises(HTTPError) as cm: + call_api( + 'http://localhost:9001/3.0/lists/ant.example.com/archivers', { + 'bogus-archiver': True, + }, + method='PATCH') + self.assertEqual(cm.exception.code, 400) + self.assertEqual(cm.exception.reason, + 'Unexpected parameters: bogus-archiver') + + def test_put_incomplete_statuses(self): + # PUT requires the full resource representation. This one forgets to + # specify the prototype and mhonarc archiver. + with self.assertRaises(HTTPError) as cm: + call_api( + 'http://localhost:9001/3.0/lists/ant.example.com/archivers', { + 'mail-archive': True, + }, + method='PUT') + self.assertEqual(cm.exception.code, 400) + self.assertEqual(cm.exception.reason, + 'Missing parameters: mhonarc, prototype') + + def test_patch_bogus_status(self): + # Archiver statuses must be interpretable as booleans. + with self.assertRaises(HTTPError) as cm: + call_api( + 'http://localhost:9001/3.0/lists/ant.example.com/archivers', { + 'mail-archive': 'sure', + 'mhonarc': False, + 'prototype': 'no' + }, + method='PATCH') + self.assertEqual(cm.exception.code, 400) + self.assertEqual(cm.exception.reason, 'Invalid boolean value: sure') diff --git a/src/mailman/rest/tests/test_membership.py b/src/mailman/rest/tests/test_membership.py index e3648d17e..037ef36b0 100644 --- a/src/mailman/rest/tests/test_membership.py +++ b/src/mailman/rest/tests/test_membership.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/tests/test_moderation.py b/src/mailman/rest/tests/test_moderation.py index bac62c799..c0ec4755a 100644 --- a/src/mailman/rest/tests/test_moderation.py +++ b/src/mailman/rest/tests/test_moderation.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/tests/test_paginate.py b/src/mailman/rest/tests/test_paginate.py index ab39d0996..0774125bb 100644 --- a/src/mailman/rest/tests/test_paginate.py +++ b/src/mailman/rest/tests/test_paginate.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 by the Free Software Foundation, Inc. +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/tests/test_root.py b/src/mailman/rest/tests/test_root.py index 4cf12da30..96a41edf7 100644 --- a/src/mailman/rest/tests/test_root.py +++ b/src/mailman/rest/tests/test_root.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/tests/test_users.py b/src/mailman/rest/tests/test_users.py index 3757edb70..80bf9526d 100644 --- a/src/mailman/rest/tests/test_users.py +++ b/src/mailman/rest/tests/test_users.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/users.py b/src/mailman/rest/users.py index 6826c92b6..731e7e5d3 100644 --- a/src/mailman/rest/users.py +++ b/src/mailman/rest/users.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/validator.py b/src/mailman/rest/validator.py index 2d178226f..72695d551 100644 --- a/src/mailman/rest/validator.py +++ b/src/mailman/rest/validator.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rest/wsgiapp.py b/src/mailman/rest/wsgiapp.py index 9cdac041b..b7ad3d698 100644 --- a/src/mailman/rest/wsgiapp.py +++ b/src/mailman/rest/wsgiapp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -17,7 +17,7 @@ """Basic WSGI Application object for REST server.""" -from __future__ import absolute_import, unicode_literals +from __future__ import absolute_import, print_function, unicode_literals __metaclass__ = type __all__ = [ diff --git a/src/mailman/rules/administrivia.py b/src/mailman/rules/administrivia.py index b09c240e4..9d30d8cf0 100644 --- a/src/mailman/rules/administrivia.py +++ b/src/mailman/rules/administrivia.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/any.py b/src/mailman/rules/any.py index 804aa8fa9..e5f80fbc4 100644 --- a/src/mailman/rules/any.py +++ b/src/mailman/rules/any.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/approved.py b/src/mailman/rules/approved.py index f6dc82dd5..2839ffef4 100644 --- a/src/mailman/rules/approved.py +++ b/src/mailman/rules/approved.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/emergency.py b/src/mailman/rules/emergency.py index a79b8ebe7..ba7abe562 100644 --- a/src/mailman/rules/emergency.py +++ b/src/mailman/rules/emergency.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/implicit_dest.py b/src/mailman/rules/implicit_dest.py index 339485089..8bfb0d2e0 100644 --- a/src/mailman/rules/implicit_dest.py +++ b/src/mailman/rules/implicit_dest.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/loop.py b/src/mailman/rules/loop.py index 0bb8e0c74..145af8b34 100644 --- a/src/mailman/rules/loop.py +++ b/src/mailman/rules/loop.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/max_recipients.py b/src/mailman/rules/max_recipients.py index c24a19d1d..3b1d4f0c5 100644 --- a/src/mailman/rules/max_recipients.py +++ b/src/mailman/rules/max_recipients.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/max_size.py b/src/mailman/rules/max_size.py index 18ace1b1c..1e2b46184 100644 --- a/src/mailman/rules/max_size.py +++ b/src/mailman/rules/max_size.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/moderation.py b/src/mailman/rules/moderation.py index 0485f3018..46ed242fa 100644 --- a/src/mailman/rules/moderation.py +++ b/src/mailman/rules/moderation.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -87,6 +87,10 @@ class NonmemberModeration: assert address is not None, ( 'Posting address is not registered: {0}'.format(sender)) mlist.subscribe(address, MemberRole.nonmember) + ## # If a member is found, the member-moderation rule takes precedence. + for sender in msg.senders: + if mlist.members.get_member(sender) is not None: + return False # Do nonmember moderation check. for sender in msg.senders: nonmember = mlist.nonmembers.get_member(sender) diff --git a/src/mailman/rules/news_moderation.py b/src/mailman/rules/news_moderation.py index 32b616bf7..c4372eb80 100644 --- a/src/mailman/rules/news_moderation.py +++ b/src/mailman/rules/news_moderation.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/no_subject.py b/src/mailman/rules/no_subject.py index 3a387d954..8f01f0c15 100644 --- a/src/mailman/rules/no_subject.py +++ b/src/mailman/rules/no_subject.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/suspicious.py b/src/mailman/rules/suspicious.py index 55a9028c8..1841ed69e 100644 --- a/src/mailman/rules/suspicious.py +++ b/src/mailman/rules/suspicious.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/tests/test_approved.py b/src/mailman/rules/tests/test_approved.py index 27b4a106f..e7f122410 100644 --- a/src/mailman/rules/tests/test_approved.py +++ b/src/mailman/rules/tests/test_approved.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/rules/tests/test_moderation.py b/src/mailman/rules/tests/test_moderation.py new file mode 100644 index 000000000..c0c3cf417 --- /dev/null +++ b/src/mailman/rules/tests/test_moderation.py @@ -0,0 +1,78 @@ +# Copyright (C) 2014 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman 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 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman 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 +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""Test the `member-moderation` and `nonmember-moderation` rules.""" + +from __future__ import absolute_import, print_function, unicode_literals + +__metaclass__ = type +__all__ = [ + 'TestModeration', + ] + + +import unittest + +from mailman.app.lifecycle import create_list +from mailman.interfaces.member import MemberRole +from mailman.interfaces.usermanager import IUserManager +from mailman.rules import moderation +from mailman.testing.helpers import specialized_message_from_string as mfs +from mailman.testing.layers import ConfigLayer +from zope.component import getUtility + + + +class TestModeration(unittest.TestCase): + """Test the approved handler.""" + + layer = ConfigLayer + + def setUp(self): + self._mlist = create_list('test@example.com') + + def test_member_and_nonmember(self): + user_manager = getUtility(IUserManager) + anne = user_manager.create_address('anne@example.com') + user_manager.create_address('bill@example.com') + self._mlist.subscribe(anne, MemberRole.member) + rule = moderation.NonmemberModeration() + msg = mfs("""\ +From: anne@example.com +Sender: bill@example.com +To: test@example.com +Subject: A test message +Message-ID: <ant> +MIME-Version: 1.0 + +A message body. +""") + # Both Anne and Bill are in the message's senders list. + self.assertIn('anne@example.com', msg.senders) + self.assertIn('bill@example.com', msg.senders) + # The NonmemberModeration rule should *not* hit, because even though + # Bill is in the list of senders he is not a member of the mailing + # list. Anne is also in the list of senders and she *is* a member, so + # she takes precedence. + result = rule.check(self._mlist, msg, {}) + self.assertFalse(result, 'NonmemberModeration rule should not hit') + # After the rule runs, Bill becomes a non-member. + bill_member = self._mlist.nonmembers.get_member('bill@example.com') + self.assertIsNotNone(bill_member) + # Bill is not a member. + bill_member = self._mlist.members.get_member('bill@example.com') + self.assertIsNone(bill_member) diff --git a/src/mailman/rules/truth.py b/src/mailman/rules/truth.py index f94f9a09e..d50b5eae4 100644 --- a/src/mailman/rules/truth.py +++ b/src/mailman/rules/truth.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/archive.py b/src/mailman/runners/archive.py index f18bd7c61..b49f5c265 100644 --- a/src/mailman/runners/archive.py +++ b/src/mailman/runners/archive.py @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2000-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -36,6 +36,7 @@ from mailman.config import config from mailman.core.runner import Runner from mailman.interfaces.archiver import ClobberDate from mailman.utilities.datetime import RFC822_DATE_FMT, now +from mailman.interfaces.mailinglist import IListArchiverSet log = logging.getLogger('mailman.error') @@ -90,7 +91,12 @@ class ArchiveRunner(Runner): def _dispose(self, mlist, msg, msgdata): received_time = msgdata.get('received_time', now(strip_tzinfo=False)) - for archiver in config.archivers: + archiver_set = IListArchiverSet(mlist) + for archiver in archiver_set.archivers: + # The archiver is disabled if either the list-specific or + # site-wide archiver is disabled. + if not archiver.is_enabled: + continue msg_copy = copy.deepcopy(msg) if _should_clobber(msg, msgdata, archiver.name): original_date = msg_copy['date'] @@ -102,6 +108,6 @@ class ArchiveRunner(Runner): # A problem in one archiver should not prevent other archivers # from running. try: - archiver.archive_message(mlist, msg_copy) + archiver.system_archiver.archive_message(mlist, msg_copy) except Exception: log.exception('Broken archiver: %s' % archiver.name) diff --git a/src/mailman/runners/bounce.py b/src/mailman/runners/bounce.py index ff1db6bfb..9312a9158 100644 --- a/src/mailman/runners/bounce.py +++ b/src/mailman/runners/bounce.py @@ -1,4 +1,4 @@ -# Copyright (C) 2001-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2001-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/command.py b/src/mailman/runners/command.py index 38da86c1b..027791fbf 100644 --- a/src/mailman/runners/command.py +++ b/src/mailman/runners/command.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/digest.py b/src/mailman/runners/digest.py index c917e3c74..b48dfba13 100644 --- a/src/mailman/runners/digest.py +++ b/src/mailman/runners/digest.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/docs/digester.rst b/src/mailman/runners/docs/digester.rst index d0231a895..96e8739e3 100644 --- a/src/mailman/runners/docs/digester.rst +++ b/src/mailman/runners/docs/digester.rst @@ -10,6 +10,7 @@ starts by a number of messages being posted to the mailing list. >>> mlist.digest_size_threshold = 0.6 >>> mlist.volume = 1 >>> mlist.next_digest_number = 1 + >>> mlist.send_welcome_message = False >>> from string import Template >>> process = config.handlers['to-digest'].process diff --git a/src/mailman/runners/incoming.py b/src/mailman/runners/incoming.py index 0298a15a7..d75469a5e 100644 --- a/src/mailman/runners/incoming.py +++ b/src/mailman/runners/incoming.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/lmtp.py b/src/mailman/runners/lmtp.py index 2bc3af979..7560fd962 100644 --- a/src/mailman/runners/lmtp.py +++ b/src/mailman/runners/lmtp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/nntp.py b/src/mailman/runners/nntp.py index de809b045..493f8d09a 100644 --- a/src/mailman/runners/nntp.py +++ b/src/mailman/runners/nntp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2000-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/outgoing.py b/src/mailman/runners/outgoing.py index 554426d70..db0d847c4 100644 --- a/src/mailman/runners/outgoing.py +++ b/src/mailman/runners/outgoing.py @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2000-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/pipeline.py b/src/mailman/runners/pipeline.py index 19ca6329f..13226c6fc 100644 --- a/src/mailman/runners/pipeline.py +++ b/src/mailman/runners/pipeline.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/rest.py b/src/mailman/runners/rest.py index 67987805d..fb21bf534 100644 --- a/src/mailman/runners/rest.py +++ b/src/mailman/runners/rest.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/retry.py b/src/mailman/runners/retry.py index 3f1372f7e..41220b989 100644 --- a/src/mailman/runners/retry.py +++ b/src/mailman/runners/retry.py @@ -1,4 +1,4 @@ -# Copyright (C) 2003-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2003-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_archiver.py b/src/mailman/runners/tests/test_archiver.py index 80a676dfd..e11b6c805 100644 --- a/src/mailman/runners/tests/test_archiver.py +++ b/src/mailman/runners/tests/test_archiver.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -34,6 +34,7 @@ from zope.interface import implementer from mailman.app.lifecycle import create_list from mailman.config import config from mailman.interfaces.archiver import IArchiver +from mailman.interfaces.mailinglist import IListArchiverSet from mailman.runners.archive import ArchiveRunner from mailman.testing.helpers import ( configuration, @@ -99,6 +100,7 @@ X-Message-ID-Hash: 4CMWUN6BHVCMHMDAOSJZ2Q72G5M32MWB First post! """) self._runner = make_testable_runner(ArchiveRunner) + IListArchiverSet(self._mlist).get('dummy').is_enabled = True def tearDown(self): config.pop('dummy') @@ -237,3 +239,16 @@ First post! self.assertEqual(archived['message-id'], '<first>') self.assertEqual(archived['date'], 'Mon, 01 Aug 2005 07:49:23 +0000') self.assertEqual(archived['x-original-date'], None) + + @configuration('archiver.dummy', enable='yes') + def test_disable_all_list_archivers(self): + # Let's disable all the archivers for the mailing list, but not the + # global archivers. No messages will get archived. + for archiver in IListArchiverSet(self._mlist).archivers: + archiver.is_enabled = False + config.db.store.commit() + self._archiveq.enqueue( + self._msg, {}, + listname=self._mlist.fqdn_listname) + self._runner.run() + self.assertEqual(os.listdir(config.MESSAGES_DIR), []) diff --git a/src/mailman/runners/tests/test_bounce.py b/src/mailman/runners/tests/test_bounce.py index fd890aed1..315a81c22 100644 --- a/src/mailman/runners/tests/test_bounce.py +++ b/src/mailman/runners/tests/test_bounce.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -57,6 +57,7 @@ class TestBounceRunner(unittest.TestCase): def setUp(self): self._mlist = create_list('test@example.com') + self._mlist.send_welcome_message = False self._bounceq = config.switchboards['bounces'] self._runner = make_testable_runner(BounceRunner, 'bounces') self._anne = getUtility(IUserManager).create_address( diff --git a/src/mailman/runners/tests/test_confirm.py b/src/mailman/runners/tests/test_confirm.py index a92682500..40fae368f 100644 --- a/src/mailman/runners/tests/test_confirm.py +++ b/src/mailman/runners/tests/test_confirm.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_incoming.py b/src/mailman/runners/tests/test_incoming.py index 53e281640..9830fedb9 100644 --- a/src/mailman/runners/tests/test_incoming.py +++ b/src/mailman/runners/tests/test_incoming.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_join.py b/src/mailman/runners/tests/test_join.py index d111fb3a7..fbea9e661 100644 --- a/src/mailman/runners/tests/test_join.py +++ b/src/mailman/runners/tests/test_join.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -52,6 +52,7 @@ class TestJoin(unittest.TestCase): def setUp(self): self._mlist = create_list('test@example.com') + self._mlist.send_welcome_message = False self._commandq = config.switchboards['command'] self._runner = make_testable_runner(CommandRunner, 'command') diff --git a/src/mailman/runners/tests/test_lmtp.py b/src/mailman/runners/tests/test_lmtp.py index bd30fc7aa..26308548c 100644 --- a/src/mailman/runners/tests/test_lmtp.py +++ b/src/mailman/runners/tests/test_lmtp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_nntp.py b/src/mailman/runners/tests/test_nntp.py index bd8540c43..3570d1a6f 100644 --- a/src/mailman/runners/tests/test_nntp.py +++ b/src/mailman/runners/tests/test_nntp.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_outgoing.py b/src/mailman/runners/tests/test_outgoing.py index c897fc013..feff2799a 100644 --- a/src/mailman/runners/tests/test_outgoing.py +++ b/src/mailman/runners/tests/test_outgoing.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_owner.py b/src/mailman/runners/tests/test_owner.py index 71c09fa28..6c68e91cc 100644 --- a/src/mailman/runners/tests/test_owner.py +++ b/src/mailman/runners/tests/test_owner.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_pipeline.py b/src/mailman/runners/tests/test_pipeline.py index 54aaca71f..50ec6cb9a 100644 --- a/src/mailman/runners/tests/test_pipeline.py +++ b/src/mailman/runners/tests/test_pipeline.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_rest.py b/src/mailman/runners/tests/test_rest.py index a7b51f720..bbe026ad6 100644 --- a/src/mailman/runners/tests/test_rest.py +++ b/src/mailman/runners/tests/test_rest.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 by the Free Software Foundation, Inc. +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/tests/test_retry.py b/src/mailman/runners/tests/test_retry.py index 99e87235e..e4f021e45 100644 --- a/src/mailman/runners/tests/test_retry.py +++ b/src/mailman/runners/tests/test_retry.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/runners/virgin.py b/src/mailman/runners/virgin.py index c3378a13a..0f91d61af 100644 --- a/src/mailman/runners/virgin.py +++ b/src/mailman/runners/virgin.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/styles/base.py b/src/mailman/styles/base.py index 243937bc6..d83b2e2a5 100644 --- a/src/mailman/styles/base.py +++ b/src/mailman/styles/base.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/styles/default.py b/src/mailman/styles/default.py index 28a4cb721..b12999f0e 100644 --- a/src/mailman/styles/default.py +++ b/src/mailman/styles/default.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/styles/manager.py b/src/mailman/styles/manager.py index 12d416646..397902c17 100644 --- a/src/mailman/styles/manager.py +++ b/src/mailman/styles/manager.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/styles/tests/test_styles.py b/src/mailman/styles/tests/test_styles.py index 277623ff8..1fb7a8410 100644 --- a/src/mailman/styles/tests/test_styles.py +++ b/src/mailman/styles/tests/test_styles.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/testing/documentation.py b/src/mailman/testing/documentation.py index b1cc36f91..d204a008f 100644 --- a/src/mailman/testing/documentation.py +++ b/src/mailman/testing/documentation.py @@ -1,4 +1,4 @@ -# Copyright (C) 2007-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2007-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/testing/helpers.py b/src/mailman/testing/helpers.py index 8201f952a..1ef9e964e 100644 --- a/src/mailman/testing/helpers.py +++ b/src/mailman/testing/helpers.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -46,6 +46,7 @@ import mock import time import uuid import errno +import shutil import signal import socket import logging @@ -326,6 +327,8 @@ def call_api(url, data=None, method=None, username=None, password=None): else: method = 'POST' method = method.upper() + if method in ('POST', 'PUT', 'PATCH') and data is None: + data = urlencode({}, doseq=True) basic_auth = '{0}:{1}'.format( (config.webservice.admin_user if username is None else username), (config.webservice.admin_pass if password is None else password)) @@ -478,6 +481,11 @@ def reset_the_world(): with transaction(): for message in message_store.messages: message_store.delete_message(message['message-id']) + # Delete any other residual messages. + for dirpath, dirnames, filenames in os.walk(config.MESSAGES_DIR): + for filename in filenames: + os.remove(os.path.join(dirpath, filename)) + shutil.rmtree(dirpath) # Reset the global style manager. getUtility(IStyleManager).populate() # Remove all dynamic header-match rules. diff --git a/src/mailman/testing/i18n.py b/src/mailman/testing/i18n.py index ec2b93b51..310815917 100644 --- a/src/mailman/testing/i18n.py +++ b/src/mailman/testing/i18n.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/testing/layers.py b/src/mailman/testing/layers.py index 2d2552f93..eb51e309f 100644 --- a/src/mailman/testing/layers.py +++ b/src/mailman/testing/layers.py @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/testing/mailman-xx.po b/src/mailman/testing/mailman-xx.po index 4945eb779..a1351b6e3 100644 --- a/src/mailman/testing/mailman-xx.po +++ b/src/mailman/testing/mailman-xx.po @@ -1,5 +1,5 @@ # Test catalog for Freedonia (xx) -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. msgid "" msgstr "" "Project-Id-Version: mailman\n" diff --git a/src/mailman/testing/mta.py b/src/mailman/testing/mta.py index 5349d2b62..7481e0093 100644 --- a/src/mailman/testing/mta.py +++ b/src/mailman/testing/mta.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/testing/nose.py b/src/mailman/testing/nose.py index 8ac85a756..8fe7017c0 100644 --- a/src/mailman/testing/nose.py +++ b/src/mailman/testing/nose.py @@ -1,4 +1,4 @@ -# Copyright (C) 2013 by the Free Software Foundation, Inc. +# Copyright (C) 2013-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # @@ -67,15 +67,19 @@ class NosePlugin(Plugin): return # Does the pattern match the fully qualified class name? for pattern in self.patterns: - full_name = '{}.{}'.format( + full_class_name = '{}.{}'.format( event.testCase.__module__, event.testCase.__name__) - if re.search(pattern, full_name): + if re.search(pattern, full_class_name): # Don't suppress this test class. return names = filter(event.isTestMethod, dir(event.testCase)) for name in names: + full_test_name = '{}.{}.{}'.format( + event.testCase.__module__, + event.testCase.__name__, + name) for pattern in self.patterns: - if re.search(pattern, name): + if re.search(pattern, full_test_name): break else: event.excludedNames.append(name) diff --git a/src/mailman/testing/testing.cfg b/src/mailman/testing/testing.cfg index 2c38322d5..fc76aa361 100644 --- a/src/mailman/testing/testing.cfg +++ b/src/mailman/testing/testing.cfg @@ -1,4 +1,4 @@ -# Copyright (C) 2008-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2008-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/tests/test_configfile.py b/src/mailman/tests/test_configfile.py index f8577d176..b4d169ba4 100644 --- a/src/mailman/tests/test_configfile.py +++ b/src/mailman/tests/test_configfile.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/datetime.py b/src/mailman/utilities/datetime.py index 5eb430005..37317d3f1 100644 --- a/src/mailman/utilities/datetime.py +++ b/src/mailman/utilities/datetime.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/email.py b/src/mailman/utilities/email.py index 5ccfa104b..c86ce0913 100644 --- a/src/mailman/utilities/email.py +++ b/src/mailman/utilities/email.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/filesystem.py b/src/mailman/utilities/filesystem.py index df9a21355..545b88931 100644 --- a/src/mailman/utilities/filesystem.py +++ b/src/mailman/utilities/filesystem.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/i18n.py b/src/mailman/utilities/i18n.py index 7c2ae6877..40dce936b 100644 --- a/src/mailman/utilities/i18n.py +++ b/src/mailman/utilities/i18n.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/importer.py b/src/mailman/utilities/importer.py index 52f454334..cf22af24f 100644 --- a/src/mailman/utilities/importer.py +++ b/src/mailman/utilities/importer.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/interact.py b/src/mailman/utilities/interact.py index 900c5d129..9aa0e2491 100644 --- a/src/mailman/utilities/interact.py +++ b/src/mailman/utilities/interact.py @@ -1,4 +1,4 @@ -# Copyright (C) 2006-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2006-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/mailbox.py b/src/mailman/utilities/mailbox.py index 69c93e760..306ac389c 100644 --- a/src/mailman/utilities/mailbox.py +++ b/src/mailman/utilities/mailbox.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/modules.py b/src/mailman/utilities/modules.py index 65e4f03ce..414af23ca 100644 --- a/src/mailman/utilities/modules.py +++ b/src/mailman/utilities/modules.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/passwords.py b/src/mailman/utilities/passwords.py index 938c5aaca..6fb7f08c0 100644 --- a/src/mailman/utilities/passwords.py +++ b/src/mailman/utilities/passwords.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/string.py b/src/mailman/utilities/string.py index 98ec95864..9f7a1dda9 100644 --- a/src/mailman/utilities/string.py +++ b/src/mailman/utilities/string.py @@ -1,4 +1,4 @@ -# Copyright (C) 2009-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2009-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/tests/test_email.py b/src/mailman/utilities/tests/test_email.py index 827661187..1448fb32b 100644 --- a/src/mailman/utilities/tests/test_email.py +++ b/src/mailman/utilities/tests/test_email.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/tests/test_import.py b/src/mailman/utilities/tests/test_import.py index a81f552f6..0dcf1959b 100644 --- a/src/mailman/utilities/tests/test_import.py +++ b/src/mailman/utilities/tests/test_import.py @@ -1,4 +1,4 @@ -# Copyright (C) 2010-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2010-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/tests/test_passwords.py b/src/mailman/utilities/tests/test_passwords.py index 3bfb7681e..0dd49cb85 100644 --- a/src/mailman/utilities/tests/test_passwords.py +++ b/src/mailman/utilities/tests/test_passwords.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2012-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/tests/test_templates.py b/src/mailman/utilities/tests/test_templates.py index 0d41a058b..6507bf8e5 100644 --- a/src/mailman/utilities/tests/test_templates.py +++ b/src/mailman/utilities/tests/test_templates.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/tests/test_wrap.py b/src/mailman/utilities/tests/test_wrap.py index e3d77910d..8d756e156 100644 --- a/src/mailman/utilities/tests/test_wrap.py +++ b/src/mailman/utilities/tests/test_wrap.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/utilities/uid.py b/src/mailman/utilities/uid.py index 8ab7bc39a..c1df36789 100644 --- a/src/mailman/utilities/uid.py +++ b/src/mailman/utilities/uid.py @@ -1,4 +1,4 @@ -# Copyright (C) 2011-2013 by the Free Software Foundation, Inc. +# Copyright (C) 2011-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # diff --git a/src/mailman/version.py b/src/mailman/version.py index 51c836d8b..6be6be6b6 100644 --- a/src/mailman/version.py +++ b/src/mailman/version.py @@ -1,4 +1,4 @@ -# Copyright (C) 1998-2013 by the Free Software Foundation, Inc. +# Copyright (C) 1998-2014 by the Free Software Foundation, Inc. # # This file is part of GNU Mailman. # |
