feat(auth): single-admin password login (signed cookie) — gate tuning + Sources catalog, keep chat and document viewer public
This commit is contained in:
+15
-3
@@ -13,6 +13,7 @@ from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.auth import require_admin
|
||||
from app.db import get_db
|
||||
from app.models import Chunk, Document
|
||||
from app.schemas import DocContent, DocList, DocSummary
|
||||
@@ -28,11 +29,17 @@ def doc_format(path: str) -> str:
|
||||
|
||||
|
||||
@router.get("/docs", response_model=DocList)
|
||||
def list_documents(db: Session = Depends(get_db)) -> DocList: # noqa: B008
|
||||
def list_documents(
|
||||
db: Session = Depends(get_db), # noqa: B008
|
||||
_admin: None = Depends(require_admin), # noqa: B008
|
||||
) -> DocList:
|
||||
"""All indexed documents with per-document chunk counts.
|
||||
|
||||
An empty list means the knowledge base has not been imported yet —
|
||||
the Sources page renders its designed empty state in that case.
|
||||
Admin-only (phase 16 — the catalog is what the sign-in gates; the
|
||||
document viewer itself stays public, see below). Anonymous callers
|
||||
get 403 ``admin only`` and the Sources page renders its sign-in gate
|
||||
instead. An empty list means the knowledge base has not been imported
|
||||
yet — the Sources page renders its designed empty state in that case.
|
||||
"""
|
||||
rows = db.execute(
|
||||
select(
|
||||
@@ -71,6 +78,11 @@ def get_document_content(
|
||||
Stateless (A10) and database-only: unknown pairs — including traversal
|
||||
strings such as ``../../etc/passwd`` — are just non-existent rows and
|
||||
map to 404 ``{detail: "document not found"}``.
|
||||
|
||||
Deliberately PUBLIC for anonymous callers (phase 16 soft rule, owner
|
||||
decision 2026-08-22): the *catalog* (``GET /api/docs``) is what the
|
||||
sign-in gates, not the viewer — chat cites documents and anyone may
|
||||
open a cited document by direct URL.
|
||||
"""
|
||||
row = db.execute(
|
||||
select(Document, func.count(Chunk.id).label("chunks"))
|
||||
|
||||
Reference in New Issue
Block a user