Coverage for src/lexigram/auth/admin/pages/sessions.py: 0%
23 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 sessions management page — active session listing."""
3from __future__ import annotations
5from datetime import UTC, datetime
6from typing import Any
8from lexigram.contracts.admin import PageContent
9from lexigram.contracts.admin.widget_content import (
10 EmptyContent,
11 TableCell,
12 TableContent,
13)
14from lexigram.contracts.auth.repositories import SessionRepositoryProtocol
15from lexigram.logging import get_logger
17logger = get_logger(__name__)
20class AuthSessionsPage:
21 """Admin page listing active authentication sessions."""
23 def __init__(
24 self,
25 session_repo: SessionRepositoryProtocol | None = None,
26 ) -> None:
27 self._session_repo = session_repo
29 async def handle(self, request: Any) -> PageContent:
30 if self._session_repo is None:
31 return PageContent(
32 title="Sessions",
33 body=EmptyContent(
34 title="Session Repository Unavailable",
35 message="No session repository is configured.",
36 icon="activity",
37 ),
38 )
40 try:
41 sessions = await self._session_repo.find_active_by_user(
42 user_id="*",
43 cutoff=datetime.now(UTC),
44 )
45 except Exception:
46 logger.warning("auth_sessions.list_failed")
47 return PageContent(
48 title="Sessions",
49 body=EmptyContent(
50 title="Error",
51 message="Failed to retrieve sessions.",
52 icon="alert-triangle",
53 ),
54 )
56 if not sessions:
57 return PageContent(
58 title="Sessions",
59 body=EmptyContent(
60 title="No Active Sessions",
61 message="There are no active sessions.",
62 icon="activity",
63 ),
64 )
66 rows = tuple(
67 (
68 TableCell(str(s.get("session_id", "-"))),
69 TableCell(str(s.get("user_id", "-"))),
70 TableCell("Active"),
71 TableCell(str(s.get("expires_at", ""))),
72 )
73 for s in sessions
74 )
76 return PageContent(
77 title="Sessions",
78 body=TableContent(
79 columns=("Session ID", "User ID", "Status", "Expires"),
80 rows=rows,
81 ),
82 )