diff options
Diffstat (limited to 'src/mailman/rest')
24 files changed, 219 insertions, 24 deletions
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__ = [ |
