57 lines
1.9 KiB
Python
57 lines
1.9 KiB
Python
"""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)
|