From 4c6350f3b7f399913417bc70738a6ef4330e6ca5 Mon Sep 17 00:00:00 2001 From: Drew Hubl Date: Fri, 24 Mar 2017 18:22:21 -0600 Subject: [PATCH] Add admin button to generate new signing key --- email_extras/admin.py | 53 ++++++++++++++++++- email_extras/settings.py | 10 ++++ .../admin/email_extras/key/change_list.html | 14 +++++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 email_extras/templates/admin/email_extras/key/change_list.html diff --git a/email_extras/admin.py b/email_extras/admin.py index 82bea64..e8824c3 100644 --- a/email_extras/admin.py +++ b/email_extras/admin.py @@ -1,18 +1,69 @@ +from django.conf.urls import url +from django.core.exceptions import PermissionDenied +from django.http import HttpResponseRedirect +from django.urls import reverse -from email_extras.settings import USE_GNUPG +from email_extras.settings import ( + USE_GNUPG, GNUPG_HOME, SIGNING_KEY_DATA +) if USE_GNUPG: from django.contrib import admin + from gnupg import GPG + from email_extras.models import Key, Address from email_extras.forms import KeyForm class KeyAdmin(admin.ModelAdmin): + change_list_template = 'admin/email_extras/key/change_list.html' form = KeyForm list_display = ('__str__', 'email_addresses') readonly_fields = ('fingerprint', ) + if SIGNING_KEY_DATA: + def generate_signing_key_view(self, request): + # Since this is a new view its permissions aren't automatically + # handled + if not request.user.is_staff: + return PermissionDenied("You do not have permission to " + "generate signing keys") + + if not self.has_add_permission(request): + return PermissionDenied("You do not have permission to " + "add keys") + + info = ( + self.model._meta.app_label, + self.model._meta.model_name, + ) + gpg = GPG(gnupghome=GNUPG_HOME) + + signing_key_cmd = gpg.gen_key_input(**SIGNING_KEY_DATA) + new_signing_key = gpg.gen_key(signing_key_cmd) + + exported_signing_key = gpg.export_keys( + new_signing_key.fingerprint) + + key = Key.objects.create(key=exported_signing_key, + use_asc=False) + + return HttpResponseRedirect( + reverse('admin:%s_%s_change' % info, args=(key.id,))) + + def get_urls(self): + info = ( + self.model._meta.app_label, + self.model._meta.model_name, + ) + extra_urls = [ + url(r'^generate_signing_key/$', + self.generate_signing_key_view, + name="%s_%s_generate_signing_key" % info), + ] + return extra_urls + super(KeyAdmin, self).get_urls() + class AddressAdmin(admin.ModelAdmin): list_display = ('__str__', 'key') readonly_fields = ('key', ) diff --git a/email_extras/settings.py b/email_extras/settings.py index 043c438..f0af97e 100644 --- a/email_extras/settings.py +++ b/email_extras/settings.py @@ -5,8 +5,18 @@ GNUPG_HOME = getattr(settings, "EMAIL_EXTRAS_GNUPG_HOME", None) USE_GNUPG = getattr(settings, "EMAIL_EXTRAS_USE_GNUPG", GNUPG_HOME is not None) + ALWAYS_TRUST = getattr(settings, "EMAIL_EXTRAS_ALWAYS_TRUST_KEYS", False) GNUPG_ENCODING = getattr(settings, "EMAIL_EXTRAS_GNUPG_ENCODING", None) +SIGNING_KEY_DATA = { + 'key_type': "DSA", + 'key_length': 4096, + 'name_real': settings.SITE_NAME, + 'name_comment': "Outgoing email server", + 'name_email': settings.DEFAULT_FROM_EMAIL, + 'expire_date': '2y', +} +SIGNING_KEY_DATA.update(getattr(settings, "EMAIL_EXTRAS_SIGNING_KEY_DATA", {})) # Used internally encrypt_kwargs = { diff --git a/email_extras/templates/admin/email_extras/key/change_list.html b/email_extras/templates/admin/email_extras/key/change_list.html new file mode 100644 index 0000000..77970fd --- /dev/null +++ b/email_extras/templates/admin/email_extras/key/change_list.html @@ -0,0 +1,14 @@ +{% extends "admin/change_list.html" %} +{% load i18n admin_urls static admin_list %} + +{% block object-tools-items %} + {% url cl.opts|admin_urlname:'generate_signing_key' as generate_signing_key_url %} + {% if generate_signing_key_url and has_add_permission %} +
  • + + {% trans "Generate Signing Key" %} + +
  • + {% endif %} + {{ block.super }} +{% endblock %}