summaryrefslogtreecommitdiff
path: root/src/mailman/rest
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/rest')
-rw-r--r--src/mailman/rest/addresses.py2
-rw-r--r--src/mailman/rest/configuration.py2
-rw-r--r--src/mailman/rest/docs/__init__.py2
-rw-r--r--src/mailman/rest/docs/helpers.rst1
-rw-r--r--src/mailman/rest/docs/lists.rst58
-rw-r--r--src/mailman/rest/domains.py2
-rw-r--r--src/mailman/rest/helpers.py2
-rw-r--r--src/mailman/rest/lists.py71
-rw-r--r--src/mailman/rest/members.py2
-rw-r--r--src/mailman/rest/moderation.py2
-rw-r--r--src/mailman/rest/preferences.py2
-rw-r--r--src/mailman/rest/root.py2
-rw-r--r--src/mailman/rest/templates.py2
-rw-r--r--src/mailman/rest/tests/test_addresses.py2
-rw-r--r--src/mailman/rest/tests/test_domains.py2
-rw-r--r--src/mailman/rest/tests/test_lists.py71
-rw-r--r--src/mailman/rest/tests/test_membership.py2
-rw-r--r--src/mailman/rest/tests/test_moderation.py2
-rw-r--r--src/mailman/rest/tests/test_paginate.py2
-rw-r--r--src/mailman/rest/tests/test_root.py2
-rw-r--r--src/mailman/rest/tests/test_users.py2
-rw-r--r--src/mailman/rest/users.py2
-rw-r--r--src/mailman/rest/validator.py2
-rw-r--r--src/mailman/rest/wsgiapp.py4
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__ = [