1 # -*- coding: utf-8 -*-
2 # Copyright (C) 1998-2022 by the Free Software Foundation, Inc.
4 # This file is part of Postorius.
6 # Postorius is free software: you can redistribute it and/or modify it under
7 # the terms of the GNU General Public License as published by the Free
8 # Software Foundation, either version 3 of the License, or (at your option)
11 # Postorius is distributed in the hope that it will be useful, but WITHOUT
12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 # You should have received a copy of the GNU General Public License along with
17 # Postorius. If not, see <http://www.gnu.org/licenses/>.
20 from urllib
.error
import HTTPError
22 from django
.contrib
import messages
23 from django
.http
import HttpResponse
24 from django
.shortcuts
import redirect
, render
25 from django
.urls
import reverse
26 from django
.utils
.translation
import gettext
as _
27 from django
.views
.generic
import TemplateView
29 from django_mailman3
.lib
.mailman
import get_mailman_client
30 from django_mailman3
.lib
.paginator
import paginate
32 from postorius
.auth
.utils
import set_list_access_props
33 from postorius
.forms
import AddBanForm
34 from postorius
.models
import List
37 class MailmanClientMixin(object):
39 """Adds a mailmanclient.Client instance."""
42 if getattr(self
, '_client', None) is None:
43 self
._client
= get_mailman_client()
47 class MailingListView(TemplateView
, MailmanClientMixin
):
49 """A generic view for everything based on a mailman.client
52 Sets self.mailing_list to list object if list_id is in **kwargs.
54 def get(self
, request
, *args
, **kwargs
):
55 # This should be overridden by the subclass.
56 return HttpResponse(status
=405)
58 def post(self
, request
, *args
, **kwargs
):
59 # This should be overridden by the subclass.
60 return HttpResponse(status
=405)
62 def _get_list(self
, list_id
, page
):
63 return List
.objects
.get_or_404(fqdn_listname
=list_id
)
65 def dispatch(self
, request
, *args
, **kwargs
):
66 # get the list object.
67 if 'list_id' in kwargs
:
68 self
.mailing_list
= self
._get
_list
(kwargs
['list_id'],
69 int(kwargs
.get('page', 1)))
70 set_list_access_props(request
.user
, self
.mailing_list
)
72 if 'template' in kwargs
:
73 self
.template
= kwargs
['template']
74 return super(MailingListView
, self
).dispatch(request
, *args
, **kwargs
)
76 def _has_pending_unsub_req(self
, email
):
77 """Check if there is a pending unsubscription request for email."""
78 for req
in self
.mailing_list
.get_requests(
79 token_owner
='moderator', request_type
='unsubscription'):
80 if req
.get('email') == email
:
85 def bans_view(request
, template
, list_id
=None):
86 """Ban or unban email addresses.
88 This is a reusable view which works for both global and list specific bans.
89 Whether a MailingList ban is updated or a Global one depends on list_id
92 :list_id: MailingList Id if this is a List ban, None otherwise.
96 m_list
= List
.objects
.get_or_404(fqdn_listname
=list_id
)
97 url
= reverse('list_bans', args
=[list_id
])
98 ban_list
= m_list
.bans
100 ban_list
= get_mailman_client().bans
101 url
= reverse('global_bans')
104 # Process form submission.
105 if request
.method
== 'POST':
106 if 'add' in request
.POST
:
107 addban_form
= AddBanForm(request
.POST
)
108 if addban_form
.is_valid():
110 ban_list
.add(addban_form
.cleaned_data
['email'])
111 messages
.success(request
, _(
112 'The email {} has been banned.').format(
113 addban_form
.cleaned_data
['email']))
114 except HTTPError
as e
:
116 request
, _('An error occurred: %s') % e
.reason
)
117 except ValueError as e
:
118 messages
.error(request
, _('Invalid data: %s') % e
)
120 elif 'del' in request
.POST
:
122 ban_list
.remove(request
.POST
['email'])
123 messages
.success(request
, _(
124 'The email {} has been un-banned').format(
125 request
.POST
['email']))
126 except HTTPError
as e
:
127 messages
.error(request
, _('An error occurred: %s') % e
.reason
)
128 except ValueError as e
:
129 messages
.error(request
, _('Invalid data: %s') % e
)
132 addban_form
= AddBanForm(initial
=request
.GET
)
133 banned_addresses
= paginate(
134 list(ban_list
), request
.GET
.get('page'), request
.GET
.get('count'))
137 'addban_form': addban_form
,
138 'banned_addresses': banned_addresses
,
142 context
['list'] = m_list
144 return render(request
, template
, context
)