diff options
| author | Barry Warsaw | 2009-12-28 08:11:37 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2009-12-28 08:11:37 -0500 |
| commit | c7074204018693425a1ba9de5129b374d918d8c6 (patch) | |
| tree | ce3d8c56eec4217722f01cd33d20d12b28343860 | |
| parent | ba2c7550b005255f75aaf3396f908cc3ead10032 (diff) | |
| download | mailman-c7074204018693425a1ba9de5129b374d918d8c6.tar.gz mailman-c7074204018693425a1ba9de5129b374d918d8c6.tar.zst mailman-c7074204018693425a1ba9de5129b374d918d8c6.zip | |
| -rw-r--r-- | src/mailman/interfaces/rest.py | 10 | ||||
| -rw-r--r-- | src/mailman/rest/adapters.py | 17 | ||||
| -rw-r--r-- | src/mailman/rest/configure.zcml | 20 | ||||
| -rw-r--r-- | src/mailman/rest/docs/membership.txt | 61 |
4 files changed, 97 insertions, 11 deletions
diff --git a/src/mailman/interfaces/rest.py b/src/mailman/interfaces/rest.py index 83a458c1d..4fbb0f5ef 100644 --- a/src/mailman/interfaces/rest.py +++ b/src/mailman/interfaces/rest.py @@ -21,12 +21,22 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ + 'APIValueError', 'IResolvePathNames', ] +from lazr.restful.declarations import error_status from zope.interface import Interface +from mailman.core.errors import MailmanError + + + +@error_status(400) +class APIValueError(MailmanError, ValueError): + """A `ValueError` from the REST API.""" + class IResolvePathNames(Interface): diff --git a/src/mailman/rest/adapters.py b/src/mailman/rest/adapters.py index ab0279d6e..afa371c5d 100644 --- a/src/mailman/rest/adapters.py +++ b/src/mailman/rest/adapters.py @@ -38,7 +38,7 @@ from mailman.interfaces.domain import IDomainCollection, IDomainManager from mailman.interfaces.listmanager import IListManager, NoSuchListError from mailman.interfaces.member import DeliveryMode, NotAMemberError from mailman.interfaces.membership import ISubscriptionService -from mailman.interfaces.rest import IResolvePathNames +from mailman.interfaces.rest import APIValueError, IResolvePathNames @@ -102,12 +102,15 @@ class SubscriptionService: mlist = getUtility(IListManager).get(fqdn_listname) if mlist is None: raise NoSuchListError(fqdn_listname) - # Convert from string to enum. Allow ValueError exceptions to be - # returned by the API. XXX 2009-12-30 Does lazr.restful intelligently - # handle ValueError? - mode = (DeliveryMode.regular - if delivery_mode is None - else DeliveryMode(delivery_mode)) + # Convert from string to enum. Turn Python's ValueErrors into one + # suitable for the REST API. + try: + mode = (DeliveryMode.regular + if delivery_mode is None + else DeliveryMode(delivery_mode)) + except ValueError: + raise APIValueError( + 'Invalid delivery_mode: {0}'.format(delivery_mode)) if real_name is None: real_name, at, domain = address.partition('@') if len(at) == 0: diff --git a/src/mailman/rest/configure.zcml b/src/mailman/rest/configure.zcml index cf08b331e..b12d42f46 100644 --- a/src/mailman/rest/configure.zcml +++ b/src/mailman/rest/configure.zcml @@ -11,6 +11,7 @@ <webservice:register module="mailman.interfaces.domain" /> <webservice:register module="mailman.interfaces.listmanager" /> <webservice:register module="mailman.interfaces.membership" /> + <webservice:register module="mailman.interfaces.rest" /> <webservice:register module="mailman.interfaces.system" /> <adapter factory="zope.publisher.http.HTTPCharsets" /> @@ -52,11 +53,12 @@ /> <!-- - XXX 2009-12-28 Why is this necessary? NotAMemberError is decorated with - @error_status(400) so it /should/ already be adaptable to - WebServiceExceptionView. For some reason though rest/membership.txt fails - without this. + XXX 2009-12-28 Why are these necessary? NotAMemberError and + AlreadySubscribedError are decorated with @error_status(400) so they + /should/ already be adaptable to WebServiceExceptionView. For some reason + though rest/membership.txt fails without these. --> + <adapter for="mailman.interfaces.member.NotAMemberError lazr.restful.simple.Request" @@ -65,6 +67,16 @@ name="index.html" /> + <adapter + for="mailman.interfaces.member.AlreadySubscribedError + lazr.restful.simple.Request" + provides="zope.interface.Interface" + factory="lazr.restful.error.WebServiceExceptionView" + name="index.html" + /> + + <!-- Utilities --> + <utility factory="mailman.rest.configuration.AdminWebServiceConfiguration" provides="lazr.restful.interfaces.IWebServiceConfiguration" diff --git a/src/mailman/rest/docs/membership.txt b/src/mailman/rest/docs/membership.txt index 4628e6af2..f14bb0203 100644 --- a/src/mailman/rest/docs/membership.txt +++ b/src/mailman/rest/docs/membership.txt @@ -231,6 +231,32 @@ Elly is no longer a member of the mailing list. set([]) +Digest delivery +=============== + +Fred joins the alpha mailing list but wants MIME digest delivery. + + >>> transaction.abort() + >>> dump_json('http://localhost:8001/3.0/members', { + ... 'ws.op': 'join', + ... 'fqdn_listname': 'alpha@example.com', + ... 'address': 'fperson@example.com', + ... 'real_name': 'Fred Person', + ... 'delivery_mode': 'mime_digests', + ... }) + http_etag: ... + resource_type_link: http://localhost:8001/3.0/#member + self_link: http://localhost:8001/3.0/lists/alpha@example.com/member/fperson@example.com + + >>> fred = user_manager.get_user('fperson@example.com') + >>> memberships = list(fred.memberships.members) + >>> len(memberships) + 1 + >>> memberships[0] + <Member: Fred Person <fperson@example.com> + on alpha@example.com as MemberRole.member> + + Corner cases ============ @@ -258,6 +284,17 @@ Then, she tries to leave a mailing list that does not exist. ... HTTPError: HTTP Error 400: Bad Request +She then tries to leave a mailing list with a bogus address. + + >>> dump_json('http://localhost:8001/3.0/members', { + ... 'ws.op': 'leave', + ... 'fqdn_listname': 'alpha@example.com', + ... 'address': 'elly', + ... }) + Traceback (most recent call last): + ... + HTTPError: HTTP Error 400: Bad Request + For some reason, Elly tries to leave the mailing list again, but she's already been unsubscribed. @@ -269,3 +306,27 @@ been unsubscribed. Traceback (most recent call last): ... HTTPError: HTTP Error 400: Bad Request + +Anna tries to join a mailing list she's already a member of. + + >>> dump_json('http://localhost:8001/3.0/members', { + ... 'ws.op': 'join', + ... 'fqdn_listname': 'alpha@example.com', + ... 'address': 'aperson@example.com', + ... }) + Traceback (most recent call last): + ... + HTTPError: HTTP Error 400: Bad Request + +Gwen tries to join the alpha mailing list using an invalid delivery mode. + + >>> dump_json('http://localhost:8001/3.0/members', { + ... 'ws.op': 'join', + ... 'fqdn_listname': 'alpha@example.com', + ... 'address': 'gperson@example.com', + ... 'real_name': 'Gwen Person', + ... 'delivery_mode': 'in_digests', + ... }) + Traceback (most recent call last): + ... + HTTPError: HTTP Error 400: Bad Request |
