Move auth session signing into auth_service.login
This commit is contained in:
@@ -20,7 +20,6 @@ from app.dependencies import (
|
||||
SettingsDep,
|
||||
)
|
||||
from app.models.auth import LoginRequest, LoginResponse, LogoutResponse
|
||||
from app.services.auth_service import sign_session_token
|
||||
from app.utils.constants import SESSION_COOKIE_NAME
|
||||
|
||||
log: structlog.stdlib.BoundLogger = structlog.get_logger()
|
||||
@@ -59,10 +58,11 @@ async def login(
|
||||
HTTPException: 401 if the password is incorrect.
|
||||
"""
|
||||
try:
|
||||
session = await auth_service.login(
|
||||
signed_token, expires_at = await auth_service.login(
|
||||
db,
|
||||
password=body.password,
|
||||
session_duration_minutes=settings.session_duration_minutes,
|
||||
session_secret=settings.session_secret,
|
||||
session_repo=session_repo,
|
||||
)
|
||||
except ValueError as exc:
|
||||
@@ -71,10 +71,6 @@ async def login(
|
||||
detail=str(exc),
|
||||
) from exc
|
||||
|
||||
signed_token = sign_session_token(
|
||||
session.token,
|
||||
settings.session_secret,
|
||||
)
|
||||
response.set_cookie(
|
||||
key=SESSION_COOKIE_NAME,
|
||||
value=signed_token,
|
||||
@@ -83,7 +79,7 @@ async def login(
|
||||
secure=settings.session_cookie_secure,
|
||||
max_age=settings.session_duration_minutes * 60,
|
||||
)
|
||||
return LoginResponse(token=signed_token, expires_at=session.expires_at)
|
||||
return LoginResponse(token=signed_token, expires_at=expires_at)
|
||||
|
||||
|
||||
@router.post(
|
||||
|
||||
@@ -79,17 +79,19 @@ async def login(
|
||||
db: aiosqlite.Connection,
|
||||
password: str,
|
||||
session_duration_minutes: int,
|
||||
session_secret: str,
|
||||
session_repo: SessionRepository = default_session_repo,
|
||||
) -> Session:
|
||||
"""Verify *password* and create a new session on success.
|
||||
) -> tuple[str, str]:
|
||||
"""Verify *password*, create a new session, and sign the token.
|
||||
|
||||
Args:
|
||||
db: Active aiosqlite connection.
|
||||
password: Plain-text password supplied by the user.
|
||||
session_duration_minutes: How long the new session is valid for.
|
||||
session_secret: Secret used to sign the session token.
|
||||
|
||||
Returns:
|
||||
A :class:`~app.models.auth.Session` domain model for the new session.
|
||||
A tuple of the signed session token and its expiry timestamp.
|
||||
|
||||
Raises:
|
||||
ValueError: If the password is incorrect or no password hash is stored.
|
||||
@@ -111,8 +113,9 @@ async def login(
|
||||
session = await session_repo.create_session(
|
||||
db, token=token, created_at=created_iso, expires_at=expires_iso
|
||||
)
|
||||
log.info("bangui_login_success", token_prefix=token[:8])
|
||||
return session
|
||||
signed_token = sign_session_token(session.token, session_secret)
|
||||
log.info("bangui_login_success", token_prefix=session.token[:8])
|
||||
return signed_token, session.expires_at
|
||||
|
||||
|
||||
async def validate_session(
|
||||
|
||||
@@ -6,41 +6,42 @@ layers depend on, without binding them to concrete module implementations.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import Protocol, runtime_checkable
|
||||
from typing import TYPE_CHECKING, Protocol, runtime_checkable
|
||||
|
||||
import aiosqlite
|
||||
import aiohttp
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Awaitable, Callable
|
||||
|
||||
from app.models.auth import Session
|
||||
from app.models.ban import BanOrigin, JailBannedIpsResponse, TimeRange
|
||||
from app.models.blocklist import (
|
||||
BlocklistSource,
|
||||
ImportLogListResponse,
|
||||
ImportRunResult,
|
||||
ImportSourceResult,
|
||||
PreviewResponse,
|
||||
ScheduleConfig,
|
||||
ScheduleInfo,
|
||||
)
|
||||
from app.models.config import (
|
||||
AddLogPathRequest,
|
||||
GlobalConfigResponse,
|
||||
GlobalConfigUpdate,
|
||||
JailConfigListResponse,
|
||||
JailConfigResponse,
|
||||
JailConfigUpdate,
|
||||
LogPreviewRequest,
|
||||
LogPreviewResponse,
|
||||
MapColorThresholdsResponse,
|
||||
MapColorThresholdsUpdate,
|
||||
RegexTestResponse,
|
||||
Fail2BanLogResponse,
|
||||
ServiceStatusResponse,
|
||||
)
|
||||
from app.models.geo import GeoBatchLookup, GeoEnricher, GeoInfo
|
||||
from app.models.history import HistoryListResponse, IpDetailResponse
|
||||
from app.models.server import ServerSettingsResponse, ServerSettingsUpdate, ServerStatus
|
||||
import aiohttp
|
||||
import aiosqlite
|
||||
|
||||
from app.models.auth import Session
|
||||
from app.models.ban import BanOrigin, JailBannedIpsResponse, TimeRange
|
||||
from app.models.blocklist import (
|
||||
BlocklistSource,
|
||||
ImportLogListResponse,
|
||||
ImportRunResult,
|
||||
ImportSourceResult,
|
||||
PreviewResponse,
|
||||
ScheduleConfig,
|
||||
ScheduleInfo,
|
||||
)
|
||||
from app.models.config import (
|
||||
AddLogPathRequest,
|
||||
GlobalConfigResponse,
|
||||
GlobalConfigUpdate,
|
||||
JailConfigListResponse,
|
||||
JailConfigResponse,
|
||||
JailConfigUpdate,
|
||||
LogPreviewRequest,
|
||||
LogPreviewResponse,
|
||||
MapColorThresholdsResponse,
|
||||
MapColorThresholdsUpdate,
|
||||
RegexTestResponse,
|
||||
)
|
||||
from app.models.geo import GeoBatchLookup, GeoEnricher, GeoInfo
|
||||
from app.models.history import HistoryListResponse, IpDetailResponse
|
||||
from app.models.jail import JailDetailResponse, JailListResponse
|
||||
from app.models.server import ServerSettingsResponse, ServerSettingsUpdate, ServerStatus
|
||||
|
||||
|
||||
class AuthService(Protocol):
|
||||
@@ -51,8 +52,9 @@ class AuthService(Protocol):
|
||||
db: aiosqlite.Connection,
|
||||
password: str,
|
||||
session_duration_minutes: int,
|
||||
session_secret: str,
|
||||
session_repo: object | None = None,
|
||||
) -> Session:
|
||||
) -> tuple[str, str]:
|
||||
...
|
||||
|
||||
async def validate_session(
|
||||
|
||||
Reference in New Issue
Block a user