diff options
| -rw-r--r-- | src/django_pgpmailman/decorators.py | 42 | ||||
| -rw-r--r-- | src/django_pgpmailman/plugin.py | 16 | ||||
| -rw-r--r-- | src/django_pgpmailman/views/list.py | 35 |
3 files changed, 68 insertions, 25 deletions
diff --git a/src/django_pgpmailman/decorators.py b/src/django_pgpmailman/decorators.py index 41e94da..5f994b6 100644 --- a/src/django_pgpmailman/decorators.py +++ b/src/django_pgpmailman/decorators.py @@ -15,18 +15,56 @@ # # You should have received a copy of the GNU General Public License along with # Postorius. If not, see <http://www.gnu.org/licenses/>. +from allauth.account.models import EmailAddress +from django.core.exceptions import PermissionDenied from django.http import Http404 +from six import wraps from six.moves.urllib_error import HTTPError from django_pgpmailman.plugin import get_pgp_plugin def list_view(fn): - def wrapper(request, list_id, *args, **kwargs): + @wraps(fn) + def wrapper(request, *args, **kwargs): try: - pgp_list = get_pgp_plugin().get_list(list_id) + pgp_list = get_pgp_plugin().get_list(kwargs.pop('list_id')) except HTTPError: raise Http404 return fn(request, pgp_list, *args, **kwargs) return wrapper + + +def list_class_view(fn): + @wraps(fn) + def wrapper(self, request, *args, **kwargs): + self.pgp_list = get_pgp_plugin().get_list(kwargs.pop('list_id')) + return fn(self, request, *args, **kwargs) + + return wrapper + + +def member_role_required(*roles): + def wrapper(fn): + @wraps(fn) + def wrapped(self, request, *args, **kwargs): + user = request.user + if not user.is_authenticated(): + raise PermissionDenied + mlist = self.pgp_list.mlist + addresses = set(EmailAddress.objects.filter( + user=user, verified=True).values_list('email', flat=True)) + for role in roles: + for address in addresses: + members = mlist.find_members(address, role) + if len(members) >= 0: + break + else: + raise PermissionDenied + + return fn(self, request, *args, **kwargs) + + return wrapped + + return wrapper diff --git a/src/django_pgpmailman/plugin.py b/src/django_pgpmailman/plugin.py index 9cbcc77..de6cbcc 100644 --- a/src/django_pgpmailman/plugin.py +++ b/src/django_pgpmailman/plugin.py @@ -43,9 +43,15 @@ class PGPPlugin(Plugin): return PGPMailingList(self._connection, content['self_link'], content) +plugin = None + + def get_pgp_plugin(): - client = Client('%s/3.1' % - settings.MAILMAN_REST_API_URL, - settings.MAILMAN_REST_API_USER, - settings.MAILMAN_REST_API_PASS) - return PGPPlugin(client.get_plugin(settings.MAILMAN_PGP_PLUGIN_NAME)) + global plugin + if not plugin: + client = Client('%s/3.1' % + settings.MAILMAN_REST_API_URL, + settings.MAILMAN_REST_API_USER, + settings.MAILMAN_REST_API_PASS) + plugin = PGPPlugin(client.get_plugin(settings.MAILMAN_PGP_PLUGIN_NAME)) + return plugin diff --git a/src/django_pgpmailman/views/list.py b/src/django_pgpmailman/views/list.py index bbe2547..d887d7a 100644 --- a/src/django_pgpmailman/views/list.py +++ b/src/django_pgpmailman/views/list.py @@ -29,7 +29,8 @@ from django.utils.translation import ugettext_lazy as _ from django.views.generic import FormView from six.moves.urllib.error import HTTPError -from django_pgpmailman.decorators import list_view +from django_pgpmailman.decorators import (list_view, list_class_view, + member_role_required) from django_pgpmailman.forms import (ListSignatureSettingsForm, ListEncryptionSettingsForm, ListMiscSettingsForm) @@ -37,8 +38,7 @@ from django_pgpmailman.plugin import get_pgp_plugin def pgp_list_index(request): - return render(request, - 'django_pgpmailman/index.html', + return render(request, 'django_pgpmailman/index.html', {'lists': get_pgp_plugin().lists}) @@ -48,7 +48,18 @@ def pgp_list_summary(request, pgp_list): {'pgp_list': pgp_list}) -# TODO: proper list owner auth +@list_view +def pgp_list_pubkey(request, pgp_list): + pubkey = pgp_list.pubkey + pubkey_file = ContentFile(str(pubkey)) + response = HttpResponse(pubkey_file, 'application/pgp-keys') + response['Content-Length'] = pubkey_file.size + response[ + 'Content-Disposition'] = 'attachment; filename="%s.asc"' % pgp_list.list_id + return response + + +@method_decorator(login_required, name='dispatch') class ListSettings(FormView): properties = None @@ -65,9 +76,9 @@ class ListSettings(FormView): data['mlist'] = self.pgp_list.mlist return data - @method_decorator(login_required) + @list_class_view + @member_role_required('owner') def dispatch(self, request, *args, **kwargs): - self.pgp_list = get_pgp_plugin().get_list(kwargs['list_id']) return super(ListSettings, self).dispatch(request, *args, **kwargs) def form_valid(self, form): @@ -122,20 +133,8 @@ class ListKeyManagementView(ListSettings): pass -# TODO: proper list owner auth @login_required @list_view def pgp_list_key_management(request, pgp_list): return render(request, 'django_pgpmailman/list/key_management.html', {'pgp_list': pgp_list}) - - -@list_view -def pgp_list_pubkey(request, pgp_list): - pubkey = pgp_list.pubkey - pubkey_file = ContentFile(str(pubkey)) - response = HttpResponse(pubkey_file, 'application/pgp-keys') - response['Content-Length'] = pubkey_file.size - response[ - 'Content-Disposition'] = 'attachment; filename="%s.asc"' % pgp_list.list_id - return response |
