diff options
Diffstat (limited to 'src/mailman/rest')
| -rw-r--r-- | src/mailman/rest/docs/__init__.py | 12 | ||||
| -rw-r--r-- | src/mailman/rest/plugins.py | 76 | ||||
| -rw-r--r-- | src/mailman/rest/root.py | 15 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_systemconf.py | 2 |
4 files changed, 95 insertions, 10 deletions
diff --git a/src/mailman/rest/docs/__init__.py b/src/mailman/rest/docs/__init__.py index 350a6b83e..671ea38d6 100644 --- a/src/mailman/rest/docs/__init__.py +++ b/src/mailman/rest/docs/__init__.py @@ -19,22 +19,13 @@ import threading +from http import HTTPStatus from http.server import BaseHTTPRequestHandler, HTTPServer from mailman.testing.helpers import wait_for_webservice from mailman.testing.layers import RESTLayer from public import public -# New in Python 3.5. -try: - from http import HTTPStatus -except ImportError: # pragma: nocover - class HTTPStatus: - FORBIDDEN = 403 - NOT_FOUND = 404 - OK = 200 - - # We need a web server to vend non-mailman: urls. class TestableHandler(BaseHTTPRequestHandler): # Be quiet. @@ -78,6 +69,7 @@ class HTTPLayer(RESTLayer): cls._thread.join() +# For flufl.testing -- define this doctest's layer. public(layer=HTTPLayer) diff --git a/src/mailman/rest/plugins.py b/src/mailman/rest/plugins.py new file mode 100644 index 000000000..2d61d881c --- /dev/null +++ b/src/mailman/rest/plugins.py @@ -0,0 +1,76 @@ +# Copyright (C) 2010-2017 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/>. + +"""REST for plugins, dynamically proxies requests to plugin's rest_object.""" + +from lazr.config import as_boolean +from mailman.config import config +from mailman.rest.helpers import CollectionMixin, NotFound, etag, okay +from operator import itemgetter +from public import public + + +@public +class AllPlugins(CollectionMixin): + """Read-only list of all plugin configs.""" + + def _resource_as_dict(self, plugin_config): + """See `CollectionMixin`.""" + name, plugin_section = plugin_config + resource = { + 'name': name, + 'class': plugin_section['class'], + 'enabled': as_boolean(plugin_section['enabled']), + } + # Add the path to the plugin's own configuration file, if one was + # given. + plugin_config = plugin_section['configuration'].strip() + if len(plugin_config) > 0: + resource['configuration'] = plugin_config + return resource + + def _get_collection(self, request): + """See `CollectionMixin`.""" + # plugin_configs returns a 2-tuple of (name, section), so sort + # alphabetically on the plugin name. + return sorted(config.plugin_configs, key=itemgetter(0)) + + def on_get(self, request, response): + """/plugins""" + resource = self._make_collection(request) + okay(response, etag(resource)) + + +@public +class APlugin: + """REST proxy to the plugin's rest_object.""" + + def __init__(self, plugin_name): + self._resource = None + if plugin_name in config.plugins: + plugin = config.plugins[plugin_name] + self._resource = plugin.resource + # If the plugin doesn't exist or doesn't provide a resource, just proxy + # to NotFound. + if self._resource is None: + self._resource = NotFound() + + def __getattr__(self, attrib): + return getattr(self._resource, attrib) + + def __dir__(self): + return dir(self._resource) diff --git a/src/mailman/rest/root.py b/src/mailman/rest/root.py index 76289078b..46116aba6 100644 --- a/src/mailman/rest/root.py +++ b/src/mailman/rest/root.py @@ -30,6 +30,7 @@ from mailman.rest.helpers import ( BadRequest, NotFound, child, etag, no_content, not_found, okay) from mailman.rest.lists import AList, AllLists, Styles from mailman.rest.members import AMember, AllMembers, FindMembers +from mailman.rest.plugins import APlugin, AllPlugins from mailman.rest.preferences import ReadOnlyPreferences from mailman.rest.queues import AQueue, AQueueFile, AllQueues from mailman.rest.templates import TemplateFinder @@ -308,6 +309,20 @@ class TopLevel: return BadRequest(), [] @child() + def plugins(self, context, segments): + """/<api>/plugins + /<api>/plugins/<plugin_name> + /<api>/plugins/<plugin_name>/... + """ + if self.api.version_info < (3, 1): + return NotFound(), [] + if len(segments) == 0: + return AllPlugins(), [] + else: + plugin_name = segments.pop(0) + return APlugin(plugin_name), segments + + @child() def bans(self, context, segments): """/<api>/bans /<api>/bans/<email> diff --git a/src/mailman/rest/tests/test_systemconf.py b/src/mailman/rest/tests/test_systemconf.py index f9fe9caa0..91ee9befa 100644 --- a/src/mailman/rest/tests/test_systemconf.py +++ b/src/mailman/rest/tests/test_systemconf.py @@ -168,6 +168,7 @@ class TestSystemConfiguration(unittest.TestCase): 'logging.http', 'logging.locks', 'logging.mischief', + 'logging.plugins', 'logging.root', 'logging.runner', 'logging.smtp', @@ -182,6 +183,7 @@ class TestSystemConfiguration(unittest.TestCase): 'paths.here', 'paths.local', 'paths.testing', + 'plugin.master', 'runner.archive', 'runner.bad', 'runner.bounces', |
