"""Auth API endpoints""" import os import bcrypt from fastapi import APIRouter, HTTPException, Depends, status from pydantic import BaseModel from .jwt_handler import create_access_token from .dependencies import get_current_user router = APIRouter(prefix="/api/auth", tags=["auth"]) # Default credentials (should be changed on first login) DEFAULT_USERNAME = "admin" DEFAULT_PASSWORD = "admin123" class LoginRequest(BaseModel): username: str password: str class LoginResponse(BaseModel): access_token: str token_type: str = "bearer" def _get_credentials() -> tuple[str, bytes]: """Get username and password hash from config or defaults""" try: from app.config.settings import ConfigManager cfg = ConfigManager() username = cfg.get('WebAuth', 'username', fallback=DEFAULT_USERNAME) pw_hash = cfg.get('WebAuth', 'password_hash', fallback='') if not pw_hash: # First run: store default password hash pw_hash = bcrypt.hashpw(DEFAULT_PASSWORD.encode(), bcrypt.gensalt()).decode() try: cfg.update('WebAuth', 'username', DEFAULT_USERNAME) cfg.update('WebAuth', 'password_hash', pw_hash) cfg.save_config() except Exception: pass return username, pw_hash.encode() except Exception: return DEFAULT_USERNAME, bcrypt.hashpw(DEFAULT_PASSWORD.encode(), bcrypt.gensalt()) @router.post("/login", response_model=LoginResponse) async def login(req: LoginRequest): stored_username, stored_hash = _get_credentials() if req.username != stored_username: raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户名或密码错误") if not bcrypt.checkpw(req.password.encode(), stored_hash): raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="用户名或密码错误") token = create_access_token({"sub": req.username}) return LoginResponse(access_token=token) @router.get("/me") async def me(current_user: dict = Depends(get_current_user)): return current_user class ChangePasswordRequest(BaseModel): old_password: str new_password: str @router.post("/change-password") async def change_password(req: ChangePasswordRequest, current_user: dict = Depends(get_current_user)): _, stored_hash = _get_credentials() if not bcrypt.checkpw(req.old_password.encode(), stored_hash): raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="旧密码错误") new_hash = bcrypt.hashpw(req.new_password.encode(), bcrypt.gensalt()).decode() try: from app.config.settings import ConfigManager cfg = ConfigManager() cfg.update('WebAuth', 'password_hash', new_hash) cfg.save_config() except Exception as e: raise HTTPException(status_code=500, detail=f"保存密码失败: {e}") return {"message": "密码修改成功"}