- 新增完整的 Python 实现,替代 Go 版本 - 添加 Web 登录界面和仪表板 - 实现 JWT 认证和 API 密钥管理 - 添加数据库存储功能 - 保持与 Go 版本一致的目录结构和启动脚本 - 包含完整的文档和测试脚本
122 lines
3.1 KiB
Python
122 lines
3.1 KiB
Python
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from fastapi.security import HTTPBearer
|
|
from sqlalchemy.orm import Session
|
|
from pydantic import BaseModel
|
|
from typing import List, Optional
|
|
import os
|
|
|
|
from ..models.database import get_db, APIKey
|
|
from ..auth.middleware import auth_middleware
|
|
|
|
router = APIRouter(prefix="/api/auth", tags=["authentication"])
|
|
|
|
# 请求/响应模型
|
|
class LoginRequest(BaseModel):
|
|
secret_key: str
|
|
|
|
class LoginResponse(BaseModel):
|
|
token: str
|
|
|
|
class APIKeyCreate(BaseModel):
|
|
description: str
|
|
|
|
class APIKeyResponse(BaseModel):
|
|
id: int
|
|
key: str
|
|
description: Optional[str]
|
|
created_at: str
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
class APIKeyList(BaseModel):
|
|
keys: List[APIKeyResponse]
|
|
|
|
# 获取管理员密钥
|
|
def get_admin_secret_key():
|
|
return os.getenv("ADMIN_SECRET_KEY", "admin-secret-key-change-in-production")
|
|
|
|
@router.post("/login", response_model=LoginResponse)
|
|
async def login(request: LoginRequest):
|
|
"""管理员登录"""
|
|
admin_key = get_admin_secret_key()
|
|
|
|
if request.secret_key != admin_key:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
detail="Invalid secret key"
|
|
)
|
|
|
|
# 生成 JWT 令牌
|
|
token = auth_middleware.create_access_token(
|
|
data={"sub": "admin", "role": "admin"}
|
|
)
|
|
|
|
return LoginResponse(token=token)
|
|
|
|
@router.post("/keys", response_model=APIKeyResponse)
|
|
async def create_api_key(
|
|
request: APIKeyCreate,
|
|
db: Session = Depends(get_db),
|
|
current_user: dict = Depends(auth_middleware.get_current_user)
|
|
):
|
|
"""创建新的 API 密钥"""
|
|
# 生成新的 API 密钥
|
|
api_key_value = auth_middleware.generate_api_key()
|
|
|
|
# 保存到数据库
|
|
db_key = APIKey(
|
|
key=api_key_value,
|
|
description=request.description
|
|
)
|
|
|
|
db.add(db_key)
|
|
db.commit()
|
|
db.refresh(db_key)
|
|
|
|
return APIKeyResponse(
|
|
id=db_key.id,
|
|
key=db_key.key,
|
|
description=db_key.description,
|
|
created_at=db_key.created_at.isoformat()
|
|
)
|
|
|
|
@router.get("/keys", response_model=APIKeyList)
|
|
async def list_api_keys(
|
|
db: Session = Depends(get_db),
|
|
current_user: dict = Depends(auth_middleware.get_current_user)
|
|
):
|
|
"""获取所有 API 密钥"""
|
|
keys = db.query(APIKey).order_by(APIKey.created_at.desc()).all()
|
|
|
|
return APIKeyList(
|
|
keys=[
|
|
APIKeyResponse(
|
|
id=key.id,
|
|
key=key.key,
|
|
description=key.description,
|
|
created_at=key.created_at.isoformat()
|
|
)
|
|
for key in keys
|
|
]
|
|
)
|
|
|
|
@router.delete("/keys/{key_id}")
|
|
async def delete_api_key(
|
|
key_id: int,
|
|
db: Session = Depends(get_db),
|
|
current_user: dict = Depends(auth_middleware.get_current_user)
|
|
):
|
|
"""删除 API 密钥"""
|
|
key = db.query(APIKey).filter(APIKey.id == key_id).first()
|
|
|
|
if not key:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_404_NOT_FOUND,
|
|
detail="API key not found"
|
|
)
|
|
|
|
db.delete(key)
|
|
db.commit()
|
|
|
|
return {"message": "API key deleted successfully"} |