mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 09:50: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:
209
_deprecated_py_src/utils/auth_utils.py
Normal file
209
_deprecated_py_src/utils/auth_utils.py
Normal file
@@ -0,0 +1,209 @@
|
||||
"""
|
||||
认证工具函数
|
||||
提供统一的用户认证和授权功能
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
from typing import Any
|
||||
|
||||
from fastapi import Depends, Header, HTTPException, Request, status
|
||||
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from src.core.logger import logger
|
||||
from src.models.database import ManagementToken
|
||||
from src.services.auth.service import AuthService
|
||||
from src.utils.request_utils import get_client_ip
|
||||
|
||||
from ..core.exceptions import ForbiddenException
|
||||
from ..database import get_db
|
||||
from ..models.database import User, UserRole
|
||||
|
||||
security = HTTPBearer()
|
||||
|
||||
|
||||
async def authenticate_user_from_bearer_token(
|
||||
token: str,
|
||||
db: Session,
|
||||
request: Request | None = None,
|
||||
) -> User:
|
||||
if token.startswith(ManagementToken.TOKEN_PREFIX):
|
||||
client_ip = get_client_ip(request) if request is not None else "unknown"
|
||||
result = await AuthService.authenticate_management_token(db, token, client_ip)
|
||||
if not result:
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="无效的Token")
|
||||
|
||||
user, management_token = result
|
||||
if request is not None:
|
||||
request.state.user_id = user.id
|
||||
request.state.management_token_id = management_token.id
|
||||
return user
|
||||
|
||||
# 验证Token格式和签名
|
||||
try:
|
||||
payload = await AuthService.verify_token(token, token_type="access")
|
||||
except HTTPException as token_error:
|
||||
token_fp = hashlib.sha256(token.encode()).hexdigest()[:12]
|
||||
logger.error(
|
||||
"Token验证失败: {}: {}, token_fp={}",
|
||||
token_error.status_code,
|
||||
token_error.detail,
|
||||
token_fp,
|
||||
)
|
||||
raise
|
||||
except Exception as token_error:
|
||||
token_fp = hashlib.sha256(token.encode()).hexdigest()[:12]
|
||||
logger.error("Token验证失败: {}, token_fp={}", token_error, token_fp)
|
||||
raise ForbiddenException("无效的Token")
|
||||
|
||||
user_id = payload.get("user_id")
|
||||
|
||||
if not user_id:
|
||||
logger.error("Token缺少user_id字段: payload={}", payload)
|
||||
raise ForbiddenException("无效的认证凭据")
|
||||
|
||||
token_fp = hashlib.sha256(token.encode()).hexdigest()[:12]
|
||||
|
||||
if not isinstance(user_id, str):
|
||||
logger.error("Token中user_id格式错误: {} - {}", type(user_id), user_id)
|
||||
raise ForbiddenException("认证信息格式错误,请重新登录")
|
||||
|
||||
try:
|
||||
from src.services.user.service import UserService
|
||||
|
||||
user = UserService.get_user(db, user_id)
|
||||
except Exception as db_error:
|
||||
logger.error("数据库查询失败: user_id={}, error={}", user_id, db_error)
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="数据库查询失败,请稍后重试",
|
||||
)
|
||||
|
||||
if not user:
|
||||
logger.error("用户不存在: user_id={}", user_id)
|
||||
raise ForbiddenException("用户不存在或已禁用")
|
||||
|
||||
if not user.is_active:
|
||||
logger.error("用户已禁用: user_id={}", user_id)
|
||||
raise ForbiddenException("用户不存在或已禁用")
|
||||
|
||||
if user.is_deleted:
|
||||
logger.error("用户已删除: user_id={}", user_id)
|
||||
raise ForbiddenException("用户不存在或已禁用")
|
||||
|
||||
if not AuthService.token_identity_matches_user(payload, user):
|
||||
logger.error("Token身份校验失败: user_id={}, token_fp={}", user_id, token_fp)
|
||||
raise ForbiddenException("身份验证失败")
|
||||
|
||||
if request is not None:
|
||||
request.state.user_id = user.id
|
||||
if hasattr(request.state, "management_token_id"):
|
||||
request.state.management_token_id = None
|
||||
|
||||
return user
|
||||
|
||||
|
||||
async def get_current_user(
|
||||
request: Request,
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
db: Session = Depends(get_db),
|
||||
) -> User:
|
||||
"""
|
||||
获取当前登录用户
|
||||
统一的认证依赖函数
|
||||
|
||||
Args:
|
||||
credentials: Bearer token 凭据
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
User: 当前用户对象
|
||||
|
||||
Raises:
|
||||
HTTPException: 认证失败时抛出
|
||||
"""
|
||||
try:
|
||||
return await authenticate_user_from_bearer_token(credentials.credentials, db, request)
|
||||
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error("认证失败,未预期的错误: {}", e)
|
||||
# 返回500而不是401,避免触发前端的退出逻辑
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="认证服务暂时不可用"
|
||||
)
|
||||
|
||||
|
||||
async def get_current_user_from_header(
|
||||
request: Request,
|
||||
authorization: str | None = Header(None),
|
||||
db: Session = Depends(get_db),
|
||||
) -> User:
|
||||
"""
|
||||
从Header中获取当前用户(兼容性函数)
|
||||
|
||||
Args:
|
||||
authorization: Authorization header
|
||||
db: 数据库会话
|
||||
|
||||
Returns:
|
||||
User: 当前用户对象
|
||||
|
||||
Raises:
|
||||
HTTPException: 认证失败时抛出
|
||||
"""
|
||||
if not authorization or not authorization.startswith("Bearer "):
|
||||
raise ForbiddenException("未提供认证令牌")
|
||||
|
||||
try:
|
||||
return await authenticate_user_from_bearer_token(
|
||||
authorization.replace("Bearer ", ""),
|
||||
db,
|
||||
request,
|
||||
)
|
||||
except HTTPException:
|
||||
# 保持原始的HTTPException (包括401)
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"认证失败: {e}")
|
||||
raise ForbiddenException("认证失败")
|
||||
|
||||
|
||||
def require_admin(current_user: User = Depends(get_current_user)) -> User:
|
||||
"""
|
||||
要求管理员权限
|
||||
|
||||
Args:
|
||||
current_user: 当前用户
|
||||
|
||||
Returns:
|
||||
User: 管理员用户对象
|
||||
|
||||
Raises:
|
||||
HTTPException: 非管理员时抛出403错误
|
||||
"""
|
||||
if current_user.role != UserRole.ADMIN:
|
||||
raise ForbiddenException("需要管理员权限")
|
||||
return current_user
|
||||
|
||||
|
||||
def require_role(required_role: UserRole) -> Any:
|
||||
"""
|
||||
要求特定角色权限的装饰器工厂
|
||||
|
||||
Args:
|
||||
required_role: 需要的用户角色
|
||||
|
||||
Returns:
|
||||
依赖函数
|
||||
"""
|
||||
|
||||
def check_role(current_user: User = Depends(get_current_user)) -> User:
|
||||
if current_user.role != required_role:
|
||||
raise ForbiddenException(f"需要{required_role.value}权限")
|
||||
return current_user
|
||||
|
||||
return check_role
|
||||
Reference in New Issue
Block a user