from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from app.database import get_db from app.models import User from app.schemas import LoginRequest, TokenResponse, UserOut, UserCreate from app.auth import ( verify_password, hash_password, create_access_token, get_current_user, get_current_admin_user, ) router = APIRouter(prefix="/auth", tags=["auth"]) @router.post("/login", response_model=TokenResponse) async def login(body: LoginRequest, db: AsyncSession = Depends(get_db)): result = await db.execute(select(User).where(User.username == body.username)) user = result.scalars().first() if not user or not verify_password(body.password, user.password_hash): raise HTTPException(401, "Invalid username or password") token = create_access_token({"sub": str(user.id)}) return TokenResponse(access_token=token) @router.get("/me", response_model=UserOut) async def get_me(current_user: User = Depends(get_current_user)): return current_user @router.get("/users", response_model=list[UserOut]) async def list_users( db: AsyncSession = Depends(get_db), _admin: User = Depends(get_current_admin_user), ): result = await db.execute(select(User).order_by(User.username)) return result.scalars().all() @router.post("/users", response_model=UserOut, status_code=201) async def create_user( body: UserCreate, db: AsyncSession = Depends(get_db), _admin: User = Depends(get_current_admin_user), ): existing = await db.execute(select(User).where(User.username == body.username)) if existing.scalars().first(): raise HTTPException(409, "Username already exists") user = User( username=body.username, password_hash=hash_password(body.password), is_admin=False, ) db.add(user) await db.commit() await db.refresh(user) return user @router.delete("/users/{user_id}", status_code=204) async def delete_user( user_id: int, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_admin_user), ): if user_id == current_user.id: raise HTTPException(400, "Cannot delete your own account") result = await db.execute(select(User).where(User.id == user_id)) user = result.scalars().first() if not user: raise HTTPException(404, "User not found") await db.delete(user) await db.commit()