~jimmy-sigint/mailman/rest_api_ban_management

« back to all changes in this revision

Viewing changes to src/mailman/rest/lists.py

  • Committer: Jimmy Bergman
  • Date: 2012-09-21 08:41:18 UTC
  • Revision ID: jimmy@sigint.se-20120921084118-2o45gaiue1jv15pc
Add support for handling per list bans in the REST API.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
__all__ = [
24
24
    'AList',
25
25
    'AllLists',
 
26
    'BannedAddress',
 
27
    'BannedAddresses',
26
28
    'ListConfiguration',
27
29
    'ListsForDomain',
28
30
    ]
33
35
from zope.component import getUtility
34
36
 
35
37
from mailman.app.lifecycle import create_list, remove_list
 
38
from mailman.interfaces.bans import IBanManager
36
39
from mailman.interfaces.domain import BadDomainSpecificationError
37
40
from mailman.interfaces.listmanager import (
38
41
    IListManager, ListAlreadyExistsError)
82
85
 
83
86
 
84
87
@restish_matcher
 
88
def banlist_matcher(request, segments):
 
89
    """A matcher of all banned addresses for a mailing list.
 
90
 
 
91
    e.g. /banlist
 
92
    """
 
93
    if len(segments) != 1 or segments[0] != 'banlist':
 
94
        return None
 
95
    else:
 
96
        return (), {}, ()
 
97
 
 
98
 
 
99
@restish_matcher
 
100
def banned_matcher(request, segments):
 
101
    """A matcher of a single banned addresses for a mailing list.
 
102
 
 
103
    e.g. /banlist/something@example.org
 
104
    """
 
105
    if len(segments) != 2 or segments[0] != 'banlist':
 
106
        return None
 
107
    else:
 
108
        return (), dict(address=segments[1]), ()
 
109
 
 
110
 
 
111
@restish_matcher
85
112
def config_matcher(request, segments):
86
113
    """A matcher for a mailing list's configuration resource.
87
114
 
173
200
            return http.not_found()
174
201
        return HeldMessages(self._mlist)
175
202
 
 
203
    @resource.child(banlist_matcher)
 
204
    def banlist(self, request, segments, attribute=None):
 
205
        """Return a list of banned addresses."""
 
206
        return BannedAddresses(self._mlist)
 
207
 
 
208
    @resource.child(banned_matcher)
 
209
    def banned(self, request, segments, address):
 
210
        """Return a list of banned addresses."""
 
211
        return BannedAddress(self._mlist, address)
 
212
 
 
213
 
 
214
 
 
215
class BannedAddress(resource.Resource, CollectionMixin):
 
216
    """Class to represent a banned address."""
 
217
 
 
218
    def __init__(self, mlist, address):
 
219
        self._mlist = mlist 
 
220
        self._address = address
 
221
        self.ban_manager = getUtility(IBanManager)
 
222
 
 
223
    @resource.GET()
 
224
    def container(self, request):
 
225
        """/banlist/someone@example.com"""
 
226
        if self._mlist is None or self._address is None or not self.ban_manager.is_banned(self._address, self._mlist.fqdn_listname):
 
227
            return http.not_found()
 
228
        resource = dict(banned_email=self._address)
 
229
        return http.ok([], etag(resource))
 
230
 
 
231
    @resource.DELETE()
 
232
    def remove(self, request):
 
233
        """Remove an address from the ban list."""
 
234
        if self._mlist is None or self._address is None:
 
235
            return http.not_found()
 
236
        else:
 
237
            if not self.ban_manager.is_banned(self._address, self._mlist.fqdn_listname):
 
238
                return http.bad_request([], b'Address is not in ban list')
 
239
 
 
240
        self.ban_manager.unban(self._address, self._mlist.fqdn_listname)
 
241
        return http.ok([], '')
 
242
 
 
243
class BannedAddresses(resource.Resource, CollectionMixin):
 
244
    """Class to represent the list of all banned addresses."""
 
245
 
 
246
    def __init__(self, mlist):
 
247
        self._mlist = mlist 
 
248
        self.ban_manager = getUtility(IBanManager)
 
249
 
 
250
    def _resource_as_dict(self, item):
 
251
        """See `CollectionMixin`."""
 
252
        return dict(
 
253
            banned_email=item,
 
254
            )
 
255
 
 
256
    def _get_collection(self, request):
 
257
        """See `CollectionMixin`."""
 
258
        return self.ban_manager.ban_list(self._mlist.fqdn_listname)
 
259
 
 
260
    @resource.GET()
 
261
    def container(self, request):
 
262
        """/banlist"""
 
263
        resource = self._make_collection(request)
 
264
        return http.ok([], etag(resource))
 
265
 
 
266
    @resource.POST()
 
267
    def create(self, request):
 
268
        """Ban some address from subscribing."""
 
269
        try:
 
270
            validator = Validator(address=unicode)
 
271
            converted = validator(request)
 
272
 
 
273
            address = converted['address']
 
274
            if self.ban_manager.is_banned(address, self._mlist.fqdn_listname):
 
275
                return http.bad_request([], b'Address is already in ban list')
 
276
 
 
277
            self.ban_manager.ban(address, self._mlist.fqdn_listname)
 
278
        except ValueError as error:
 
279
            return http.bad_request([], str(error))
 
280
        location = path_to('lists/{0}/banlist'.format(self._mlist.fqdn_listname))
 
281
        return http.created(location, [], None)
 
282
 
176
283
 
177
284
 
178
285
class AllLists(_ListBase):