| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- import os
- import shutil
- from typing import Annotated
- from fastapi import APIRouter, Depends, HTTPException, UploadFile, File
- from app.api.v1 import deps
- from app.models.user import User, UserRole
- router = APIRouter()
- CERTS_DIR = "/app/certs"
- CRT_FILENAME = "server.crt"
- KEY_FILENAME = "server.key"
- @router.post("/ssl/config", summary="更新SSL证书")
- async def update_ssl_config(
- crt_file: Annotated[UploadFile, File(description="证书文件 (.crt/.pem)")],
- key_file: Annotated[UploadFile, File(description="私钥文件 (.key)")],
- current_user: User = Depends(deps.get_current_active_user),
- ):
- """
- 上传并更新SSL证书。
- 证书文件将保存到共享卷中,Nginx会自动检测变化并重载。
- 需要超级管理员权限。
- """
- if current_user.role != UserRole.SUPER_ADMIN:
- raise HTTPException(status_code=403, detail="权限不足")
- # 确保目录存在
- os.makedirs(CERTS_DIR, exist_ok=True)
-
- crt_path = os.path.join(CERTS_DIR, CRT_FILENAME)
- key_path = os.path.join(CERTS_DIR, KEY_FILENAME)
-
- # 简单的文件扩展名检查 (可以根据需要增强)
- if not crt_file.filename.endswith(('.crt', '.pem', '.cer')):
- raise HTTPException(status_code=400, detail="证书文件格式不正确,请上传 .crt, .pem 或 .cer 文件")
-
- if not key_file.filename.endswith(('.key', '.pem')):
- raise HTTPException(status_code=400, detail="私钥文件格式不正确,请上传 .key 或 .pem 文件")
- try:
- # 保存证书文件
- with open(crt_path, "wb") as buffer:
- shutil.copyfileobj(crt_file.file, buffer)
-
- # 保存私钥文件
- with open(key_path, "wb") as buffer:
- shutil.copyfileobj(key_file.file, buffer)
-
- except Exception as e:
- raise HTTPException(status_code=500, detail=f"保存证书文件失败: {str(e)}")
-
- return {"message": "SSL证书已更新,Nginx将自动重新加载配置。"}
|