mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
refactor: 移除 Python 后端源码,全面迁移至 Rust gateway 架构
- 删除全部 Python 源码 (src/) 及 Alembic 迁移脚本,归档至 _deprecated_py_src/ - 重构 Rust gateway ai_pipeline: 拆分 planner/finalize 模块,新增 contracts/adaptation 层 - 重组 handlers 模块为 admin/public/proxy/internal/shared 子模块结构 - 新增 executor 模块,引入 Rust 原生数据库迁移 (aether-data/migrations) - 简化 CI/Docker 构建流程,移除 base image 二级构建,统一为单一 app image - 移除 Python 相关基础设施文件 (entrypoint.sh, gunicorn_conf.py, Dockerfile.base)
This commit is contained in:
276
_deprecated_py_src/api/admin/security/ip_management.py
Normal file
276
_deprecated_py_src/api/admin/security/ip_management.py
Normal file
@@ -0,0 +1,276 @@
|
||||
"""
|
||||
IP 安全管理接口
|
||||
|
||||
提供 IP 黑白名单管理和速率限制统计
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
||||
from pydantic import BaseModel, Field, ValidationError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from src.api.base.adapter import ApiMode
|
||||
from src.api.base.authenticated_adapter import AuthenticatedApiAdapter
|
||||
from src.api.base.context import ApiRequestContext
|
||||
from src.api.base.pipeline import get_pipeline
|
||||
from src.core.exceptions import InvalidRequestException, translate_pydantic_error
|
||||
from src.database import get_db
|
||||
from src.services.rate_limit.ip_limiter import IPRateLimiter
|
||||
|
||||
router = APIRouter(prefix="/api/admin/security/ip", tags=["Admin - Security"])
|
||||
pipeline = get_pipeline()
|
||||
|
||||
|
||||
# ========== Pydantic 模型 ==========
|
||||
|
||||
|
||||
class AddIPToBlacklistRequest(BaseModel):
|
||||
"""添加 IP 到黑名单请求"""
|
||||
|
||||
ip_address: str = Field(..., description="IP 地址")
|
||||
reason: str = Field(..., min_length=1, max_length=200, description="加入黑名单的原因")
|
||||
ttl: int | None = Field(None, gt=0, description="过期时间(秒),None 表示永久")
|
||||
|
||||
|
||||
class RemoveIPFromBlacklistRequest(BaseModel):
|
||||
"""从黑名单移除 IP 请求"""
|
||||
|
||||
ip_address: str = Field(..., description="IP 地址")
|
||||
|
||||
|
||||
class AddIPToWhitelistRequest(BaseModel):
|
||||
"""添加 IP 到白名单请求"""
|
||||
|
||||
ip_address: str = Field(..., description="IP 地址或 CIDR 格式(如 192.168.1.0/24)")
|
||||
|
||||
|
||||
class RemoveIPFromWhitelistRequest(BaseModel):
|
||||
"""从白名单移除 IP 请求"""
|
||||
|
||||
ip_address: str = Field(..., description="IP 地址")
|
||||
|
||||
|
||||
# ========== API 端点 ==========
|
||||
|
||||
|
||||
@router.post("/blacklist")
|
||||
async def add_to_blacklist(request: Request, db: Session = Depends(get_db)) -> None:
|
||||
"""
|
||||
添加 IP 到黑名单
|
||||
|
||||
将指定 IP 地址添加到黑名单,被加入黑名单的 IP 将无法访问系统。需要管理员权限。
|
||||
|
||||
**请求体字段**:
|
||||
- `ip_address`: IP 地址
|
||||
- `reason`: 加入黑名单的原因
|
||||
- `ttl`: 可选,过期时间(秒),不指定表示永久
|
||||
|
||||
**返回字段**:
|
||||
- `success`: 是否成功
|
||||
- `message`: 操作结果信息
|
||||
- `reason`: 加入黑名单的原因
|
||||
- `ttl`: 过期时间(秒或"永久")
|
||||
"""
|
||||
adapter = AddToBlacklistAdapter()
|
||||
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=ApiMode.ADMIN)
|
||||
|
||||
|
||||
@router.delete("/blacklist/{ip_address}")
|
||||
async def remove_from_blacklist(
|
||||
ip_address: str, request: Request, db: Session = Depends(get_db)
|
||||
) -> None:
|
||||
"""
|
||||
从黑名单移除 IP
|
||||
|
||||
将指定 IP 地址从黑名单中移除。需要管理员权限。
|
||||
|
||||
**路径参数**:
|
||||
- `ip_address`: IP 地址
|
||||
|
||||
**返回字段**:
|
||||
- `success`: 是否成功
|
||||
- `message`: 操作结果信息
|
||||
"""
|
||||
adapter = RemoveFromBlacklistAdapter(ip_address=ip_address)
|
||||
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=ApiMode.ADMIN)
|
||||
|
||||
|
||||
@router.get("/blacklist/stats")
|
||||
async def get_blacklist_stats(request: Request, db: Session = Depends(get_db)) -> Any:
|
||||
"""
|
||||
获取黑名单统计信息
|
||||
|
||||
获取黑名单的统计信息和列表。需要管理员权限。
|
||||
|
||||
**返回字段**:
|
||||
- `total`: 黑名单总数
|
||||
- `items`: 黑名单列表,每个项包含:
|
||||
- `ip`: IP 地址
|
||||
- `reason`: 加入原因
|
||||
- `added_at`: 添加时间
|
||||
- `ttl`: 剩余有效时间(秒)
|
||||
"""
|
||||
adapter = GetBlacklistStatsAdapter()
|
||||
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=ApiMode.ADMIN)
|
||||
|
||||
|
||||
@router.post("/whitelist")
|
||||
async def add_to_whitelist(request: Request, db: Session = Depends(get_db)) -> None:
|
||||
"""
|
||||
添加 IP 到白名单
|
||||
|
||||
将指定 IP 地址或 CIDR 网段添加到白名单,白名单中的 IP 将跳过速率限制检查。需要管理员权限。
|
||||
|
||||
**请求体字段**:
|
||||
- `ip_address`: IP 地址或 CIDR 格式(如 192.168.1.0/24)
|
||||
|
||||
**返回字段**:
|
||||
- `success`: 是否成功
|
||||
- `message`: 操作结果信息
|
||||
"""
|
||||
adapter = AddToWhitelistAdapter()
|
||||
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=ApiMode.ADMIN)
|
||||
|
||||
|
||||
@router.delete("/whitelist/{ip_address}")
|
||||
async def remove_from_whitelist(
|
||||
ip_address: str, request: Request, db: Session = Depends(get_db)
|
||||
) -> None:
|
||||
"""
|
||||
从白名单移除 IP
|
||||
|
||||
将指定 IP 地址从白名单中移除。需要管理员权限。
|
||||
|
||||
**路径参数**:
|
||||
- `ip_address`: IP 地址
|
||||
|
||||
**返回字段**:
|
||||
- `success`: 是否成功
|
||||
- `message`: 操作结果信息
|
||||
"""
|
||||
adapter = RemoveFromWhitelistAdapter(ip_address=ip_address)
|
||||
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=ApiMode.ADMIN)
|
||||
|
||||
|
||||
@router.get("/whitelist")
|
||||
async def get_whitelist(request: Request, db: Session = Depends(get_db)) -> Any:
|
||||
"""
|
||||
获取白名单
|
||||
|
||||
获取当前的 IP 白名单列表。需要管理员权限。
|
||||
|
||||
**返回字段**:
|
||||
- `whitelist`: 白名单 IP 地址列表
|
||||
- `total`: 白名单总数
|
||||
"""
|
||||
adapter = GetWhitelistAdapter()
|
||||
return await pipeline.run(adapter=adapter, http_request=request, db=db, mode=ApiMode.ADMIN)
|
||||
|
||||
|
||||
# ========== 适配器实现 ==========
|
||||
|
||||
|
||||
class AddToBlacklistAdapter(AuthenticatedApiAdapter):
|
||||
"""添加 IP 到黑名单适配器"""
|
||||
|
||||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||||
payload = context.ensure_json_body()
|
||||
try:
|
||||
req = AddIPToBlacklistRequest.model_validate(payload)
|
||||
except ValidationError as e:
|
||||
errors = e.errors()
|
||||
if errors:
|
||||
raise InvalidRequestException(translate_pydantic_error(errors[0]))
|
||||
raise InvalidRequestException("请求数据验证失败")
|
||||
|
||||
success = await IPRateLimiter.add_to_blacklist(req.ip_address, req.reason, req.ttl)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="添加 IP 到黑名单失败(Redis 不可用)",
|
||||
)
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"IP {req.ip_address} 已加入黑名单",
|
||||
"reason": req.reason,
|
||||
"ttl": req.ttl or "永久",
|
||||
}
|
||||
|
||||
|
||||
class RemoveFromBlacklistAdapter(AuthenticatedApiAdapter):
|
||||
"""从黑名单移除 IP 适配器"""
|
||||
|
||||
def __init__(self, ip_address: str):
|
||||
self.ip_address = ip_address
|
||||
|
||||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||||
success = await IPRateLimiter.remove_from_blacklist(self.ip_address)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=f"IP {self.ip_address} 不在黑名单中"
|
||||
)
|
||||
|
||||
return {"success": True, "message": f"IP {self.ip_address} 已从黑名单移除"}
|
||||
|
||||
|
||||
class GetBlacklistStatsAdapter(AuthenticatedApiAdapter):
|
||||
"""获取黑名单统计适配器"""
|
||||
|
||||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||||
stats = await IPRateLimiter.get_blacklist_stats()
|
||||
return stats
|
||||
|
||||
|
||||
class AddToWhitelistAdapter(AuthenticatedApiAdapter):
|
||||
"""添加 IP 到白名单适配器"""
|
||||
|
||||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||||
payload = context.ensure_json_body()
|
||||
try:
|
||||
req = AddIPToWhitelistRequest.model_validate(payload)
|
||||
except ValidationError as e:
|
||||
errors = e.errors()
|
||||
if errors:
|
||||
raise InvalidRequestException(translate_pydantic_error(errors[0]))
|
||||
raise InvalidRequestException("请求数据验证失败")
|
||||
|
||||
success = await IPRateLimiter.add_to_whitelist(req.ip_address)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"添加 IP 到白名单失败(无效的 IP 格式或 Redis 不可用)",
|
||||
)
|
||||
|
||||
return {"success": True, "message": f"IP {req.ip_address} 已加入白名单"}
|
||||
|
||||
|
||||
class RemoveFromWhitelistAdapter(AuthenticatedApiAdapter):
|
||||
"""从白名单移除 IP 适配器"""
|
||||
|
||||
def __init__(self, ip_address: str):
|
||||
self.ip_address = ip_address
|
||||
|
||||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||||
success = await IPRateLimiter.remove_from_whitelist(self.ip_address)
|
||||
|
||||
if not success:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail=f"IP {self.ip_address} 不在白名单中"
|
||||
)
|
||||
|
||||
return {"success": True, "message": f"IP {self.ip_address} 已从白名单移除"}
|
||||
|
||||
|
||||
class GetWhitelistAdapter(AuthenticatedApiAdapter):
|
||||
"""获取白名单适配器"""
|
||||
|
||||
async def handle(self, context: ApiRequestContext) -> Any: # type: ignore[override]
|
||||
whitelist = await IPRateLimiter.get_whitelist()
|
||||
return {"whitelist": list(whitelist), "total": len(whitelist)}
|
||||
Reference in New Issue
Block a user