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

1from django.conf import settings as django_settings 

2from django.contrib import admin 

3from django.utils.translation import gettext_lazy as _ 

4 

5from django_otp_webauthn.models import WebAuthnCredential 

6from django_otp_webauthn.settings import app_settings 

7 

8credential_model = app_settings.OTP_WEBAUTHN_CREDENTIAL_MODEL 

9 

10 

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 ] 

34 

35 # Disable the "Add" button - no use creating credentials manually 

36 def has_add_permission(self, request, obj=None): 

37 return False 

38 

39 def credential_id_hex(self, obj): 

40 return obj.credential_id.hex() 

41 

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] 

45 

46 def public_key_hex(self, obj): 

47 return obj.public_key.hex() 

48 

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") 

52 

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"] 

58 

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 

68 

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 

90 

91 def get_queryset(self, request): 

92 queryset = super().get_queryset(request) 

93 queryset = queryset.select_related("user") 

94 

95 return queryset 

96 

97 

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)