Introduce service/repository dependency protocols and tests

This commit is contained in:
2026-04-10 19:51:19 +02:00
parent 3b6e39ddad
commit 3371ff8324
8 changed files with 419 additions and 11 deletions

View File

@@ -20,6 +20,8 @@ from app.config import Settings
from app.models.auth import Session
from app.models.config import PendingRecovery
from app.models.server import ServerStatus
from app.repositories.protocols import SessionRepository
from app.services.protocols import AuthService, JailService
from app.utils.runtime_state import RuntimeState, get_effective_settings
from app.utils.session_cache import SessionCache
@@ -169,6 +171,27 @@ async def get_session_cache(request: Request) -> SessionCache:
return session_cache
async def get_auth_service() -> AuthService:
"""Provide the concrete authentication service implementation."""
from app.services import auth_service # noqa: PLC0415
return cast(AuthService, auth_service)
async def get_jail_service() -> JailService:
"""Provide the concrete jail service implementation."""
from app.services import jail_service # noqa: PLC0415
return cast(JailService, jail_service)
async def get_session_repo() -> SessionRepository:
"""Provide the concrete session repository implementation."""
from app.repositories import session_repo # noqa: PLC0415
return session_repo
async def get_app_state(request: Request) -> AppState:
"""Provide the application state object for the current request."""
return cast("AppState", request.app.state)
@@ -194,6 +217,8 @@ async def require_auth(
db: Annotated[aiosqlite.Connection, Depends(get_db)],
settings: Annotated[Settings, Depends(get_settings)],
session_cache: Annotated[SessionCache, Depends(get_session_cache)],
auth_service: Annotated[AuthService, Depends(get_auth_service)],
session_repo: Annotated[SessionRepository, Depends(get_session_repo)],
) -> Session:
"""Validate the session token and return the active session.
@@ -218,7 +243,6 @@ async def require_auth(
Raises:
HTTPException: 401 if no valid session token is found.
"""
from app.services import auth_service # noqa: PLC0415
token: str | None = request.cookies.get(_COOKIE_NAME)
if not token:
@@ -240,7 +264,12 @@ async def require_auth(
return cached
try:
session = await auth_service.validate_session(db, token, settings.session_secret)
session = await auth_service.validate_session(
db,
token,
settings.session_secret,
session_repo=session_repo,
)
except ValueError as exc:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
@@ -264,6 +293,9 @@ Fail2BanStartCommandDep = Annotated[str, Depends(get_fail2ban_start_command)]
ServerStatusDep = Annotated[ServerStatus, Depends(get_server_status)]
PendingRecoveryDep = Annotated[PendingRecovery | None, Depends(get_pending_recovery)]
SessionCacheDep = Annotated[SessionCache, Depends(get_session_cache)]
AuthServiceDep = Annotated[AuthService, Depends(get_auth_service)]
JailServiceDep = Annotated[JailService, Depends(get_jail_service)]
SessionRepoDep = Annotated[SessionRepository, Depends(get_session_repo)]
AppStateDep = Annotated[AppState, Depends(get_app_state)]
AppDep = Annotated[FastAPI, Depends(get_app)]
AuthDep = Annotated[Session, Depends(require_auth)]