refactor: 将访问令牌功能迁移至模块系统

- 新增 management_tokens 模块定义,支持通过环境变量控制可用性
- 从静态路由中移除 management-tokens,改由模块动态注册
- 前端路由添加模块激活检查,未激活时重定向到仪表盘
- 认证服务添加模块激活检查,未激活时禁止令牌认证
- 导航菜单中移除访问令牌入口(保留直接 URL 访问)
- 修复 alembic 迁移脚本格式和错误处理
This commit is contained in:
fawney19
2026-02-05 16:32:27 +08:00
parent 440721368f
commit 5be7813ab8
8 changed files with 210 additions and 77 deletions

View File

@@ -6,14 +6,13 @@ from .adaptive import router as adaptive_router
from .api_keys import router as api_keys_router
from .billing import router as billing_router
from .endpoints import router as endpoints_router
from .management_tokens import router as management_tokens_router
from .models import router as models_router
from .modules import router as modules_router
from .monitoring import router as monitoring_router
from .provider_oauth import router as provider_oauth_router
from .provider_ops import router as provider_ops_router
from .provider_query import router as provider_query_router
from .provider_strategy import router as provider_strategy_router
from .provider_oauth import router as provider_oauth_router
from .providers import router as providers_router
from .security import router as security_router
from .stats import router as stats_router
@@ -38,12 +37,12 @@ router.include_router(models_router)
router.include_router(security_router)
router.include_router(stats_router)
router.include_router(provider_query_router)
router.include_router(management_tokens_router)
router.include_router(modules_router)
router.include_router(provider_ops_router)
router.include_router(video_tasks_router)
# 注意:ldap_router 已迁移到模块系统,由 ModuleRegistry 动态注册
# 当 LDAP_AVAILABLE=true 时才会注册路由
# 注意:以下路由已迁移到模块系统,由 ModuleRegistry 动态注册
# - ldap_router: 当 LDAP_AVAILABLE=true 时注册
# - management_tokens_router: 当 MANAGEMENT_TOKENS_AVAILABLE=true 时注册
__all__ = ["router"]

View File

@@ -2,11 +2,12 @@
from fastapi import APIRouter
from .management_tokens import router as management_tokens_router
from .routes import router as me_router
router = APIRouter()
router.include_router(me_router)
router.include_router(management_tokens_router)
# 注意management_tokens_router 已迁移到模块系统,由 ModuleRegistry 动态注册
# 当 MANAGEMENT_TOKENS_AVAILABLE=true 时注册
__all__ = ["router"]

View File

@@ -9,6 +9,7 @@ from src.core.modules.base import ModuleDefinition
# 导入所有模块定义
from src.modules.gemini_files import gemini_files_module
from src.modules.ldap import ldap_module
from src.modules.management_tokens import management_tokens_module
from src.modules.oauth import oauth_module
# 所有模块列表
@@ -16,6 +17,7 @@ ALL_MODULES: list[ModuleDefinition] = [
ldap_module,
oauth_module,
gemini_files_module,
management_tokens_module,
]
__all__ = ["ALL_MODULES"]

View File

@@ -0,0 +1,78 @@
"""
访问令牌模块
提供管理 API 访问令牌的功能
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from fastapi import APIRouter
from src.core.modules.base import (
ModuleCategory,
ModuleDefinition,
ModuleHealth,
ModuleMetadata,
)
if TYPE_CHECKING:
from sqlalchemy.orm import Session
def _get_router() -> Any:
"""延迟导入路由(避免启动时加载重依赖)
返回一个合并了管理员和用户两个路由的 APIRouter
- /api/admin/management-tokens: 管理员管理所有用户的令牌
- /api/me/management-tokens: 用户管理自己的令牌
"""
from src.api.admin.management_tokens import router as admin_router
from src.api.user_me.management_tokens import router as user_router
# 创建一个组合路由器
combined_router = APIRouter()
combined_router.include_router(admin_router)
combined_router.include_router(user_router)
return combined_router
async def _health_check() -> ModuleHealth:
"""健康检查 - 简化版,不依赖数据库连接"""
return ModuleHealth.HEALTHY
def _validate_config(db: Session) -> tuple[bool, str]:
"""
验证配置是否可以启用模块
访问令牌模块没有特殊配置要求,始终可用
"""
return True, ""
# 访问令牌模块定义
management_tokens_module = ModuleDefinition(
metadata=ModuleMetadata(
name="management_tokens",
display_name="访问令牌",
description="管理 API 访问令牌,支持细粒度权限控制和 IP 白名单",
category=ModuleCategory.SECURITY,
# 可用性控制
env_key="MANAGEMENT_TOKENS_AVAILABLE",
default_available=True,
required_packages=[],
# 路由配置
api_prefix="/api/admin/management-tokens, /api/me/management-tokens",
# 前端配置 - 不在导航栏显示,但保留路由用于直接访问
admin_route="/admin/management-tokens",
admin_menu_icon=None,
admin_menu_group=None, # 不显示在导航菜单中
admin_menu_order=0,
),
router_factory=_get_router,
health_check=_health_check,
validate_config=_validate_config,
)

View File

@@ -614,10 +614,17 @@ class AuthService:
RateLimitException: 超过速率限制时抛出(用于返回 429
"""
from src.core.exceptions import RateLimitException
from src.core.modules import get_module_registry
from src.models.database import AuditEventType, ManagementToken
from src.services.rate_limit.ip_limiter import IPRateLimiter
from src.services.system.audit import AuditService
# 检查访问令牌模块是否激活
module_registry = get_module_registry()
if not module_registry.is_active("management_tokens", db):
logger.warning("Management Token 认证失败 - 访问令牌模块未激活")
return None
# 速率限制检查(防止暴力破解)
allowed, remaining, ttl = await IPRateLimiter.check_limit(
client_ip,