from django.contrib import admin, messages from django.db.models import QuerySet from django.http import HttpRequest from django.utils.translation import gettext_lazy as _ from apikey.hashers import generate_key from apikey.models import ApiClient, ApiKey @admin.register(ApiClient) class ApiClientAdmin(admin.ModelAdmin): list_display = ("name", "owner", "created_at", "updated_at") search_fields = ( "name", "owner__first_name", "owner__last_name", "owner__nick_name", ) autocomplete_fields = ("owner", "groups", "client_permissions") @admin.register(ApiKey) class ApiKeyAdmin(admin.ModelAdmin): list_display = ("name", "client", "created_at", "revoked") list_filter = ("revoked",) date_hierarchy = "created_at" readonly_fields = ("prefix", "hashed_key") actions = ("revoke_keys",) def save_model(self, request: HttpRequest, obj: ApiKey, form, change): if not change: key, hashed = generate_key() obj.prefix = key[: ApiKey.PREFIX_LENGTH] obj.hashed_key = hashed self.message_user( request, _( "The API key for %(name)s is: %(key)s. " "Please store it somewhere safe: " "you will not be able to see it again." ) % {"name": obj.name, "key": key}, level=messages.WARNING, ) return super().save_model(request, obj, form, change) def get_readonly_fields(self, request, obj: ApiKey | None = None): if obj is None or obj.revoked: return ["revoked", *self.readonly_fields] return self.readonly_fields @admin.action(description=_("Revoke selected API keys")) def revoke_keys(self, _request: HttpRequest, queryset: QuerySet[ApiKey]): queryset.update(revoked=True)