"""Admin router endpoints.""" from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, update from typing import Optional, List from datetime import datetime from app.core.database import get_db from app.core.security import get_current_user from app.models.models import User, Ban, GameLog, AuditLog from app.schemas.schemas import BanCreate, BanResponse router = APIRouter() @router.get("/users", response_model=List[dict]) async def list_users( page: int = 1, page_size: int = 50, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """List all users (admin only).""" # Check if current user is admin if current_user.get("privlevel") not in ["Admin", "Judge"]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin privileges required", ) stmt = ( select(User) .order_by(User.id) .offset((page - 1) * page_size) .limit(page_size) ) result = await db.execute(stmt) users = result.scalars().all() return [ { "id": user.id, "username": user.username, "email": user.email, "privlevel": user.privlevel, "is_active": user.is_active, "is_banned": user.is_banned, "vip_status": user.vip_status, "creation_date": user.creation_date, } for user in users ] @router.get("/bans", response_model=List[BanResponse]) async def list_bans( active_only: bool = True, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """List all bans (admin only).""" # Check if current user is admin if current_user.get("privlevel") not in ["Admin", "Judge"]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin privileges required", ) stmt = select(Ban).order_by(Ban.id) if active_only: stmt = stmt.where(Ban.active == True) result = await db.execute(stmt) bans = result.scalars().all() return [BanResponse.model_validate(ban) for ban in bans] @router.post("/bans", response_model=BanResponse) async def create_ban( request: BanCreate, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """Create a ban (admin only).""" # Check if current user is admin if current_user.get("privlevel") not in ["Admin", "Judge"]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin privileges required", ) new_ban = Ban( user_id=request.user_id, reason=request.reason, expiration_time=request.expiration_time, moderators=current_user.get("username"), ip_address=None, # Would get from request ) db.add(new_ban) await db.flush() return BanResponse.model_validate(new_ban) @router.post("/bans/{ban_id}/unban") async def unban( ban_id: int, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """Unban a user (admin only).""" # Check if current user is admin if current_user.get("privlevel") not in ["Admin", "Judge"]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin privileges required", ) stmt = select(Ban).where(Ban.id == ban_id) result = await db.execute(stmt) ban = result.scalar_one_or_none() if not ban: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Ban not found", ) # Deactivate ban stmt = ( update(Ban) .where(Ban.id == ban_id) .values(active=False) ) await db.execute(stmt) # Also unban the user stmt = ( update(User) .where(User.id == ban.user_id) .values( is_banned=False, ban_reason=None, ban_ends=None, ) ) await db.execute(stmt) return {"message": "User unbanned successfully"} @router.get("/logs", response_model=List[dict]) async def list_logs( room_id: Optional[int] = None, limit: int = 100, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """List game logs (admin only).""" # Check if current user is admin if current_user.get("privlevel") not in ["Admin", "Judge"]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin privileges required", ) stmt = select(GameLog).order_by(GameLog.id.desc()).limit(limit) if room_id: stmt = stmt.where(GameLog.room_id == room_id) result = await db.execute(stmt) logs = result.scalars().all() return [ { "id": log.id, "room_id": log.room_id, "player_id": log.player_id, "message": log.message, "timestamp": log.timestamp, } for log in logs ] @router.post("/audit", response_model=dict) async def log_audit( action_type: str, target_user_id: Optional[int] = None, details: Optional[str] = None, db: AsyncSession = Depends(get_db), current_user: dict = Depends(get_current_user), ): """Create an audit log entry (admin only).""" # Check if current user is admin if current_user.get("privlevel") not in ["Admin", "Judge"]: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin privileges required", ) new_audit = AuditLog( admin_id=int(current_user["user_id"]), action_type=action_type, target_user_id=target_user_id, details=details, ip_address=None, # Would get from request ) db.add(new_audit) await db.flush() return { "id": new_audit.id, "admin_id": new_audit.admin_id, "action_type": new_audit.action_type, "target_user_id": new_audit.target_user_id, "details": new_audit.details, "timestamp": new_audit.timestamp, }