summaryrefslogtreecommitdiff
path: root/src/mailman/rest/docs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/rest/docs')
-rw-r--r--src/mailman/rest/docs/basic.rst70
-rw-r--r--src/mailman/rest/docs/configuration.rst3
-rw-r--r--src/mailman/rest/docs/domains.rst7
-rw-r--r--src/mailman/rest/docs/helpers.rst64
-rw-r--r--src/mailman/rest/docs/preferences.rst20
5 files changed, 61 insertions, 103 deletions
diff --git a/src/mailman/rest/docs/basic.rst b/src/mailman/rest/docs/basic.rst
index 51b287c90..42e5379ad 100644
--- a/src/mailman/rest/docs/basic.rst
+++ b/src/mailman/rest/docs/basic.rst
@@ -7,70 +7,48 @@ Mailman exposes a REST HTTP server for administrative control.
The server listens for connections on a configurable host name and port.
It is always protected by HTTP basic authentication using a single global
-username and password. The credentials are set in the webservice section
-of the config using the admin_user and admin_pass properties.
+user name and password. The credentials are set in the `[webservice]` section
+of the configuration using the `admin_user` and `admin_pass` properties.
Because the REST server has full administrative access, it should always be
run only on localhost, unless you really know what you're doing. In addition
-you should set the username and password to secure values and distribute them
+you should set the user name and password to secure values and distribute them
to any REST clients with reasonable precautions.
The Mailman major and minor version numbers are in the URL.
-System information can be retrieved from the server. By default JSON is
-returned.
- >>> dump_json('http://localhost:9001/3.0/system')
- http_etag: "..."
- mailman_version: GNU Mailman 3.0... (...)
- python_version: ...
- self_link: http://localhost:9001/3.0/system
-
-
-Non-existent links
-==================
-
-When you try to access a link that doesn't exist, you get the appropriate HTTP
-404 Not Found error.
-
- >>> dump_json('http://localhost:9001/3.0/does-not-exist')
- Traceback (most recent call last):
- ...
- HTTPError: HTTP Error 404: 404 Not Found
-
-
-Invalid credentials
-===================
+Credentials
+===========
-When you try to access the REST server using invalid credentials you will get
-an appropriate HTTP 401 Unauthorized error.
-::
+When the `Authorization` header contains the proper creditials, the request
+succeeds.
>>> from base64 import b64encode
- >>> auth = b64encode('baduser:badpass')
-
- >>> url = 'http://localhost:9001/3.0/system'
+ >>> from httplib2 import Http
+ >>> auth = b64encode('{0}:{1}'.format(config.webservice.admin_user,
+ ... config.webservice.admin_pass))
>>> headers = {
... 'Content-Type': 'application/x-www-form-urlencode',
... 'Authorization': 'Basic ' + auth,
... }
-
- >>> from httplib2 import Http
- >>> response, content = Http().request(url, 'GET', None, headers)
- >>> print(content)
- 401 Unauthorized
- <BLANKLINE>
- User is not authorized for the REST API
- <BLANKLINE>
-
-But with the right headers, the request succeeds.
-
- >>> auth = b64encode('{0}:{1}'.format(config.webservice.admin_user,
- ... config.webservice.admin_pass))
- >>> headers['Authorization'] = 'Basic ' + auth
+ >>> url = 'http://localhost:9001/3.0/system'
>>> response, content = Http().request(url, 'GET', None, headers)
>>> print(response.status)
200
+Basic information
+=================
+
+System information can be retrieved from the server, in the form of a JSON
+encoded response.
+
+ >>> dump_json('http://localhost:9001/3.0/system')
+ http_etag: "..."
+ mailman_version: GNU Mailman 3.0... (...)
+ python_version: ...
+ self_link: http://localhost:9001/3.0/system
+
+
.. _REST: http://en.wikipedia.org/wiki/REST
diff --git a/src/mailman/rest/docs/configuration.rst b/src/mailman/rest/docs/configuration.rst
index 53ad172e9..841ab3c27 100644
--- a/src/mailman/rest/docs/configuration.rst
+++ b/src/mailman/rest/docs/configuration.rst
@@ -73,9 +73,8 @@ Not all of the readable attributes can be set through the web interface. The
ones that can, can either be set via ``PUT`` or ``PATCH``. ``PUT`` changes
all the writable attributes in one request.
-When using PUT, all writable attributes must be included.
+When using ``PUT``, all writable attributes must be included.
- >>> from mailman.interfaces.action import Action
>>> dump_json('http://localhost:9001/3.0/lists/'
... 'ant@example.com/config',
... dict(
diff --git a/src/mailman/rest/docs/domains.rst b/src/mailman/rest/docs/domains.rst
index 92c73ffbf..b28326f73 100644
--- a/src/mailman/rest/docs/domains.rst
+++ b/src/mailman/rest/docs/domains.rst
@@ -110,13 +110,6 @@ The information for a single domain is available by following one of the
self_link: http://localhost:9001/3.0/domains/lists.example.net
url_host: example.net
-But we get a 404 for a non-existent domain.
-
- >>> dump_json('http://localhost:9001/3.0/domains/does-not-exist')
- Traceback (most recent call last):
- ...
- HTTPError: HTTP Error 404: 404 Not Found
-
You can also list all the mailing lists for a given domain. At first, the
example.com domain does not contain any mailing lists.
::
diff --git a/src/mailman/rest/docs/helpers.rst b/src/mailman/rest/docs/helpers.rst
index 0acbb5f45..5bcf5cad4 100644
--- a/src/mailman/rest/docs/helpers.rst
+++ b/src/mailman/rest/docs/helpers.rst
@@ -62,19 +62,19 @@ dictionary after tagging, since that's almost always what you want.
neil : drums
-POST unpacking
-==============
+POST and PUT unpacking
+======================
-Another helper unpacks ``POST`` request variables, validating and converting
-their values.
+Another helper unpacks ``POST`` and ``PUT`` request variables, validating and
+converting their values.
::
>>> from mailman.rest.validator import Validator
>>> validator = Validator(one=int, two=unicode, three=bool)
>>> class FakeRequest:
- ... POST = {}
- >>> FakeRequest.POST = dict(one='1', two='two', three='yes')
+ ... params = None
+ >>> FakeRequest.params = dict(one='1', two='two', three='yes')
On valid input, the validator can be used as a ``**keyword`` argument.
@@ -85,7 +85,7 @@ On valid input, the validator can be used as a ``**keyword`` argument.
On invalid input, an exception is raised.
- >>> FakeRequest.POST['one'] = 'hello'
+ >>> FakeRequest.params['one'] = 'hello'
>>> print_request(**validator(FakeRequest))
Traceback (most recent call last):
...
@@ -93,7 +93,7 @@ On invalid input, an exception is raised.
On missing input, an exception is raised.
- >>> del FakeRequest.POST['one']
+ >>> del FakeRequest.params['one']
>>> print_request(**validator(FakeRequest))
Traceback (most recent call last):
...
@@ -101,7 +101,7 @@ On missing input, an exception is raised.
If more than one key is missing, it will be reflected in the error message.
- >>> del FakeRequest.POST['two']
+ >>> del FakeRequest.params['two']
>>> print_request(**validator(FakeRequest))
Traceback (most recent call last):
...
@@ -109,8 +109,8 @@ If more than one key is missing, it will be reflected in the error message.
Extra keys are also not allowed.
- >>> FakeRequest.POST = dict(one='1', two='two', three='yes',
- ... four='', five='')
+ >>> FakeRequest.params = dict(one='1', two='two', three='yes',
+ ... four='', five='')
>>> print_request(**validator(FakeRequest))
Traceback (most recent call last):
...
@@ -123,25 +123,25 @@ However, if optional keys are missing, it's okay.
... four=int, five=int,
... _optional=('four', 'five'))
- >>> FakeRequest.POST = dict(one='1', two='two', three='yes',
- ... four='4', five='5')
+ >>> FakeRequest.params = dict(one='1', two='two', three='yes',
+ ... four='4', five='5')
>>> def print_request(one, two, three, four=None, five=None):
... print(repr(one), repr(two), repr(three), repr(four), repr(five))
>>> print_request(**validator(FakeRequest))
1 u'two' True 4 5
- >>> del FakeRequest.POST['four']
+ >>> del FakeRequest.params['four']
>>> print_request(**validator(FakeRequest))
1 u'two' True None 5
- >>> del FakeRequest.POST['five']
+ >>> del FakeRequest.params['five']
>>> print_request(**validator(FakeRequest))
1 u'two' True None None
But if the optional values are present, they must of course also be valid.
- >>> FakeRequest.POST = dict(one='1', two='two', three='yes',
- ... four='no', five='maybe')
+ >>> FakeRequest.params = dict(one='1', two='two', three='yes',
+ ... four='no', five='maybe')
>>> print_request(**validator(FakeRequest))
Traceback (most recent call last):
...
@@ -157,12 +157,17 @@ such form data. Specifically, when a key shows up multiple times in the form
data, a list is given to the validator.
::
- # Of course we can't use a normal dictionary, but webob has a useful data
- # type we can use.
- >>> from webob.multidict import MultiDict
- >>> form_data = MultiDict(one='1', many='3')
- >>> form_data.add('many', '4')
- >>> form_data.add('many', '5')
+ # We can't use a normal dictionary because we'll have multiple keys, but
+ # the validator only wants to call .items() on the object.
+ >>> class MultiDict:
+ ... def __init__(self, *params): self.values = list(params)
+ ... def items(self): return iter(self.values)
+ >>> form_data = MultiDict(
+ ... ('one', '1'),
+ ... ('many', '3'),
+ ... ('many', '4'),
+ ... ('many', '5'),
+ ... )
This is a validation function that ensures the value is a list.
@@ -181,7 +186,7 @@ This is a validation function that ensure the value is *not* a list.
And a validator to pull it all together.
>>> validator = Validator(one=must_be_scalar, many=must_be_list)
- >>> FakeRequest.POST = form_data
+ >>> FakeRequest.params = form_data
>>> values = validator(FakeRequest)
>>> print(values['one'])
1
@@ -191,11 +196,12 @@ And a validator to pull it all together.
The list values are guaranteed to be in the same order they show up in the
form data.
- >>> from webob.multidict import MultiDict
- >>> form_data = MultiDict(one='1', many='3')
- >>> form_data.add('many', '5')
- >>> form_data.add('many', '4')
- >>> FakeRequest.POST = form_data
+ >>> FakeRequest.params = MultiDict(
+ ... ('one', '1'),
+ ... ('many', '3'),
+ ... ('many', '5'),
+ ... ('many', '4'),
+ ... )
>>> values = validator(FakeRequest)
>>> print(values['one'])
1
diff --git a/src/mailman/rest/docs/preferences.rst b/src/mailman/rest/docs/preferences.rst
index f4839b1f4..b9332c954 100644
--- a/src/mailman/rest/docs/preferences.rst
+++ b/src/mailman/rest/docs/preferences.rst
@@ -199,21 +199,12 @@ Preferences accessed through this interface are always read only.
receive_own_postings: False
self_link: http://localhost:9001/3.0/members/1/all/preferences
-These preferences cannot be changed.
-
- >>> dump_json('http://localhost:9001/3.0/members/1/all/preferences', {
- ... 'delivery_status': 'enabled',
- ... }, method='PATCH')
- Traceback (most recent call last):
- ...
- HTTPError: HTTP Error 405: 405 Method Not Allowed
-
System preferences
==================
The Mailman system itself has a default set of preference. All preference
-lookups fall back to these values, which are read-only.
+look ups fall back to these values, which are read-only.
>>> dump_json('http://localhost:9001/3.0/system/preferences')
acknowledge_posts: False
@@ -225,12 +216,3 @@ lookups fall back to these values, which are read-only.
receive_list_copy: True
receive_own_postings: True
self_link: http://localhost:9001/3.0/system/preferences
-
-These preferences cannot be changed.
-
- >>> dump_json('http://localhost:9001/3.0/system/preferences', {
- ... 'delivery_status': 'enabled',
- ... }, method='PATCH')
- Traceback (most recent call last):
- ...
- HTTPError: HTTP Error 405: 405 Method Not Allowed