summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--devel/management/commands/generate_keyring.py2
-rw-r--r--main/templatetags/pgp.py8
-rw-r--r--public/views.py18
-rw-r--r--templates/public/keys.html30
4 files changed, 52 insertions, 6 deletions
diff --git a/devel/management/commands/generate_keyring.py b/devel/management/commands/generate_keyring.py
index b9117c84..15ae488d 100644
--- a/devel/management/commands/generate_keyring.py
+++ b/devel/management/commands/generate_keyring.py
@@ -48,7 +48,7 @@ def generate_keyring(keyserver, keyring):
logger.info("getting all known key IDs")
# Screw you Django, for not letting one natively do value != <empty string>
- key_ids = UserProfile.objects.filter(user__is_active=True,
+ key_ids = UserProfile.objects.filter(
pgp_key__isnull=False).extra(where=["pgp_key != ''"]).values_list(
"pgp_key", flat=True)
logger.info("%d keys fetched from user profiles", len(key_ids))
diff --git a/main/templatetags/pgp.py b/main/templatetags/pgp.py
index 50b1aa17..5c9fe511 100644
--- a/main/templatetags/pgp.py
+++ b/main/templatetags/pgp.py
@@ -39,6 +39,14 @@ def pgp_key_link(key_id, link_text=None):
values = (url, format_key(key_id), link_text)
return '<a href="%s" title="PGP key search for %s">%s</a>' % values
+@register.simple_tag
+def user_pgp_key_link(users, key_id):
+ matched = [user for user in users if user.userprofile.pgp_key and
+ user.userprofile.pgp_key[-16:] == key_id[-16:]]
+ if matched and len(matched) == 1:
+ return pgp_key_link(key_id, matched[0].get_full_name())
+ return pgp_key_link(key_id)
+
@register.filter
def pgp_fingerprint(key_id, autoescape=True):
if not key_id:
diff --git a/public/views.py b/public/views.py
index c8854b72..312cb3b2 100644
--- a/public/views.py
+++ b/public/views.py
@@ -91,30 +91,38 @@ def feeds(request):
@cache_control(max_age=300)
def keys(request):
+ users = User.objects.filter(is_active=True).select_related(
+ 'userprofile__pgp_key').order_by('first_name', 'last_name')
+ user_key_ids = frozenset(user.userprofile.pgp_key[-16:] for user in users
+ if user.userprofile.pgp_key)
+
not_expired = Q(expires__gt=datetime.utcnow) | Q(expires__isnull=True)
master_keys = MasterKey.objects.select_related('owner', 'revoker',
'owner__userprofile', 'revoker__userprofile').filter(
revoked__isnull=True)
+ master_key_ids = frozenset(key.pgp_key[-16:] for key in master_keys)
- sig_counts = PGPSignature.objects.filter(
- not_expired, valid=True).values_list('signer').annotate(
+ sig_counts = PGPSignature.objects.filter(not_expired, valid=True,
+ signee__in=user_key_ids).values_list('signer').annotate(
Count('signer'))
sig_counts = dict((key_id[-16:], ct) for key_id, ct in sig_counts)
for key in master_keys:
key.signature_count = sig_counts.get(key.pgp_key[-16:], 0)
- users = User.objects.filter(is_active=True).select_related(
- 'userprofile__pgp_key').order_by('first_name', 'last_name')
-
# frozenset because we are going to do lots of __contains__ lookups
signatures = frozenset(PGPSignature.objects.filter(
not_expired, valid=True).values_list('signer', 'signee'))
+ restrict = Q(signer__in=user_key_ids) & Q(signee__in=user_key_ids)
+ cross_signatures = PGPSignature.objects.filter(restrict,
+ not_expired, valid=True).order_by('created')
+
context = {
'keys': master_keys,
'active_users': users,
'signatures': signatures,
+ 'cross_signatures': cross_signatures,
}
return render(request, 'public/keys.html', context)
diff --git a/templates/public/keys.html b/templates/public/keys.html
index 1fed3c15..1b027202 100644
--- a/templates/public/keys.html
+++ b/templates/public/keys.html
@@ -89,6 +89,33 @@
</tbody>
</table>
</div>
+
+<div class="box">
+ <h2>Developer Cross-Signatures</h2>
+
+ <p>This table lists signatures directly between developer keys.</p>
+
+ <table class="pretty2" id="cross-signatures">
+ <thead>
+ <tr>
+ <th>Signer</th>
+ <th>Signee</th>
+ <th>Created</th>
+ <th>Expires</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for sig in cross_signatures %}
+ <tr>
+ <td>{% user_pgp_key_link active_users sig.signer %}</td>
+ <td>{% user_pgp_key_link active_users sig.signee %}</td>
+ <td>{{ sig.created }}</td>
+ <td>{{ sig.expires|default:"" }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+</div>
{% load cdn %}{% jquery %}{% jquery_tablesorter %}
<script type="text/javascript" src="{% static "archweb.js" %}"></script>
<script type="text/javascript">
@@ -97,6 +124,9 @@ $(document).ready(function() {
sortLocaleCompare: true,
headers: { 1: { sorter: false } }
});
+ $("#cross-signatures").tablesorter({
+ sortLocaleCompare: true
+ });
});
</script>
{% endblock %}