mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +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:
193
_deprecated_py_src/modules/ldap/__init__.py
Normal file
193
_deprecated_py_src/modules/ldap/__init__.py
Normal file
@@ -0,0 +1,193 @@
|
||||
"""
|
||||
LDAP 认证模块
|
||||
|
||||
提供 LDAP/Active Directory 用户认证支持
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from src.core.modules.base import (
|
||||
ModuleCategory,
|
||||
ModuleDefinition,
|
||||
ModuleHealth,
|
||||
ModuleMetadata,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
||||
def _get_router() -> Any:
|
||||
"""延迟导入路由(避免启动时加载重依赖)"""
|
||||
from src.api.admin.ldap import router
|
||||
|
||||
return router
|
||||
|
||||
|
||||
async def _health_check() -> ModuleHealth:
|
||||
"""健康检查 - 简化版,不依赖数据库连接"""
|
||||
# 健康检查在启动时调用,此时可能没有数据库会话
|
||||
# 返回 UNKNOWN 表示需要进一步检查
|
||||
return ModuleHealth.UNKNOWN
|
||||
|
||||
|
||||
def _validate_config(db: Session) -> tuple[bool, str]:
|
||||
"""
|
||||
验证 LDAP 配置是否可以启用模块
|
||||
|
||||
检查项:
|
||||
1. 配置是否存在
|
||||
2. 必填字段是否完整
|
||||
3. 绑定密码是否可解密
|
||||
|
||||
注意:不在此处执行连接测试,因为 validate_config 会在每次查询模块状态时调用,
|
||||
同步阻塞等待 LDAP 服务器响应会严重影响性能。连接测试应在专门的测试接口中进行。
|
||||
"""
|
||||
from src.core.crypto import crypto_service
|
||||
from src.models.database import LDAPConfig
|
||||
|
||||
config = db.query(LDAPConfig).first()
|
||||
if not config:
|
||||
return False, "请先配置 LDAP 连接信息"
|
||||
|
||||
# 检查必填字段
|
||||
if not config.server_url:
|
||||
return False, "请配置 LDAP 服务器地址"
|
||||
if not config.bind_dn:
|
||||
return False, "请配置绑定 DN"
|
||||
if not config.base_dn:
|
||||
return False, "请配置搜索基准 DN"
|
||||
if not config.bind_password_encrypted:
|
||||
return False, "请配置绑定密码"
|
||||
|
||||
# 尝试解密密码(仅验证可解密,不执行连接测试)
|
||||
try:
|
||||
bind_password = crypto_service.decrypt(config.bind_password_encrypted)
|
||||
if not bind_password:
|
||||
return False, "绑定密码为空,请重新设置"
|
||||
except Exception:
|
||||
return False, "绑定密码解密失败,请重新设置"
|
||||
|
||||
return True, ""
|
||||
|
||||
|
||||
# ==================== 钩子实现 ====================
|
||||
|
||||
|
||||
def _hook_get_auth_methods(db: Session) -> list[dict[str, Any]]:
|
||||
"""auth.get_methods: 返回 LDAP 认证方法信息"""
|
||||
from src.services.auth.ldap import LDAPService
|
||||
|
||||
if not LDAPService.is_ldap_enabled(db):
|
||||
return []
|
||||
is_exclusive = LDAPService.is_ldap_exclusive(db)
|
||||
return [
|
||||
{
|
||||
"type": "ldap",
|
||||
"enabled": True,
|
||||
"exclusive": is_exclusive,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
async def _hook_authenticate(db: Session, email: str, password: str, auth_type: str) -> Any:
|
||||
"""auth.authenticate: LDAP 认证
|
||||
|
||||
仅当 auth_type == "ldap" 时处理,否则返回 None 让其他模块尝试。
|
||||
"""
|
||||
if auth_type != "ldap":
|
||||
return None
|
||||
|
||||
import asyncio
|
||||
|
||||
from starlette.concurrency import run_in_threadpool
|
||||
|
||||
from src.core.logger import logger
|
||||
from src.services.auth.ldap import LDAPService
|
||||
|
||||
# 预取配置,避免将 Session 传递到线程池
|
||||
config_data = LDAPService.get_config_data(db)
|
||||
if not config_data:
|
||||
logger.warning("登录失败 - LDAP 未启用或配置无效")
|
||||
return None
|
||||
|
||||
# 计算总体超时
|
||||
single_timeout = config_data.get("connect_timeout", 10)
|
||||
total_timeout = max(20, min(int(single_timeout * 4 * 1.1), 60))
|
||||
|
||||
try:
|
||||
ldap_user = await asyncio.wait_for(
|
||||
run_in_threadpool(LDAPService.authenticate_with_config, config_data, email, password),
|
||||
timeout=total_timeout,
|
||||
)
|
||||
except TimeoutError:
|
||||
logger.error("LDAP 认证总体超时({}秒): {}", total_timeout, email)
|
||||
return None
|
||||
|
||||
if not ldap_user:
|
||||
return None
|
||||
|
||||
# 获取或创建本地用户
|
||||
from src.services.auth.service import AuthService
|
||||
|
||||
user = await AuthService.get_or_create_ldap_user(db, ldap_user)
|
||||
if not user:
|
||||
return None
|
||||
if user.is_deleted:
|
||||
logger.warning("登录失败 - 用户已删除: {}", email)
|
||||
return None
|
||||
if not user.is_active:
|
||||
logger.warning("登录失败 - 用户已禁用: {}", email)
|
||||
return None
|
||||
return user
|
||||
|
||||
|
||||
def _hook_check_exclusive_mode(db: Session) -> bool | None:
|
||||
"""auth.check_exclusive_mode: 检查 LDAP 排他登录模式"""
|
||||
from src.services.auth.ldap import LDAPService
|
||||
|
||||
if LDAPService.is_ldap_exclusive(db):
|
||||
return True
|
||||
return None
|
||||
|
||||
|
||||
def _hook_check_registration(db: Session) -> dict[str, Any] | None:
|
||||
"""auth.check_registration: LDAP 排他模式下阻止本地注册"""
|
||||
from src.services.auth.ldap import LDAPService
|
||||
|
||||
if LDAPService.is_ldap_exclusive(db):
|
||||
return {"blocked": True, "reason": "系统已启用 LDAP 专属登录,禁止本地注册"}
|
||||
return None
|
||||
|
||||
|
||||
# LDAP 模块定义
|
||||
ldap_module = ModuleDefinition(
|
||||
metadata=ModuleMetadata(
|
||||
name="ldap",
|
||||
display_name="LDAP 认证",
|
||||
description="支持通过 LDAP/Active Directory 进行用户认证",
|
||||
category=ModuleCategory.AUTH,
|
||||
# 可用性控制
|
||||
env_key="LDAP_AVAILABLE",
|
||||
default_available=True,
|
||||
required_packages=["ldap3"],
|
||||
# 路由配置(使用现有路由,不改变路径)
|
||||
api_prefix="/api/admin/ldap",
|
||||
# 前端配置
|
||||
admin_route="/admin/ldap",
|
||||
admin_menu_icon="Users",
|
||||
admin_menu_group="system",
|
||||
admin_menu_order=50,
|
||||
),
|
||||
router_factory=_get_router,
|
||||
health_check=_health_check,
|
||||
validate_config=_validate_config,
|
||||
hooks={
|
||||
"auth.get_methods": _hook_get_auth_methods,
|
||||
"auth.authenticate": _hook_authenticate,
|
||||
"auth.check_exclusive_mode": _hook_check_exclusive_mode,
|
||||
"auth.check_registration": _hook_check_registration,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user