feat(admin): upload-material + delete-material endpoints with whitelist
This commit is contained in:
40
app/admin.py
40
app/admin.py
@@ -2,11 +2,12 @@ import csv
|
||||
import io
|
||||
from pathlib import Path
|
||||
|
||||
from fastapi import APIRouter, Depends, Query
|
||||
from fastapi import APIRouter, Depends, File, Form, HTTPException, Query, UploadFile
|
||||
from fastapi.responses import Response
|
||||
|
||||
from app.config import get_settings
|
||||
from app.db import list_leads, stats
|
||||
from app.frontend import ALLOWED_FILENAMES
|
||||
from app.security import require_admin
|
||||
|
||||
router = APIRouter(prefix="/admin", tags=["admin"])
|
||||
@@ -30,6 +31,43 @@ def admin_material_files(_user: str = Depends(require_admin)):
|
||||
return {"material_dir": str(material_dir), "exists": True, "files": files}
|
||||
|
||||
|
||||
@router.post("/upload-material")
|
||||
async def admin_upload_material(
|
||||
target_name: str = Form(...),
|
||||
file: UploadFile = File(...),
|
||||
_user: str = Depends(require_admin),
|
||||
):
|
||||
"""Sube un archivo al volumen /app/material/ con un nombre de la whitelist."""
|
||||
if target_name not in ALLOWED_FILENAMES:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail=f"target_name must be one of {sorted(ALLOWED_FILENAMES)}",
|
||||
)
|
||||
material_dir = Path(get_settings().material_dir)
|
||||
material_dir.mkdir(parents=True, exist_ok=True)
|
||||
dest = material_dir / target_name
|
||||
content = await file.read()
|
||||
dest.write_bytes(content)
|
||||
return {
|
||||
"saved_as": str(dest),
|
||||
"size_bytes": len(content),
|
||||
"size_mb": round(len(content) / (1024 * 1024), 2),
|
||||
"original_filename": file.filename,
|
||||
}
|
||||
|
||||
|
||||
@router.delete("/material-files/{filename}")
|
||||
def admin_delete_material(filename: str, _user: str = Depends(require_admin)):
|
||||
"""Borra un archivo del volumen material/."""
|
||||
if filename not in ALLOWED_FILENAMES:
|
||||
raise HTTPException(status_code=400, detail="filename not in whitelist")
|
||||
path = Path(get_settings().material_dir) / filename
|
||||
if not path.exists():
|
||||
raise HTTPException(status_code=404, detail="file not found")
|
||||
path.unlink()
|
||||
return {"deleted": filename}
|
||||
|
||||
|
||||
@router.get("/leads.json")
|
||||
def admin_leads_json(
|
||||
_user: str = Depends(require_admin),
|
||||
|
||||
Reference in New Issue
Block a user