From dcf82cf45a6a3c4b523117da1eec6eb8549ca8b7 Mon Sep 17 00:00:00 2001
From: Frank Sauerburger <frank@sauerburger.com>
Date: Sun, 21 Feb 2021 23:21:42 +0100
Subject: [PATCH] Implement permission checks for hkp and wkd

---
 hkp/urls.py                             |  2 +-
 hkp/views.py                            |  5 ++++-
 pgp/models.py                           |  6 +++++-
 pgp/templates/pgp/publickey_detail.html |  4 ++++
 pgp/views.py                            |  5 -----
 wkd/views.py                            | 17 ++++++++++++-----
 6 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/hkp/urls.py b/hkp/urls.py
index 0437ef5..fd6d15a 100644
--- a/hkp/urls.py
+++ b/hkp/urls.py
@@ -18,5 +18,5 @@ from django.urls import path
 from . import views
 
 urlpatterns = [
-    path("lookup", views.lookup, name="hkp-lookup"),
+    path("lookup", views.lookup, name="key-lookup"),
 ]
diff --git a/hkp/views.py b/hkp/views.py
index 1e12a92..ae42b4f 100644
--- a/hkp/views.py
+++ b/hkp/views.py
@@ -1,5 +1,5 @@
 from django.shortcuts import render, get_object_or_404
-from django.http import HttpResponse
+from django.http import HttpResponse, Http404
 from django.views.decorators.http import require_safe
 
 from pgp import models
@@ -19,4 +19,7 @@ def lookup(request):
         search = search[2:]
 
     key = get_object_or_404(models.PublicKey, keyid__endswith=search)
+    if not request.user.has_perm("pgp.view_publickey", key):
+        raise Http404()
+
     return HttpResponse(key.armor, content_type="application/pgp-keys")
diff --git a/pgp/models.py b/pgp/models.py
index 052cc08..e373042 100644
--- a/pgp/models.py
+++ b/pgp/models.py
@@ -20,9 +20,13 @@ class PublicKey(models.Model):
         fingerprint = self.decoded.fingerprint
         self.keyid = re.sub("\s+", "", fingerprint).lower()
 
+    def wkddomain(self):
+        local, domain = self.email.rsplit("@", 1)
+        return domain.lower()
+
     def set_wkdid(self):
         local, domain = self.email.rsplit("@", 1)
-        digest = hashlib.sha1(local.encode()).digest()
+        digest = hashlib.sha1(local.lower().encode()).digest()
         self.wkdid = zbase32.encode(digest).decode()
 
     def save(self, *args, **kwds):
diff --git a/pgp/templates/pgp/publickey_detail.html b/pgp/templates/pgp/publickey_detail.html
index f5d42f1..337f020 100644
--- a/pgp/templates/pgp/publickey_detail.html
+++ b/pgp/templates/pgp/publickey_detail.html
@@ -6,6 +6,10 @@
 gpg2 --keyserver hkp://{{ request.get_host }} --recv-key 0x{{ publickey.details.id }}
 </pre>
 <p>
+<a href="{% url 'key-lookup' %}?op=get&search=0x{{ publickey.details.id }}">HPK download</a>
+<a href="{% url 'wkd-advanced-lookup' publickey.wkddomain publickey.wkdid %}">WKD download</a>
+</p>
+<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>
diff --git a/pgp/views.py b/pgp/views.py
index bf6513e..25038c0 100644
--- a/pgp/views.py
+++ b/pgp/views.py
@@ -10,11 +10,6 @@ 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']
diff --git a/wkd/views.py b/wkd/views.py
index 0e74993..aa50f64 100644
--- a/wkd/views.py
+++ b/wkd/views.py
@@ -1,18 +1,25 @@
 from django.shortcuts import render, get_object_or_404
-from django.http import HttpResponse
+from django.http import HttpResponse, Http404
 
 from pgp import models
 
-def policy(request):
-    return HttpResponse("", content_type="text/plain")
+def policy(request, domain=None):
+    if domain is None:
+        domain = request.get_host().rsplit(":", 1)[0]
+    return HttpResponse(f"# WKD policy file for {domain}",
+                        content_type="text/plain")
 
 def lookup(request, zbase, domain=None):
     if domain is None:
         domain = request.get_host().rsplit(":", 1)[0]
 
-    publickey = get_object_or_404(models.PublicKey, wkdid=zbase)
-    publickey._decode()
+    publickey = get_object_or_404(models.PublicKey,
+                                  wkdid=zbase,
+                                  email__endswith=f"@{domain}")
+    if not request.user.has_perm("pgp.view_publickey", publickey):
+        raise Http404()
 
+    publickey._decode()
     encoded = publickey.decoded.ascii_unarmor(str(publickey.decoded))
 
     return HttpResponse(bytes(encoded["body"]),
-- 
GitLab