Add the self_link for bans and factor some code
[mailman.git] / src / mailman / rest / bans.py
blobb6c25b74929697a965f9da6cf297ae2d8289e4ed
1 # Copyright (C) 2015 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
8 # any later version.
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 # more details.
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """REST for banned emails."""
20 __all__ = [
21 'BannedEmail',
22 'BannedEmails',
26 from mailman.interfaces.bans import IBanManager
27 from mailman.rest.helpers import (
28 CollectionMixin, bad_request, child, created, etag, no_content, not_found,
29 okay, path_to)
30 from mailman.rest.validator import Validator
34 class _BannedBase:
35 """Common base class."""
37 def __init__(self, mailing_list):
38 self._mlist = mailing_list
39 self.ban_manager = IBanManager(self._mlist)
41 def _location(self, email):
42 if self._mlist is None:
43 base_location = ''
44 else:
45 base_location = 'lists/{}/'.format(self._mlist.list_id)
46 return path_to(
47 '{}bans/{}'.format(base_location, email), self.api_version)
50 class BannedEmail(_BannedBase):
51 """A banned email."""
53 def __init__(self, mailing_list, email):
54 super().__init__(mailing_list)
55 self._email = email
57 def on_get(self, request, response):
58 """Get a banned email."""
59 if self._email is None:
60 bad_request(response, 'Invalid email')
61 elif not self.ban_manager.is_banned(self._email):
62 not_found(
63 response, 'Email {} is not banned'.format(self._email))
64 else:
65 resource = dict(
66 email=self._email,
67 list_id=self._mlist.list_id if self._mlist else None,
68 self_link=self._location(self._email),
70 okay(response, etag(resource))
72 def on_delete(self, request, response):
73 """Remove an email from the ban list."""
74 if self._email is None:
75 bad_request(response, 'Invalid email')
76 elif not self.ban_manager.is_banned(self._email):
77 bad_request(
78 response, 'Email {} is not banned'.format(self._email))
79 else:
80 self.ban_manager.unban(self._email)
81 no_content(response)
84 class BannedEmails(_BannedBase, CollectionMixin):
85 """The list of all banned emails."""
87 def _resource_as_dict(self, ban):
88 """See `CollectionMixin`."""
89 return dict(
90 email=ban.email,
91 list_id=ban.list_id,
92 self_link=self._location(ban.email),
95 def _get_collection(self, request):
96 """See `CollectionMixin`."""
97 return list(self.ban_manager)
99 def on_get(self, request, response):
100 """/bans"""
101 resource = self._make_collection(request)
102 okay(response, etag(resource))
104 def on_post(self, request, response):
105 """Ban some email from subscribing."""
106 validator = Validator(email=str)
107 try:
108 email = validator(request)['email']
109 except ValueError as error:
110 bad_request(response, str(error))
111 return
112 if self.ban_manager.is_banned(email):
113 bad_request(response, b'Address is already banned')
114 else:
115 self.ban_manager.ban(email)
116 created(response, self._location(email))
118 @child(r'^(?P<email>[^/]+)')
119 def email(self, request, segments, **kw):
120 return BannedEmail(self._mlist, kw['email'])