Coverage for src/django_otp_webauthn/admin.py: 58%
36 statements
« prev ^ index » next coverage.py v7.5.4, created at 2024-06-23 20:15 +0000
« prev ^ index » next coverage.py v7.5.4, created at 2024-06-23 20:15 +0000
1from django.conf import settings as django_settings
2from django.contrib import admin
3from django.utils.translation import gettext_lazy as _
5from django_otp_webauthn.models import WebAuthnCredential
6from django_otp_webauthn.settings import app_settings
8credential_model = app_settings.OTP_WEBAUTHN_CREDENTIAL_MODEL
11class WebAuthnCredentialAdmin(admin.ModelAdmin):
12 list_display = [
13 "user",
14 "name",
15 "credential_id_hex_display",
16 "aaguid",
17 "last_used_at",
18 "created_at",
19 ]
20 list_filter = ["last_used_at", "created_at"]
21 raw_id_fields = ["user"]
22 readonly_fields = [
23 "aaguid",
24 "credential_id_hex",
25 "public_key_hex",
26 "last_used_at",
27 "created_at",
28 "transports",
29 "discoverable",
30 "backup_eligible",
31 "backup_state",
32 "sign_count",
33 ]
35 # Disable the "Add" button - no use creating credentials manually
36 def has_add_permission(self, request, obj=None):
37 return False
39 def credential_id_hex(self, obj):
40 return obj.credential_id.hex()
42 def credential_id_hex_display(self, obj):
43 """Truncate the credential ID to 64 characters for display in listing."""
44 return obj.credential_id.hex()[:64]
46 def public_key_hex(self, obj):
47 return obj.public_key.hex()
49 credential_id_hex_display.admin_order_field = "credential_id"
50 credential_id_hex_display.short_description = _("credential ID")
51 public_key_hex.short_description = _("COSE public key")
53 def get_fieldsets(self, request, obj=None):
54 extra_fields = []
55 hide_sensitive_data = getattr(django_settings, "OTP_ADMIN_HIDE_SENSITIVE_DATA", False)
56 if not hide_sensitive_data and obj:
57 extra_fields = ["public_key_hex"]
59 configuration_fields = [
60 "aaguid",
61 "credential_id_hex",
62 "transports",
63 "discoverable",
64 "backup_eligible",
65 "backup_state",
66 "sign_count",
67 ] + extra_fields
69 fieldsets = [
70 (
71 _("Identity"),
72 {
73 "fields": ["user", "name", "confirmed"],
74 },
75 ),
76 (
77 _("Meta"),
78 {
79 "fields": ["last_used_at", "created_at"],
80 },
81 ),
82 (
83 _("WebAuthn credential data"),
84 {
85 "fields": configuration_fields,
86 },
87 ),
88 ]
89 return fieldsets
91 def get_queryset(self, request):
92 queryset = super().get_queryset(request)
93 queryset = queryset.select_related("user")
95 return queryset
98# Only register our ModelAdmin if the default model is the active WebAuthnCredential model.
99# Otherwise, it is up to the developer to register their own ModelAdmin for their custom model.
100if credential_model == "django_otp_webauthn.WebAuthnCredential": 100 ↛ exitline 100 didn't exit the module because the condition on line 100 was always true
101 admin.site.register(WebAuthnCredential, WebAuthnCredentialAdmin)