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}