from __future__ import annotations from typing import Annotated from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel, Field from ..config import Settings, get_settings from ..credentials import get_credentials, update_credentials from .auth import LoginRequest, LoginResponse, issue_token, require_user router = APIRouter(prefix="/api/auth", tags=["auth"]) class ChangeCredentialsRequest(BaseModel): current_password: str = Field(min_length=1) new_username: str = Field(min_length=1, max_length=64) new_password: str = Field(min_length=4, max_length=128) @router.post("/login", response_model=LoginResponse) async def login(body: LoginRequest, settings: Annotated[Settings, Depends(get_settings)]) -> LoginResponse: user, pwd = get_credentials() if body.username != user or body.password != pwd: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户名或密码错误") token, ttl = issue_token(body.username, settings) return LoginResponse( token=token, username=body.username, expires_in=ttl, env_name=settings.env_name, mode=settings.mode, ) @router.get("/me") async def me(username: Annotated[str, Depends(require_user)], settings: Annotated[Settings, Depends(get_settings)]) -> dict: return { "username": username, "env_name": settings.env_name, "mode": settings.mode, "sim": settings.is_sim, } @router.post("/change-credentials", response_model=LoginResponse) async def change_credentials( body: ChangeCredentialsRequest, username: Annotated[str, Depends(require_user)], settings: Annotated[Settings, Depends(get_settings)], ) -> LoginResponse: _cur_user, cur_pwd = get_credentials() if body.current_password != cur_pwd: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="当前密码不正确") try: update_credentials(new_username=body.new_username, new_password=body.new_password) except ValueError as e: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) from e token, ttl = issue_token(body.new_username.strip(), settings) return LoginResponse( token=token, username=body.new_username.strip(), expires_in=ttl, env_name=settings.env_name, mode=settings.mode, )