Files
webmail-client/backend/app/api/admin.py
T

57 lines
1.9 KiB
Python
Raw Normal View History

"""Instance administration (SPEC §6.1).
The backend seam for the admin panel. Today it carries only the registration
gate — the first account on a fresh install becomes the administrator and closes
signup behind itself, and this is how that gets reopened. Further instance-wide
options land here as the panel grows.
"""
from __future__ import annotations
import datetime as dt
from typing import Annotated
from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from app.db import get_session
from app.identity.deps import CurrentAdmin, require_csrf
from app.identity.schemas import AdminSettingsIn, AdminSettingsOut
from app.identity.service import app_settings
from app.models import AppSettings
router = APIRouter(prefix="/admin", tags=["admin"])
DbSession = Annotated[AsyncSession, Depends(get_session)]
def _out(row: AppSettings) -> AdminSettingsOut:
return AdminSettingsOut(
registration_open=row.registration_open,
default_quota_bytes=row.default_quota_bytes,
)
@router.get("/settings", response_model=AdminSettingsOut)
async def read_settings(admin: CurrentAdmin, db: DbSession) -> AdminSettingsOut:
return _out(await app_settings(db))
@router.put("/settings", response_model=AdminSettingsOut, dependencies=[Depends(require_csrf)])
async def write_settings(
body: AdminSettingsIn, admin: CurrentAdmin, db: DbSession
) -> AdminSettingsOut:
"""Merge the supplied fields into the settings row.
Changing ``default_quota_bytes`` affects users created afterwards only —
nothing here rewrites an existing ``users.quota_bytes``.
"""
row = await app_settings(db, for_update=True)
if body.registration_open is not None:
row.registration_open = body.registration_open
if body.default_quota_bytes is not None:
row.default_quota_bytes = body.default_quota_bytes
row.updated_at = dt.datetime.now(dt.UTC)
await db.commit()
return _out(row)