Files
MincedPad/backend/app/api/admin.py
T
2026-07-14 12:54:20 +08:00

102 lines
2.6 KiB
Python

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from sqlalchemy import select
from sqlalchemy.orm import Session
from app import config
from app.db import get_db
from app.models import BannedIP, Item
from app.security import create_access_token, require_admin
from app.services import items as items_service
router = APIRouter(prefix="/api/admin", tags=["admin"])
class LoginBody(BaseModel):
password: str
class BanCreate(BaseModel):
ip: str = Field(min_length=1)
reason: str = ""
@router.post("/login")
def login(body: LoginBody):
if body.password != config.settings.admin_password:
raise HTTPException(status_code=401, detail="Unauthorized")
return {"token": create_access_token()}
@router.get("/items")
def list_items(
_admin: dict = Depends(require_admin),
db: Session = Depends(get_db),
):
rows = list(db.scalars(select(Item).order_by(Item.created_at.desc())).all())
items = []
for item in rows:
data = items_service.item_to_dict(item)
data["id"] = item.id
data["created_ip"] = item.created_ip
data["burned"] = item.burned
items.append(data)
return {"items": items}
@router.delete("/items/{item_id}")
def delete_item(
item_id: int,
_admin: dict = Depends(require_admin),
db: Session = Depends(get_db),
):
item = db.get(Item, item_id)
if item is None:
raise HTTPException(status_code=404, detail="Not found")
items_service.delete_item_file(item)
db.delete(item)
db.commit()
return {"ok": True}
@router.get("/bans")
def list_bans(
_admin: dict = Depends(require_admin),
db: Session = Depends(get_db),
):
rows = list(db.scalars(select(BannedIP).order_by(BannedIP.created_at.desc())).all())
return {
"bans": [
{"ip": b.ip, "reason": b.reason, "created_at": b.created_at} for b in rows
]
}
@router.post("/bans")
def create_ban(
body: BanCreate,
_admin: dict = Depends(require_admin),
db: Session = Depends(get_db),
):
existing = db.get(BannedIP, body.ip)
if existing is None:
db.add(BannedIP(ip=body.ip, reason=body.reason or ""))
else:
existing.reason = body.reason or existing.reason
db.commit()
return {"ok": True}
@router.delete("/bans/{ip}")
def delete_ban(
ip: str,
_admin: dict = Depends(require_admin),
db: Session = Depends(get_db),
):
ban = db.get(BannedIP, ip)
if ban is None:
raise HTTPException(status_code=404, detail="Not found")
db.delete(ban)
db.commit()
return {"ok": True}