mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
- 删除全部 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)
101 lines
3.6 KiB
Python
101 lines
3.6 KiB
Python
"""
|
||
Provider Key 重复校验规则。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import json
|
||
|
||
from sqlalchemy.orm import Session
|
||
|
||
from src.core.crypto import crypto_service
|
||
from src.core.exceptions import InvalidRequestException
|
||
from src.models.database import ProviderAPIKey
|
||
|
||
|
||
def check_duplicate_key(
|
||
db: Session,
|
||
provider_id: str,
|
||
auth_type: str,
|
||
new_api_key: str | None = None,
|
||
new_auth_config: dict | None = None,
|
||
exclude_key_id: str | None = None,
|
||
) -> None:
|
||
"""
|
||
检查密钥是否与其他现有密钥重复
|
||
|
||
对于不同的认证类型,使用不同的比较方式:
|
||
- api_key: 比较 API Key 的哈希值
|
||
- service_account: 比较 Service Account 的 client_email
|
||
|
||
Args:
|
||
db: 数据库会话
|
||
provider_id: Provider ID
|
||
auth_type: 认证类型 (api_key, service_account, oauth)
|
||
new_api_key: 新的 API Key(用于 api_key 类型)
|
||
new_auth_config: 新的认证配置(用于 service_account 类型)
|
||
exclude_key_id: 要排除的 Key ID(用于更新场景)
|
||
"""
|
||
if auth_type == "api_key" and new_api_key:
|
||
# 跳过占位符
|
||
if new_api_key == "__placeholder__":
|
||
return
|
||
|
||
# 仅查询同 auth_type 的 Keys,减少不必要的解密操作
|
||
query = db.query(ProviderAPIKey).filter(
|
||
ProviderAPIKey.provider_id == provider_id,
|
||
ProviderAPIKey.auth_type == "api_key",
|
||
)
|
||
if exclude_key_id:
|
||
query = query.filter(ProviderAPIKey.id != exclude_key_id)
|
||
|
||
new_key_hash = crypto_service.hash_api_key(new_api_key)
|
||
for existing_key in query:
|
||
try:
|
||
decrypted_key = crypto_service.decrypt(existing_key.api_key, silent=True)
|
||
if decrypted_key == "__placeholder__":
|
||
continue
|
||
existing_hash = crypto_service.hash_api_key(decrypted_key)
|
||
if new_key_hash == existing_hash:
|
||
raise InvalidRequestException(
|
||
f"该 API Key 已存在于当前 Provider 中(名称: {existing_key.name})"
|
||
)
|
||
except InvalidRequestException:
|
||
raise
|
||
except Exception:
|
||
# 解密失败时跳过该 Key
|
||
continue
|
||
|
||
elif auth_type in ("service_account", "vertex_ai") and new_auth_config:
|
||
new_client_email = (
|
||
new_auth_config.get("client_email") if isinstance(new_auth_config, dict) else None
|
||
)
|
||
if not new_client_email:
|
||
return
|
||
|
||
# 仅查询同 auth_type 且有 auth_config 的 Keys
|
||
query = db.query(ProviderAPIKey).filter(
|
||
ProviderAPIKey.provider_id == provider_id,
|
||
ProviderAPIKey.auth_type.in_(["service_account", "vertex_ai"]),
|
||
ProviderAPIKey.auth_config.isnot(None),
|
||
)
|
||
if exclude_key_id:
|
||
query = query.filter(ProviderAPIKey.id != exclude_key_id)
|
||
|
||
for existing_key in query:
|
||
try:
|
||
decrypted_config = json.loads(
|
||
crypto_service.decrypt(existing_key.auth_config, silent=True)
|
||
)
|
||
existing_email = decrypted_config.get("client_email")
|
||
if existing_email and existing_email == new_client_email:
|
||
raise InvalidRequestException(
|
||
f"该 Service Account ({new_client_email}) 已存在于当前 Provider 中"
|
||
f"(名称: {existing_key.name})"
|
||
)
|
||
except InvalidRequestException:
|
||
raise
|
||
except Exception:
|
||
# 解密失败时跳过该 Key
|
||
continue
|