diff options
-rw-r--r-- | devel/management/commands/generate_keyring.py | 2 | ||||
-rw-r--r-- | main/templatetags/pgp.py | 8 | ||||
-rw-r--r-- | public/views.py | 18 | ||||
-rw-r--r-- | templates/public/keys.html | 30 |
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 %} |