mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
refactor: 全局适配 ApiFamily/EndpointKind 结构化标识体系
将新的 (ApiFamily, EndpointKind) / `family:kind` 签名体系应用到整个代码库: - API Handlers: 所有 adapter/handler 使用新的签名格式 - Services: provider, model, usage, cache, auth 等服务层适配 - Database: ProviderEndpoint 新增 api_family/endpoint_kind 字段 - Frontend: Provider 管理、Usage 表格等组件适配 - Tests: 更新所有相关测试用例
This commit is contained in:
@@ -163,8 +163,15 @@ class NewApiBalanceAction(BalanceAction):
|
||||
|
||||
# 检查是否是认证失败(未登录、无权限等)- Cookie 已失效
|
||||
auth_fail_indicators = [
|
||||
"未登录", "请登录", "login", "unauthorized", "无权限", "权限不足",
|
||||
"turnstile", "captcha", "验证码", # 需要人机验证
|
||||
"未登录",
|
||||
"请登录",
|
||||
"login",
|
||||
"unauthorized",
|
||||
"无权限",
|
||||
"权限不足",
|
||||
"turnstile",
|
||||
"captcha",
|
||||
"验证码", # 需要人机验证
|
||||
]
|
||||
is_auth_fail = any(ind in message.lower() for ind in auth_fail_indicators)
|
||||
if is_auth_fail:
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
Provider 架构模块
|
||||
"""
|
||||
|
||||
from src.services.provider_ops.architectures.anyrouter import AnyrouterArchitecture
|
||||
from src.services.provider_ops.architectures.base import (
|
||||
ProviderArchitecture,
|
||||
ProviderConnector,
|
||||
VerifyResult,
|
||||
)
|
||||
from src.services.provider_ops.architectures.anyrouter import AnyrouterArchitecture
|
||||
from src.services.provider_ops.architectures.cubence import CubenceArchitecture
|
||||
from src.services.provider_ops.architectures.generic_api import GenericApiArchitecture
|
||||
from src.services.provider_ops.architectures.nekocode import NekoCodeArchitecture
|
||||
|
||||
@@ -11,7 +11,6 @@ from typing import Any
|
||||
import httpx
|
||||
|
||||
from src.core.logger import logger
|
||||
from src.utils.ssl_utils import get_ssl_context
|
||||
from src.services.provider_ops.actions import (
|
||||
AnyrouterBalanceAction,
|
||||
ProviderAction,
|
||||
@@ -22,6 +21,7 @@ from src.services.provider_ops.architectures.base import (
|
||||
VerifyResult,
|
||||
)
|
||||
from src.services.provider_ops.types import ConnectorAuthType, ProviderActionType
|
||||
from src.utils.ssl_utils import get_ssl_context
|
||||
|
||||
# acw_sc__v2 算法常量
|
||||
_XOR_KEY = "3000176000856006061501533003690027800375"
|
||||
|
||||
@@ -3,23 +3,22 @@ Provider 架构抽象基类
|
||||
"""
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
from collections.abc import AsyncIterator
|
||||
|
||||
import httpx
|
||||
|
||||
from src.services.provider_ops.actions.base import ProviderAction
|
||||
from src.utils.ssl_utils import get_ssl_context
|
||||
from src.services.provider_ops.types import (
|
||||
ConnectorAuthType,
|
||||
ConnectorState,
|
||||
ConnectorStatus,
|
||||
ProviderActionType,
|
||||
)
|
||||
|
||||
from src.utils.ssl_utils import get_ssl_context
|
||||
|
||||
# ==================== 连接器基类 ====================
|
||||
|
||||
@@ -488,8 +487,6 @@ class ProviderArchitecture(ABC):
|
||||
for a in self.supported_actions
|
||||
],
|
||||
"default_connector": (
|
||||
self.supported_connectors[0].auth_type.value
|
||||
if self.supported_connectors
|
||||
else None
|
||||
self.supported_connectors[0].auth_type.value if self.supported_connectors else None
|
||||
),
|
||||
}
|
||||
|
||||
@@ -80,7 +80,16 @@ class ProviderOpsService:
|
||||
"""
|
||||
|
||||
# 凭据中需要加密的字段
|
||||
SENSITIVE_FIELDS = {"api_key", "password", "session_token", "session_cookie", "token_cookie", "auth_cookie", "cookie_string", "cookie"}
|
||||
SENSITIVE_FIELDS = {
|
||||
"api_key",
|
||||
"password",
|
||||
"session_token",
|
||||
"session_cookie",
|
||||
"token_cookie",
|
||||
"auth_cookie",
|
||||
"cookie_string",
|
||||
"cookie",
|
||||
}
|
||||
|
||||
def __init__(self, db: Session):
|
||||
self.db = db
|
||||
@@ -385,9 +394,7 @@ class ProviderOpsService:
|
||||
Returns:
|
||||
操作结果
|
||||
"""
|
||||
result = await self.execute_action(
|
||||
provider_id, ProviderActionType.QUERY_BALANCE, config
|
||||
)
|
||||
result = await self.execute_action(provider_id, ProviderActionType.QUERY_BALANCE, config)
|
||||
|
||||
# 成功或 auth_expired 时缓存(auth_expired 带有 cookie_expired 信息供前端显示警告)
|
||||
if result.status in (ActionStatus.SUCCESS, ActionStatus.AUTH_EXPIRED) and result.data:
|
||||
@@ -485,7 +492,9 @@ class ProviderOpsService:
|
||||
"response_time_ms": result.response_time_ms,
|
||||
}
|
||||
await CacheService.set(cache_key, cache_data, AUTH_FAILED_CACHE_TTL)
|
||||
logger.info(f"余额缓存已写入(认证失败): provider_id={provider_id}, message={result.message}")
|
||||
logger.info(
|
||||
f"余额缓存已写入(认证失败): provider_id={provider_id}, message={result.message}"
|
||||
)
|
||||
|
||||
async def _cache_balance(self, provider_id: str, result: ActionResult) -> None:
|
||||
"""缓存余额结果"""
|
||||
@@ -504,7 +513,9 @@ class ProviderOpsService:
|
||||
}
|
||||
|
||||
await CacheService.set(cache_key, cache_data, BALANCE_CACHE_TTL)
|
||||
logger.debug(f"余额缓存已写入: provider_id={provider_id}, extra={data.get('extra') if data else None}")
|
||||
logger.debug(
|
||||
f"余额缓存已写入: provider_id={provider_id}, extra={data.get('extra') if data else None}"
|
||||
)
|
||||
|
||||
async def _cache_balance_from_verify(
|
||||
self,
|
||||
@@ -633,7 +644,9 @@ class ProviderOpsService:
|
||||
if key in self.SENSITIVE_FIELDS and isinstance(value, str):
|
||||
if value: # 只加密非空值
|
||||
encrypted[key] = self.crypto.encrypt(value)
|
||||
logger.debug(f"加密字段 {key}: 原始长度={len(value)}, 加密后长度={len(encrypted[key])}")
|
||||
logger.debug(
|
||||
f"加密字段 {key}: 原始长度={len(value)}, 加密后长度={len(encrypted[key])}"
|
||||
)
|
||||
else:
|
||||
logger.warning(f"跳过空值字段 {key}")
|
||||
encrypted[key] = value
|
||||
@@ -705,8 +718,14 @@ class ProviderOpsService:
|
||||
if saved_config:
|
||||
saved_credentials = self._decrypt_credentials(saved_config.connector_credentials)
|
||||
sensitive_fields = [
|
||||
"api_key", "password", "session_token", "cookie_string", "cookie",
|
||||
"token_cookie", "auth_cookie", "session_cookie", # Cookie 认证字段
|
||||
"api_key",
|
||||
"password",
|
||||
"session_token",
|
||||
"cookie_string",
|
||||
"cookie",
|
||||
"token_cookie",
|
||||
"auth_cookie",
|
||||
"session_cookie", # Cookie 认证字段
|
||||
]
|
||||
|
||||
for field in sensitive_fields:
|
||||
@@ -738,11 +757,7 @@ class ProviderOpsService:
|
||||
if provider_ids is None:
|
||||
# 查询所有已配置的 Provider
|
||||
providers = self.db.query(Provider).filter(Provider.is_active.is_(True)).all()
|
||||
provider_ids = [
|
||||
p.id
|
||||
for p in providers
|
||||
if p.config and p.config.get("provider_ops")
|
||||
]
|
||||
provider_ids = [p.id for p in providers if p.config and p.config.get("provider_ops")]
|
||||
|
||||
if not provider_ids:
|
||||
return {}
|
||||
|
||||
Reference in New Issue
Block a user