summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mailman/rest/addresses.py37
-rw-r--r--src/mailman/rest/configuration.py41
-rw-r--r--src/mailman/rest/domains.py28
-rw-r--r--src/mailman/rest/helpers.py46
-rw-r--r--src/mailman/rest/lists.py46
-rw-r--r--src/mailman/rest/members.py53
-rw-r--r--src/mailman/rest/moderation.py46
-rw-r--r--src/mailman/rest/preferences.py18
-rw-r--r--src/mailman/rest/root.py6
-rw-r--r--src/mailman/rest/templates.py7
-rw-r--r--src/mailman/rest/users.py67
-rw-r--r--src/mailman/rest/wsgiapp.py10
12 files changed, 190 insertions, 215 deletions
diff --git a/src/mailman/rest/addresses.py b/src/mailman/rest/addresses.py
index a1ed31781..475f0699d 100644
--- a/src/mailman/rest/addresses.py
+++ b/src/mailman/rest/addresses.py
@@ -27,8 +27,6 @@ __all__ = [
]
-import falcon
-
from operator import attrgetter
from zope.component import getUtility
@@ -36,7 +34,8 @@ from mailman.interfaces.address import (
ExistingAddressError, InvalidEmailAddressError)
from mailman.interfaces.usermanager import IUserManager
from mailman.rest.helpers import (
- BadRequest, CollectionMixin, NotFound, child, etag, path_to)
+ BadRequest, CollectionMixin, NotFound, bad_request, child, created, etag,
+ no_content, not_found, okay, path_to)
from mailman.rest.members import MemberCollection
from mailman.rest.preferences import Preferences
from mailman.rest.validator import Validator
@@ -77,8 +76,7 @@ class AllAddresses(_AddressBase):
def on_get(self, request, response):
"""/addresses"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
@@ -96,7 +94,7 @@ class _VerifyResource:
self._address.verified_on = now()
elif self._action == 'unverify':
self._address.verified_on = None
- response.status = falcon.HTTP_204
+ no_content(response)
class AnAddress(_AddressBase):
@@ -113,11 +111,9 @@ class AnAddress(_AddressBase):
def on_get(self, request, response):
"""Return a single address."""
if self._address is None:
- falcon.responders.path_not_found(
- request, response, b'404 Not Found')
+ not_found(response)
else:
- response.status = falcon.HTTP_200
- response.body = self._resource_as_json(self._address)
+ okay(response, self._resource_as_json(self._address))
@child()
def memberships(self, request, segments):
@@ -177,12 +173,9 @@ class UserAddresses(_AddressBase):
def on_get(self, request, response):
"""/addresses"""
if self._user is None:
- falcon.responders.path_not_found(
- request, response, b'404 Not Found')
+ not_found(response)
else:
- response.status = falcon.HTTP_200
- resource = self._make_collection(request)
- response.body = etag(resource)
+ okay(response, etag(self._make_collection(request)))
def on_post(self, request, response):
"""POST to /addresses
@@ -190,7 +183,7 @@ class UserAddresses(_AddressBase):
Add a new address to the user record.
"""
if self._user is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
user_manager = getUtility(IUserManager)
validator = Validator(email=unicode,
@@ -199,19 +192,15 @@ class UserAddresses(_AddressBase):
try:
address = user_manager.create_address(**validator(request))
except ValueError as error:
- falcon.responders.bad_request(request, response, body=str(error))
+ bad_request(response, body=str(error))
except InvalidEmailAddressError:
- falcon.responders.bad_request(
- request, response, body=b'Invalid email address')
+ bad_request(response, body=b'Invalid email address')
except ExistingAddressError:
- falcon.responders.bad_request(
- request, response, body=b'Address already exists')
+ bad_request(response, b'Address already exists')
else:
# Link the address to the current user and return it.
address.user = self._user
- location = path_to('addresses/{0}'.format(address.email))
- response.status = falcon.HTTP_201
- response.location = location
+ created(response, path_to('addresses/{0}'.format(address.email)))
diff --git a/src/mailman/rest/configuration.py b/src/mailman/rest/configuration.py
index 532f7bc4d..1e05ce8c0 100644
--- a/src/mailman/rest/configuration.py
+++ b/src/mailman/rest/configuration.py
@@ -25,8 +25,6 @@ __all__ = [
]
-import falcon
-
from lazr.config import as_boolean, as_timedelta
from mailman.config import config
from mailman.core.errors import (
@@ -35,7 +33,8 @@ from mailman.interfaces.action import Action
from mailman.interfaces.archiver import ArchivePolicy
from mailman.interfaces.autorespond import ResponseAction
from mailman.interfaces.mailinglist import IAcceptableAliasSet, ReplyToMunging
-from mailman.rest.helpers import GetterSetter, etag
+from mailman.rest.helpers import (
+ GetterSetter, bad_request, etag, no_content, okay)
from mailman.rest.validator import PatchValidator, Validator, enum_validator
@@ -172,16 +171,15 @@ class ListConfiguration:
value = ATTRIBUTES[attribute].get(self._mlist, attribute)
resource[attribute] = value
elif self._attribute not in ATTRIBUTES:
- falcon.responders.bad_request(
- request, response,
+ bad_request(
+ response,
body=b'Unknown attribute: {0}'.format(self._attribute))
return
else:
attribute = self._attribute
value = ATTRIBUTES[attribute].get(self._mlist, attribute)
resource[attribute] = value
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
def on_put(self, request, response):
"""Set a mailing list configuration."""
@@ -191,46 +189,41 @@ class ListConfiguration:
try:
validator.update(self._mlist, request)
except ValueError as error:
- falcon.responders.bad_request(
- request, response, body=str(error))
+ bad_request(response, body=str(error))
return
elif attribute not in ATTRIBUTES:
- falcon.responders.bad_request(
- request, response,
- body=b'Unknown attribute: {0}'.format(attribute))
+ bad_request(response, b'Unknown attribute: {0}'.format(attribute))
return
elif ATTRIBUTES[attribute].decoder is None:
- falcon.responders.bad_request(
- request, response,
- body=b'Read-only attribute: {0}'.format(attribute))
+ bad_request(
+ response, b'Read-only attribute: {0}'.format(attribute))
return
else:
validator = Validator(**{attribute: VALIDATORS[attribute]})
try:
validator.update(self._mlist, request)
except ValueError as error:
- falcon.responders.bad_request(
- request, response, body=str(error))
+ bad_request(response, str(error))
return
- response.status = falcon.HTTP_204
+ no_content(response)
def on_patch(self, request, response):
"""Patch the configuration (i.e. partial update)."""
try:
validator = PatchValidator(request, ATTRIBUTES)
except UnknownPATCHRequestError as error:
- falcon.responders.bad_request(
- request, response,
+ bad_request(
+ response,
body=b'Unknown attribute: {0}'.format(error.attribute))
return
except ReadOnlyPATCHRequestError as error:
- falcon.responders.bad_request(
- request, response,
+ bad_request(
+ response,
body=b'Read-only attribute: {0}'.format(error.attribute))
return
try:
validator.update(self._mlist, request)
except ValueError as error:
- falcon.responders.bad_request(request, response, body=str(error))
+ bad_request(response, str(error))
else:
- response.status = falcon.HTTP_204
+ no_content(response)
diff --git a/src/mailman/rest/domains.py b/src/mailman/rest/domains.py
index 23b1c6b3c..5d36dcab9 100644
--- a/src/mailman/rest/domains.py
+++ b/src/mailman/rest/domains.py
@@ -26,12 +26,11 @@ __all__ = [
]
-import falcon
-
from mailman.interfaces.domain import (
BadDomainSpecificationError, IDomainManager)
from mailman.rest.helpers import (
- BadRequest, CollectionMixin, NotFound, child, etag, path_to)
+ BadRequest, CollectionMixin, NotFound, bad_request, child, created, etag,
+ no_content, not_found, okay, path_to)
from mailman.rest.lists import ListsForDomain
from mailman.rest.validator import Validator
from zope.component import getUtility
@@ -67,10 +66,9 @@ class ADomain(_DomainBase):
"""Return a single domain end-point."""
domain = getUtility(IDomainManager).get(self._domain)
if domain is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
else:
- response.status = falcon.HTTP_200
- response.body = self._resource_as_json(domain)
+ okay(response, self._resource_as_json(domain))
def on_delete(self, request, response):
"""Delete the domain."""
@@ -78,10 +76,9 @@ class ADomain(_DomainBase):
getUtility(IDomainManager).remove(self._domain)
except KeyError:
# The domain does not exist.
- falcon.responders.path_not_found(
- request, response, '404 Not Found')
+ not_found(response)
else:
- response.status = falcon.HTTP_204
+ no_content(response)
@child()
def lists(self, request, segments):
@@ -110,18 +107,13 @@ class AllDomains(_DomainBase):
'contact_address'))
domain = domain_manager.add(**validator(request))
except BadDomainSpecificationError:
- falcon.responders.bad_request(
- request, response, body=b'Domain exists')
+ bad_request(response, b'Domain exists')
except ValueError as error:
- falcon.responders.bad_request(
- request, response, body=str(error))
+ bad_request(response, str(error))
else:
- location = path_to('domains/{0}'.format(domain.mail_host))
- response.status = falcon.HTTP_201
- response.location = location
+ created(response, path_to('domains/{0}'.format(domain.mail_host)))
def on_get(self, request, response):
"""/domains"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py
index 74c66958d..acc5106be 100644
--- a/src/mailman/rest/helpers.py
+++ b/src/mailman/rest/helpers.py
@@ -25,8 +25,15 @@ __all__ = [
'ChildError',
'GetterSetter',
'NotFound',
+ 'bad_request',
'child',
+ 'conflict',
+ 'created',
'etag',
+ 'forbidden',
+ 'no_content',
+ 'not_found',
+ 'okay',
'path_to',
]
@@ -272,3 +279,42 @@ class BadRequest(ChildError):
class NotFound(ChildError):
def __init__(self):
super(NotFound, self).__init__(falcon.HTTP_404)
+
+
+def okay(response, body=None):
+ response.status = falcon.HTTP_200
+ if body is not None:
+ response.body = body
+
+
+def no_content(response):
+ response.status = falcon.HTTP_204
+
+
+def not_found(response, body=b'404 Not Found'):
+ response.status = falcon.HTTP_404
+ if body is not None:
+ response.body = body
+
+
+def bad_request(response, body='400 Bad Request'):
+ response.status = falcon.HTTP_400
+ if body is not None:
+ response.body = body
+
+
+def created(response, location):
+ response.status = falcon.HTTP_201
+ response.location = location
+
+
+def conflict(response, body=b'409 Conflict'):
+ response.status = falcon.HTTP_409
+ if body is not None:
+ response.body = body
+
+
+def forbidden(response, body=b'403 Forbidden'):
+ response.status = falcon.HTTP_403
+ if body is not None:
+ response.body = body
diff --git a/src/mailman/rest/lists.py b/src/mailman/rest/lists.py
index 0aaa6298f..580b6e898 100644
--- a/src/mailman/rest/lists.py
+++ b/src/mailman/rest/lists.py
@@ -30,8 +30,6 @@ __all__ = [
]
-import falcon
-
from lazr.config import as_boolean
from operator import attrgetter
from zope.component import getUtility
@@ -47,7 +45,8 @@ from mailman.interfaces.styles import IStyleManager
from mailman.interfaces.subscriptions import ISubscriptionService
from mailman.rest.configuration import ListConfiguration
from mailman.rest.helpers import (
- CollectionMixin, GetterSetter, NotFound, child, etag, paginate, path_to)
+ CollectionMixin, GetterSetter, NotFound, bad_request, child, created,
+ etag, no_content, not_found, okay, paginate, path_to)
from mailman.rest.members import AMember, MemberCollection
from mailman.rest.moderation import HeldMessages, SubscriptionRequests
from mailman.rest.validator import Validator
@@ -138,18 +137,17 @@ class AList(_ListBase):
def on_get(self, request, response):
"""Return a single mailing list end-point."""
if self._mlist is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
else:
- response.status = falcon.HTTP_200
- response.body = self._resource_as_json(self._mlist)
+ okay(response, self._resource_as_json(self._mlist))
def on_delete(self, request, response):
"""Delete the named mailing list."""
if self._mlist is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
else:
remove_list(self._mlist)
- response.status = falcon.HTTP_204
+ no_content(response)
@child(member_matcher)
def member(self, request, segments, role, email):
@@ -211,25 +209,20 @@ class AllLists(_ListBase):
_optional=('style_name',))
mlist = create_list(**validator(request))
except ListAlreadyExistsError:
- falcon.responders.bad_request(
- request, response, body=b'Mailing list exists')
+ bad_request(response, b'Mailing list exists')
except BadDomainSpecificationError as error:
- falcon.responders.bad_request(
- request, response, body=b'Domain does not exist: {0}'.format(
- error.domain))
+ bad_request(
+ response,
+ b'Domain does not exist: {0}'.format(error.domain))
except ValueError as error:
- falcon.responders.bad_request(
- request, response, body=str(error))
+ bad_request(response, str(error))
else:
- location = path_to('lists/{0}'.format(mlist.list_id))
- response.status = falcon.HTTP_201
- response.location = location
+ created(response, path_to('lists/{0}'.format(mlist.list_id)))
def on_get(self, request, response):
"""/lists"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
@@ -260,8 +253,7 @@ class ListsForDomain(_ListBase):
def on_get(self, request, response):
"""/domains/<domain>/lists"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
@paginate
def _get_collection(self, request):
@@ -298,8 +290,7 @@ class ListArchivers:
archiver_set = IListArchiverSet(self._mlist)
resource = {archiver.name: archiver.is_enabled
for archiver in archiver_set.archivers}
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
def patch_put(self, request, response, is_optional):
archiver_set = IListArchiverSet(self._mlist)
@@ -311,9 +302,9 @@ class ListArchivers:
try:
Validator(**kws).update(self._mlist, request)
except ValueError as error:
- falcon.responders.bad_request(request, response, body=str(error))
+ bad_request(response, str(error))
else:
- response.status = falcon.HTTP_204
+ no_content(response)
def on_put(self, request, response):
"""Update all the archiver statuses."""
@@ -336,5 +327,4 @@ class Styles:
default=config.styles.default)
def on_get(self, request, response):
- response.status = falcon.HTTP_200
- response.body = etag(self._resource)
+ okay(response, etag(self._resource))
diff --git a/src/mailman/rest/members.py b/src/mailman/rest/members.py
index afc4b302d..4d1c87b73 100644
--- a/src/mailman/rest/members.py
+++ b/src/mailman/rest/members.py
@@ -28,8 +28,6 @@ __all__ = [
]
-import falcon
-
from uuid import UUID
from operator import attrgetter
from zope.component import getUtility
@@ -44,7 +42,8 @@ from mailman.interfaces.subscriptions import ISubscriptionService
from mailman.interfaces.user import UnverifiedAddressError
from mailman.interfaces.usermanager import IUserManager
from mailman.rest.helpers import (
- CollectionMixin, NotFound, child, etag, paginate, path_to)
+ CollectionMixin, NotFound, bad_request, child, conflict, created, etag,
+ no_content, not_found, okay, paginate, path_to)
from mailman.rest.preferences import Preferences, ReadOnlyPreferences
from mailman.rest.validator import (
Validator, enum_validator, subscriber_validator)
@@ -98,8 +97,7 @@ class MemberCollection(_MemberBase):
def on_get(self, request, response):
"""roster/[members|owners|moderators]"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
@@ -121,10 +119,9 @@ class AMember(_MemberBase):
def on_get(self, request, response):
"""Return a single member end-point."""
if self._member is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
else:
- response.status = falcon.HTTP_200
- response.body = self._resource_as_json(self._member)
+ okay(response, self._resource_as_json(self._member))
@child()
def preferences(self, request, segments):
@@ -156,18 +153,18 @@ class AMember(_MemberBase):
# owner. Handle the former case first. For now too, we will not send
# an admin or user notification.
if self._member is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
mlist = getUtility(IListManager).get_by_list_id(self._member.list_id)
if self._member.role is MemberRole.member:
try:
delete_member(mlist, self._member.address.email, False, False)
except NotAMemberError:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
else:
self._member.unsubscribe()
- response.status = falcon.HTTP_204
+ no_content(response)
def on_patch(self, request, response):
"""Patch the membership.
@@ -175,7 +172,7 @@ class AMember(_MemberBase):
This is how subscription changes are done.
"""
if self._member is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
try:
values = Validator(
@@ -183,24 +180,22 @@ class AMember(_MemberBase):
delivery_mode=enum_validator(DeliveryMode),
_optional=('address', 'delivery_mode'))(request)
except ValueError as error:
- falcon.responders.bad_request(request, response, body=str(error))
+ bad_request(response, str(error))
return
if 'address' in values:
email = values['address']
address = getUtility(IUserManager).get_address(email)
if address is None:
- falcon.responders.bad_request(
- request, response, body=b'Address not registered')
+ bad_request(response, b'Address not registered')
return
try:
self._member.address = address
except (MembershipError, UnverifiedAddressError) as error:
- falcon.responders.bad_request(
- request, response, body=str(error))
+ bad_request(response, str(error))
return
if 'delivery_mode' in values:
self._member.preferences.delivery_mode = values['delivery_mode']
- response.status = falcon.HTTP_204
+ no_content(response)
@@ -220,29 +215,24 @@ class AllMembers(_MemberBase):
_optional=('delivery_mode', 'display_name', 'role'))
member = service.join(**validator(request))
except AlreadySubscribedError:
- response.status = falcon.HTTP_409
- response.body = b'Member already subscribed'
+ conflict(response, b'Member already subscribed')
except NoSuchListError:
- falcon.responders.bad_request(
- request, response, body=b'No such list')
+ bad_request(response, b'No such list')
except InvalidEmailAddressError:
- falcon.responders.bad_request(
- request, response, body=b'Invalid email address')
+ bad_request(response, b'Invalid email address')
except ValueError as error:
- falcon.responders.bad_request(request, response, body=str(error))
+ bad_request(response, str(error))
else:
# The member_id are UUIDs. We need to use the integer equivalent
# in the URL.
member_id = member.member_id.int
location = path_to('members/{0}'.format(member_id))
- response.status = falcon.HTTP_201
- response.location = location
+ created(response, location)
def on_get(self, request, response):
"""/members"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
@@ -273,8 +263,7 @@ class FindMembers(_MemberBase):
try:
members = service.find_members(**validator(request))
except ValueError as error:
- falcon.responders.bad_request(response, body=str(error))
+ bad_request(response, str(error))
else:
resource = _FoundMembers(members)._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
diff --git a/src/mailman/rest/moderation.py b/src/mailman/rest/moderation.py
index 97371168d..0bdc50688 100644
--- a/src/mailman/rest/moderation.py
+++ b/src/mailman/rest/moderation.py
@@ -28,14 +28,13 @@ __all__ = [
]
-import falcon
-
from mailman.app.moderator import (
handle_message, handle_subscription, handle_unsubscription)
from mailman.interfaces.action import Action
from mailman.interfaces.messages import IMessageStore
from mailman.interfaces.requests import IListRequests, RequestType
-from mailman.rest.helpers import CollectionMixin, child, etag
+from mailman.rest.helpers import (
+ CollectionMixin, bad_request, child, etag, no_content, not_found, okay)
from mailman.rest.validator import Validator, enum_validator
from zope.component import getUtility
@@ -112,35 +111,33 @@ class HeldMessage(_HeldMessageBase):
try:
request_id = int(self._request_id)
except ValueError:
- falcon.responders.bad_request(request, response)
+ bad_request(response)
return
resource = self._make_resource(request_id)
if resource is None:
- falcon.responders.path_not_found(
- request, response, body=b'404 Not Found')
+ not_found(response)
else:
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
def on_post(self, request, response):
try:
validator = Validator(action=enum_validator(Action))
arguments = validator(request)
except ValueError as error:
- falcon.responders.bad_request(request, response, body=str(error))
+ bad_request(response, str(error))
return
requests = IListRequests(self._mlist)
try:
request_id = int(self._request_id)
except ValueError:
- falcon.responders.bad_request(request, response)
+ bad_request(response)
return
results = requests.get_request(request_id, RequestType.held_message)
if results is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
else:
handle_message(self._mlist, request_id, **arguments)
- response.status = falcon.HTTP_204
+ no_content(response)
@@ -163,8 +160,7 @@ class HeldMessages(_HeldMessageBase, CollectionMixin):
def on_get(self, request, response):
"""/lists/listname/held"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
@child(r'^(?P<id>[^/]+)')
def message(self, request, segments, **kw):
@@ -183,48 +179,47 @@ class MembershipChangeRequest(_ModerationBase):
try:
request_id = int(self._request_id)
except ValueError:
- falcon.responders.bad_request(request, response)
+ bad_request(response)
return
resource = self._make_resource(request_id, MEMBERSHIP_CHANGE_REQUESTS)
if resource is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
else:
# Remove unnecessary keys.
del resource['key']
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
def on_post(self, request, response):
try:
validator = Validator(action=enum_validator(Action))
arguments = validator(request)
except ValueError as error:
- falcon.responders.bad_request(request, response, body=str(error))
+ bad_request(response, str(error))
return
requests = IListRequests(self._mlist)
try:
request_id = int(self._request_id)
except ValueError:
- falcon.responders.bad_request(request, response)
+ bad_request(response)
return
results = requests.get_request(request_id)
if results is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
key, data = results
try:
request_type = RequestType[data['_request_type']]
except ValueError:
- falcon.responders.bad_request(request, response)
+ bad_request(response)
return
if request_type is RequestType.subscription:
handle_subscription(self._mlist, request_id, **arguments)
elif request_type is RequestType.unsubscription:
handle_unsubscription(self._mlist, request_id, **arguments)
else:
- falcon.responders.bad_request(request, response)
+ bad_request(response)
return
- response.status = falcon.HTTP_204
+ no_content(response)
class SubscriptionRequests(_ModerationBase, CollectionMixin):
@@ -253,8 +248,7 @@ class SubscriptionRequests(_ModerationBase, CollectionMixin):
def on_get(self, request, response):
"""/lists/listname/requests"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
@child(r'^(?P<id>[^/]+)')
def subscription(self, request, segments, **kw):
diff --git a/src/mailman/rest/preferences.py b/src/mailman/rest/preferences.py
index fdd1f65fb..b85388ec9 100644
--- a/src/mailman/rest/preferences.py
+++ b/src/mailman/rest/preferences.py
@@ -26,11 +26,10 @@ __all__ = [
]
-import falcon
-
from lazr.config import as_boolean
from mailman.interfaces.member import DeliveryMode, DeliveryStatus
-from mailman.rest.helpers import GetterSetter, etag, path_to
+from mailman.rest.helpers import (
+ GetterSetter, bad_request, etag, no_content, not_found, okay, path_to)
from mailman.rest.validator import (
Validator, enum_validator, language_validator)
@@ -70,8 +69,7 @@ class ReadOnlyPreferences:
# Add the self link.
resource['self_link'] = path_to(
'{0}/preferences'.format(self._base_url))
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
@@ -80,7 +78,8 @@ class Preferences(ReadOnlyPreferences):
def patch_put(self, request, response, is_optional):
if self._parent is None:
- response.status = falcon.HTTP_404
+ not_found(response)
+ return
kws = dict(
acknowledge_posts=GetterSetter(as_boolean),
hide_address = GetterSetter(as_boolean),
@@ -96,10 +95,9 @@ class Preferences(ReadOnlyPreferences):
try:
Validator(**kws).update(self._parent, request)
except ValueError as error:
- falcon.responders.bad_request(
- request, response, body=str(error))
+ bad_request(response, str(error))
else:
- response.status = falcon.HTTP_204
+ no_content(response)
def on_patch(self, request, response):
"""Patch the preferences."""
@@ -114,4 +112,4 @@ class Preferences(ReadOnlyPreferences):
for attr in PREFERENCES:
if hasattr(self._parent, attr):
setattr(self._parent, attr, None)
- response.status = falcon.HTTP_204
+ no_content(response)
diff --git a/src/mailman/rest/root.py b/src/mailman/rest/root.py
index 5db59ad7d..93a8f0086 100644
--- a/src/mailman/rest/root.py
+++ b/src/mailman/rest/root.py
@@ -36,7 +36,8 @@ from mailman.core.system import system
from mailman.interfaces.listmanager import IListManager
from mailman.rest.addresses import AllAddresses, AnAddress
from mailman.rest.domains import ADomain, AllDomains
-from mailman.rest.helpers import BadRequest, NotFound, child, etag, path_to
+from mailman.rest.helpers import (
+ BadRequest, NotFound, child, etag, okay, path_to)
from mailman.rest.lists import AList, AllLists, Styles
from mailman.rest.members import AMember, AllMembers, FindMembers
from mailman.rest.preferences import ReadOnlyPreferences
@@ -87,8 +88,7 @@ class System:
python_version=system.python_version,
self_link=path_to('system'),
)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
class TopLevel:
diff --git a/src/mailman/rest/templates.py b/src/mailman/rest/templates.py
index 85c698f07..44dcdefc5 100644
--- a/src/mailman/rest/templates.py
+++ b/src/mailman/rest/templates.py
@@ -25,8 +25,7 @@ __all__ = [
]
-import falcon
-
+from mailman.rest.helpers import not_found
from mailman.utilities.i18n import TemplateNotFoundError, find
@@ -51,7 +50,7 @@ class TemplateFinder:
# XXX We currently only support .txt and .html files.
extension = EXTENSIONS.get(self.content_type)
if extension is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
template = self.template + extension
fp = None
@@ -59,7 +58,7 @@ class TemplateFinder:
try:
path, fp = find(template, self.mlist, self.language)
except TemplateNotFoundError:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
else:
return fp.read()
diff --git a/src/mailman/rest/users.py b/src/mailman/rest/users.py
index cccd5ab98..645b83a36 100644
--- a/src/mailman/rest/users.py
+++ b/src/mailman/rest/users.py
@@ -26,8 +26,6 @@ __all__ = [
]
-import falcon
-
from passlib.utils import generate_password as generate
from uuid import UUID
from zope.component import getUtility
@@ -39,8 +37,8 @@ from mailman.interfaces.address import ExistingAddressError
from mailman.interfaces.usermanager import IUserManager
from mailman.rest.addresses import UserAddresses
from mailman.rest.helpers import (
- BadRequest, CollectionMixin, GetterSetter, NotFound, child, etag,
- paginate, path_to)
+ BadRequest, CollectionMixin, GetterSetter, NotFound, bad_request, child,
+ created, etag, forbidden, no_content, not_found, okay, paginate, path_to)
from mailman.rest.preferences import Preferences
from mailman.rest.validator import PatchValidator, Validator
@@ -101,8 +99,7 @@ class AllUsers(_UserBase):
def on_get(self, request, response):
"""/users"""
resource = self._make_collection(request)
- response.status = falcon.HTTP_200
- response.body = etag(resource)
+ okay(response, etag(resource))
def on_post(self, request, response):
"""Create a new user."""
@@ -113,7 +110,7 @@ class AllUsers(_UserBase):
_optional=('display_name', 'password'))
arguments = validator(request)
except ValueError as error:
- falcon.responders.bad_request(response, body=str(error))
+ bad_request(response, str(error))
return
# We can't pass the 'password' argument to the user creation method,
# so strip that out (if it exists), then create the user, adding the
@@ -122,8 +119,8 @@ class AllUsers(_UserBase):
try:
user = getUtility(IUserManager).create_user(**arguments)
except ExistingAddressError as error:
- falcon.responders.bad_request(
- request, response,
+ bad_request(
+ response,
body=b'Address already exists: {0}'.format(error.address))
return
if password is None:
@@ -131,8 +128,7 @@ class AllUsers(_UserBase):
password = generate(int(config.passwords.password_length))
user.password = config.password_context.encrypt(password)
location = path_to('users/{0}'.format(user.user_id.int))
- response.status = falcon.HTTP_201
- response.location = location
+ created(response, location)
@@ -165,11 +161,9 @@ class AUser(_UserBase):
def on_get(self, request, response):
"""Return a single user end-point."""
if self._user is None:
- falcon.responders.path_not_found(
- request, response, body=b'404 Not Found')
+ not_found(response)
else:
- response.status = falcon.HTTP_200
- response.body = self._resource_as_json(self._user)
+ okay(response, self._resource_as_json(self._user))
@child()
def addresses(self, request, segments):
@@ -181,7 +175,7 @@ class AUser(_UserBase):
def on_delete(self, request, response):
"""Delete the named user, all her memberships, and addresses."""
if self._user is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
for member in self._user.memberships.members:
member.unsubscribe()
@@ -189,7 +183,7 @@ class AUser(_UserBase):
for address in self._user.addresses:
user_manager.delete_address(address)
user_manager.delete_user(self._user)
- response.status = falcon.HTTP_204
+ no_content(response)
@child()
def preferences(self, request, segments):
@@ -206,44 +200,38 @@ class AUser(_UserBase):
def on_patch(self, request, response):
"""Patch the user's configuration (i.e. partial update)."""
if self._user is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
try:
validator = PatchValidator(request, ATTRIBUTES)
except UnknownPATCHRequestError as error:
- falcon.responders.bad_request(
- request, response,
- body=b'Unknown attribute: {0}'.format(error.attribute))
+ bad_request(
+ response, b'Unknown attribute: {0}'.format(error.attribute))
except ReadOnlyPATCHRequestError as error:
- falcon.responders.bad_request(
- request, response,
- body=b'Read-only attribute: {0}'.format(error.attribute))
+ bad_request(
+ response, b'Read-only attribute: {0}'.format(error.attribute))
else:
validator.update(self._user, request)
- response.status = falcon.HTTP_204
+ no_content(response)
def on_put(self, request, response):
"""Put the user's configuration (i.e. full update)."""
if self._user is None:
- falcon.responders.path_not_found(request, response)
+ not_found(response)
return
validator = Validator(**ATTRIBUTES)
try:
validator.update(self._user, request)
except UnknownPATCHRequestError as error:
- falcon.responders.bad_request(
- request, response,
- body=b'Unknown attribute: {0}'.format(error.attribute))
+ bad_request(
+ response, b'Unknown attribute: {0}'.format(error.attribute))
except ReadOnlyPATCHRequestError as error:
- falcon.responders.bad_request(
- request, response,
- body=b'Read-only attribute: {0}'.format(error.attribute))
+ bad_request(
+ response, b'Read-only attribute: {0}'.format(error.attribute))
except ValueError as error:
- falcon.responders.bad_request(
- request, response,
- body=str(error))
+ bad_request(response, str(error))
else:
- response.status = falcon.HTTP_204
+ no_content(response)
@child()
def login(self, request, segments):
@@ -269,14 +257,13 @@ class Login:
try:
values = validator(request)
except ValueError as error:
- falcon.responders.bad_request(request, response, body=str(error))
+ bad_request(response, str(error))
return
is_valid, new_hash = config.password_context.verify(
values['cleartext_password'], self._user.password)
if is_valid:
if new_hash is not None:
self._user.password = new_hash
- response.status = falcon.HTTP_204
+ no_content(response)
else:
- response.status = falcon.HTTP_403
- response.body = b'403 Forbidden'
+ forbidden(response)
diff --git a/src/mailman/rest/wsgiapp.py b/src/mailman/rest/wsgiapp.py
index 341a4cbb4..98239ec51 100644
--- a/src/mailman/rest/wsgiapp.py
+++ b/src/mailman/rest/wsgiapp.py
@@ -27,18 +27,16 @@ __all__ = [
import re
-import falcon
import logging
from falcon import API
from falcon.api_helpers import create_http_method_map
-
-from wsgiref.simple_server import WSGIRequestHandler
-from wsgiref.simple_server import make_server as wsgi_server
-
+from falcon.responders import path_not_found
from mailman.config import config
from mailman.database.transaction import transactional
from mailman.rest.root import Root
+from wsgiref.simple_server import WSGIRequestHandler
+from wsgiref.simple_server import make_server as wsgi_server
log = logging.getLogger('mailman.http')
@@ -148,7 +146,7 @@ class RootedAPI(API):
else:
# None of the attributes matched this path component, so the
# response is a 404.
- return falcon.responders.path_not_found, {}, None
+ return path_not_found, {}, None