diff --git a/keys/settings.py b/keys/settings.py index e2be4f2437c9b7dd67dfb909024135d882cc0922..5cbb30e2a116f3aa1af07bc5ad4bd6a3eab3b9eb 100644 --- a/keys/settings.py +++ b/keys/settings.py @@ -15,7 +15,6 @@ from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ diff --git a/keys/urls.py b/keys/urls.py index 7acaa720c004b07f82b9237fa8b324a8af1194e0..fe4c047e00bec0802da01af2bc7f4170c1aa528e 100644 --- a/keys/urls.py +++ b/keys/urls.py @@ -20,5 +20,6 @@ urlpatterns = [ path('pki/', include('owlca.urls')), path('pgp/', include('pgp.urls')), path('ssh/', include('ssh.urls')), + path('pks/', include('hkp.urls')), path('admin/', admin.site.urls), ] diff --git a/pgp/models.py b/pgp/models.py index 75671f39d578f78876be3568b2fff017f06b347a..c2446170c032b2214d65eb7e2e2462779f15198a 100644 --- a/pgp/models.py +++ b/pgp/models.py @@ -31,6 +31,47 @@ class PublicKey(models.Model): def details(self): self._decode() - return self.decoded + def get_exp(created, expires_at): + if not expires_at: + return None + return created + expires_at + data = { + "userids": [{ + "email": userid.email, + "name": userid.name, + "comment": userid.comment, + "signatures": [{ + "created": sig.created, + "expires_at": get_exp(sig.created, sig.expires_at), + "signer": sig.signer, + } for sig in userid._signatures], + } for userid in self.decoded.userids], + "fingerprint": self.decoded.fingerprint, + "id": re.sub("\s+", "", self.decoded.fingerprint[-8:]), + "created": self.decoded.created, + "expires_at": self.decoded.expires_at, + "signatures": [{ + "created": sig.created, + "expires_at": get_exp(sig.created, sig.expires_at), + "signer": sig.signer, + } for sig in self.decoded._signatures], + "subkeys": [{ + "fingerprint": subkey.fingerprint, + "created": subkey.created, + "expires_at": subkey.expires_at, + "signatures": [{ + "created": sig.created, + "expires_at": get_exp(subkey.created, sig.key_expiration), + "signer": sig.signer, + } + for sig in subkey._signatures + if sig.type == pgpy.constants.SignatureType.Subkey_Binding], + } for id, subkey in self.decoded.subkeys.items()], + } + return data + + def __str__(self): + keyid = f" (0x{self.keyid[-8:]})" if self.keyid else "" + return f"{self.email}{keyid}" diff --git a/pgp/templates/pgp/publickey_detail.html b/pgp/templates/pgp/publickey_detail.html index 05e0ac330cd36ffc2688414c7fbb3242a9b521c0..f5d42f1a375c4be3e0d288fa1517dbe27b655ee7 100644 --- a/pgp/templates/pgp/publickey_detail.html +++ b/pgp/templates/pgp/publickey_detail.html @@ -2,5 +2,42 @@ {% block content %} <h2>Public key for: {{ publickey.email }}</h2> -<pre>{{ publickey.armor }}</pre> +<pre> +gpg2 --keyserver hkp://{{ request.get_host }} --recv-key 0x{{ publickey.details.id }} +</pre> +<p> +<span style="font-family: monospace; font-weight: bold">{{ publickey.details.fingerprint }} +{% for sig in publickey.details.signatures %} + <span style="font-family: monospace">{{ sig.signer }}</span> + ({{ sig.created|date:"Y-m-d" }} – {{ sig.expires_at|date:"Y-m-d"|default:"never" }})<br /> +{% endfor %} +</p> +<h3>User Ids</h3> +<ul> +{% for uid in publickey.details.userids %} + <li> + {{ uid.name }} + {% if uid.comment %}({{ uid.comment }}) {% endif %} + <<a href="mailto:{{ uid.email }}">{{ uid.email }}</a>><br> + {% for sig in uid.signatures %} + <span style="font-family: monospace">{{ sig.signer }}</span> + ({{ sig.created|date:"Y-m-d" }} – {{ sig.expires_at|date:"Y-m-d"|default:"never" }})<br /> + {% endfor %} + </li> +{% endfor %} +</ul> +<h3>Subkeys</h3> +<ul> +{% for key in publickey.details.subkeys %} + <li> + <span style="font-family: monospace; font-weight: bold">{{ key.fingerprint }}</span><br /> + {% for sig in key.signatures %} + <span style="font-family: monospace">{{ sig.signer }}</span> + ({{ sig.created|date:"Y-m-d" }} – {{ sig.expires_at|date:"Y-m-d"|default:"never" }})<br /> + {% endfor %} + </li> +{% endfor %} +</ul> +<h3>Key data</h3> +<textarea cols="80" rows="20" readonly>{{ publickey.armor }}</textarea> {% endblock %} diff --git a/pgp/views.py b/pgp/views.py index 88cb030953bc69d0b464d2fc8bdbdb123435178c..bf6513ec993d492eb81fd716e3f25fce7944bc18 100644 --- a/pgp/views.py +++ b/pgp/views.py @@ -8,6 +8,13 @@ from guardian.utils import get_anonymous_user from . import models from . import forms +from django import template + +register = template.Library() +@register.simple_tag +def get_private_attribute(model_instance, attrib_name): + return getattr(model_instance, attrib_name, '') + class PublicKeyListView(PermissionListMixin, ListView): model = models.PublicKey permission_required = ['view_publickey']