admin.py
1 from django.contrib import admin 2 from django import forms 3 4 from django_magic_authorization.models import AccessToken 5 from django_magic_authorization.middleware import MagicAuthorizationRouter 6 from django_magic_authorization.settings import get_setting 7 8 9 class AccessTokenForm(forms.ModelForm): 10 def get_routes(): 11 router = MagicAuthorizationRouter() 12 return ((p, p) for p in router.get_protected_paths()) 13 14 path_choice = forms.ChoiceField(choices=get_routes) 15 16 def save(self, commit=True): 17 instance = super().save(commit=False) 18 instance.path = self.cleaned_data.get("path_choice") 19 if commit: 20 instance.save() 21 return instance 22 23 class Meta: 24 model = AccessToken 25 exclude = ["path"] 26 27 28 class AccessTokenAdmin(admin.ModelAdmin): 29 """Admin interface for managing access tokens. 30 31 Provides a dropdown of registered protected paths, displays computed 32 access links, and flags tokens whose paths no longer match a route. 33 """ 34 35 date_hierarchy = "created_at" 36 list_display = ( 37 "description", 38 "display_path", 39 "is_valid", 40 "expires_at", 41 "max_uses", 42 "access_link", 43 "created_at", 44 "last_accessed", 45 "times_accessed", 46 ) 47 readonly_fields = ( 48 "created_at", 49 "last_accessed", 50 "times_accessed", 51 "token", 52 "access_link", 53 ) 54 form = AccessTokenForm 55 list_filter = ["is_valid", "created_at", "expires_at"] 56 search_fields = ["description", "path"] 57 58 def changelist_view(self, request, extra_context=None): 59 self._request = request 60 return super().changelist_view(request, extra_context) 61 62 def change_view(self, request, object_id, form_url="", extra_context=None): 63 self._request = request 64 return super().change_view(request, object_id, form_url, extra_context) 65 66 def display_path(self, obj): 67 router = MagicAuthorizationRouter() 68 if obj.path not in router.get_protected_paths(): 69 return f"❗ {obj.path}" 70 else: 71 return obj.path 72 73 display_path.short_description = "Path" 74 75 def access_link(self, obj): 76 token_param = get_setting("TOKEN_PARAM") 77 if hasattr(self, "_request") and self._request: 78 relative_url = f"{obj.path}?{token_param}={obj.token}" 79 # Ensure path starts with / 80 if not relative_url.startswith("/"): 81 relative_url = f"/{relative_url}" 82 return self._request.build_absolute_uri(relative_url) 83 return f"{obj.path}?{token_param}={obj.token}" 84 85 access_link.short_description = "Access Link" 86 87 88 admin.site.register(AccessToken, AccessTokenAdmin)