Coverage for src/lexigram/auth/admin/pages/tokens.py: 0%
21 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 12:26 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-25 12:26 +0800
1"""Auth tokens management page — token key information."""
3from __future__ import annotations
5from typing import Any
7from lexigram.auth.authn.jwt import JWTTokenManager
8from lexigram.contracts.admin import PageContent
9from lexigram.contracts.admin.widget_content import (
10 EmptyContent,
11 TableCell,
12 TableContent,
13)
14from lexigram.logging import get_logger
16logger = get_logger(__name__)
19class AuthTokensPage:
20 """Admin page displaying JWT token configuration and key info."""
22 def __init__(
23 self,
24 token_manager: JWTTokenManager | None = None,
25 ) -> None:
26 self._token_manager = token_manager
28 async def handle(self, request: Any) -> PageContent:
29 if self._token_manager is None:
30 return PageContent(
31 title="Token Configuration",
32 body=EmptyContent(
33 title="Token Manager Unavailable",
34 message="No JWT token manager is configured.",
35 icon="key",
36 ),
37 )
39 try:
40 keys_data = self._token_manager.list_keys()
41 current_key_id = self._token_manager.current_key_id
42 except Exception:
43 logger.warning("auth_tokens.config_unavailable")
44 return PageContent(
45 title="Token Configuration",
46 body=EmptyContent(
47 title="Token Configuration Unavailable",
48 message="Failed to read JWT token configuration.",
49 icon="alert-triangle",
50 ),
51 )
53 rows = tuple(
54 (
55 TableCell(str(kid)),
56 TableCell("Current" if kid == current_key_id else "Active"),
57 TableCell(str(meta.get("created_at", "-"))),
58 )
59 for kid, meta in keys_data.items()
60 )
62 return PageContent(
63 title="Token Configuration",
64 body=TableContent(columns=("Key ID", "Status", "Created"), rows=rows),
65 )