chore(security): 摘除 knowledge_service 硬编码默认 DeepSeek Key(缺 env 抛明确错误/503)
- knowledge_service: 移除 os.getenv 默认值占位,改 _require_deepseek_key() 必填,缺 env 抛 DeepSeekKeyMissing
- knowledge API: generate/{daily,weekly,monthly} 缺 Key 返回 503(可观测,不再静默走模板兜底)
- finance_bot / verify_zxt_vouchers_json / bot_bridge_push: 凭据改 env 优先(CMA_BOT_KEY_* / CMA_BOT_API_KEYS / CMA_BRIDGE_TOKEN),历史共享键仅作兼容期兜底并告警
- tests: 新增 5 例回归(缺 Key 服务层抛错、API 503;有 Key 正常 200)
(cherry picked from commit 859bd8276d7c5aad4bf10ee3399b6cccc188f064)
This commit is contained in:
committed by
Hermes CI Fix
parent
885cfddbff
commit
a9dcbf22bc
@@ -18,6 +18,7 @@ from app.auth_middleware import require_role
|
||||
from app.deps import get_entity_id
|
||||
from app.models import KnowledgeEvent, KnowledgeSummary
|
||||
from app.services.knowledge_service import (
|
||||
DeepSeekKeyMissing,
|
||||
generate_summary_sync,
|
||||
generate_daily_sync,
|
||||
generate_weekly_sync,
|
||||
@@ -150,6 +151,9 @@ def trigger_daily_summary(
|
||||
try:
|
||||
result = generate_daily_sync(db, entity_id=entity_id)
|
||||
return {"message": "每日摘要已生成", "summary": result}
|
||||
except DeepSeekKeyMissing as e:
|
||||
logger.error("每日摘要生成失败(缺少 DeepSeek Key): %s", e)
|
||||
raise HTTPException(status_code=503, detail=str(e))
|
||||
except Exception as e:
|
||||
logger.exception("每日摘要生成失败")
|
||||
raise HTTPException(status_code=500, detail=f"生成失败: {str(e)}")
|
||||
@@ -164,6 +168,9 @@ def trigger_weekly_summary(
|
||||
try:
|
||||
result = generate_weekly_sync(db, entity_id=entity_id)
|
||||
return {"message": "周度摘要已生成", "summary": result}
|
||||
except DeepSeekKeyMissing as e:
|
||||
logger.error("周度摘要生成失败(缺少 DeepSeek Key): %s", e)
|
||||
raise HTTPException(status_code=503, detail=str(e))
|
||||
except Exception as e:
|
||||
logger.exception("周度摘要生成失败")
|
||||
raise HTTPException(status_code=500, detail=f"生成失败: {str(e)}")
|
||||
@@ -178,6 +185,9 @@ def trigger_monthly_summary(
|
||||
try:
|
||||
result = generate_monthly_sync(db, entity_id=entity_id)
|
||||
return {"message": "月度摘要已生成", "summary": result}
|
||||
except DeepSeekKeyMissing as e:
|
||||
logger.error("月度摘要生成失败(缺少 DeepSeek Key): %s", e)
|
||||
raise HTTPException(status_code=503, detail=str(e))
|
||||
except Exception as e:
|
||||
logger.exception("月度摘要生成失败")
|
||||
raise HTTPException(status_code=500, detail=f"生成失败: {str(e)}")
|
||||
|
||||
@@ -39,9 +39,23 @@ KPI变化:列出核心指标变化(名称、方向、幅度)
|
||||
注意:如果事件列表为空或没有有价值的信息,直接输出"本期无重要变化"。"""
|
||||
|
||||
|
||||
class DeepSeekKeyMissing(RuntimeError):
|
||||
"""DEEPSEEK_API_KEY 未配置 —— 禁止用硬编码默认 Key 兜底(2026-10-18 代码卫生)。"""
|
||||
|
||||
|
||||
def _require_deepseek_key() -> str:
|
||||
"""强制从环境变量读取 DeepSeek Key;缺失即抛明确错误,绝不静默使用假 Key。"""
|
||||
api_key = (os.getenv("DEEPSEEK_API_KEY") or "").strip()
|
||||
if not api_key:
|
||||
raise DeepSeekKeyMissing(
|
||||
"DEEPSEEK_API_KEY 未配置(knowledge_service 禁止硬编码默认 key)"
|
||||
)
|
||||
return api_key
|
||||
|
||||
|
||||
async def _call_deepseek(prompt: str, timeout: int = 30) -> str:
|
||||
"""调用DeepSeek API生成摘要"""
|
||||
api_key = os.getenv("DEEPSEEK_API_KEY", "sk-8e2...c2e8")
|
||||
api_key = _require_deepseek_key() # 缺 env 直接抛,不拿假 Key 发请求
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=timeout) as client:
|
||||
resp = await client.post(
|
||||
|
||||
Reference in New Issue
Block a user