from typing import Annotated from fastapi import APIRouter, Depends, Request from sqlalchemy.engine import Connection from core.auth.schemas import ( ChangePasswordRequest, CreateUserRequest, LoginRequest, ) from core.auth.service import AuthService from database import get_db from dependencies import get_current_user, require_admin router = APIRouter(prefix="/auth", tags=["auth"]) # Rate limiter will be attached after main.py is imported _limiter = None def _ok(data): return {"success": True, "data": data, "error": None} @router.post("/login") def login( request: Request, body: LoginRequest, db: Annotated[Connection, Depends(get_db)], ): return _ok(AuthService(db).login(body.username, body.password)) @router.post("/logout") def logout(user: Annotated[dict, Depends(get_current_user)]): # Client-side token deletion. No server-side blacklist. return _ok({"message": "Logged out"}) @router.get("/me") def me(user: Annotated[dict, Depends(get_current_user)]): return _ok({"id": user["id"], "username": user["username"], "role": user["role"]}) @router.put("/password") def change_password( body: ChangePasswordRequest, user: Annotated[dict, Depends(get_current_user)], db: Annotated[Connection, Depends(get_db)], ): AuthService(db).change_password(user["id"], body.current_password, body.new_password) return _ok({"message": "Password changed"}) @router.get("/users") def list_users( _admin: Annotated[dict, Depends(require_admin)], db: Annotated[Connection, Depends(get_db)], ): return _ok(AuthService(db).list_users()) @router.post("/users", status_code=201) def create_user( body: CreateUserRequest, _admin: Annotated[dict, Depends(require_admin)], db: Annotated[Connection, Depends(get_db)], ): user = AuthService(db).create_user(body.username, body.password, body.role) return _ok(user) @router.delete("/users/{user_id}", status_code=204) def delete_user( user_id: int, admin: Annotated[dict, Depends(require_admin)], db: Annotated[Connection, Depends(get_db)], ): AuthService(db).delete_user(user_id, admin["id"])