Skip to main content
Glama
leeguooooo
by leeguooooo
CRITICAL_FIXES.md8.93 kB
# 关键修复 - 消除账户回退逻辑 ## 🚨 问题背景 在之前的修复中,虽然我们添加了 `account_id` 支持,但保留了 `or email` 的回退逻辑,这**重新引入了我们刚修复的跨账户混淆问题**。 ### 发现的问题 #### ❌ 问题 1: ConnectionManager 回退 **文件**: `src/connection_manager.py:63` ```python # 问题代码 self.account_id = account_config.get('id') or account_config.get('email') ``` **风险**: - 环境变量账户可能没有 `id` 字段 - 回退到 `email` 会导致 `account_id = "leeguoo@qq.com"` - 下游代码用这个邮箱地址查找账户 → 找不到 → 回退到默认账户 - **重新出现跨账户混淆** --- #### ❌ 问题 2: SearchOperations 回退 **文件**: `src/operations/search_operations.py:53-54` ```python # 问题代码 canonical_account_id = self.connection_manager.account_id or \ self.connection_manager.email ``` **风险**: - 搜索结果返回邮箱地址作为 `account_id` - 前端用邮箱地址调用 `get_email_detail` - AccountManager 无法解析 → 回退到错误账户 - **导致"Email not found"或获取错误邮件** --- #### ❌ 问题 3: 缓存层检查不足 **文件**: `src/legacy_operations.py:161-177` ```python # 问题代码 if use_cache: cached_ops = CachedEmailOperations() cached_result = cached_ops.list_emails_cached(...) # 直接调用 ``` **风险**: - 没有检查数据库是否存在 - 没有检查数据库是否已初始化 - Schema 不匹配时会抛异常(`no such column: last_synced`) - 每次调用都要等待数据库超时 - **降低性能而不是提升性能** --- ## ✅ 修复方案 ### 修复 1: 强制要求 account_id **文件**: `src/connection_manager.py` ```python # 修复后 self.account_id = account_config.get('id') if not self.account_id: raise ValueError(f"Account config missing required 'id' field. Email: {self.email}") ``` **效果**: - ✅ **Fail Fast**: 如果配置缺少 ID,立即报错 - ✅ **强制规范**: 所有账户配置必须有 `id` 字段 - ✅ **消除歧义**: 不再有回退逻辑,ID 就是 ID **影响**: - 环境变量账户必须在 `AccountManager.get_account()` 中设置 `id` - 已在 `account_manager.py` 中修复(`'id': 'env_default'`) --- ### 修复 2: 消除 canonical_account_id 回退 **文件**: `src/operations/search_operations.py` ```python # 修复后 canonical_account_id = self.connection_manager.account_id if not canonical_account_id: logger.error("ConnectionManager missing account_id - this should never happen") return { 'success': False, 'error': 'Account ID not configured properly', 'emails': [] } ``` **效果**: - ✅ **只使用真实 ID**: 不再回退到邮箱地址 - ✅ **明确错误**: 如果没有 ID,直接返回错误而不是默默失败 - ✅ **保护下游**: 防止错误的 `account_id` 传播 --- ### 修复 3: 缓存层安全检查 **文件**: `src/legacy_operations.py` ```python # 修复后 if use_cache: try: cached_ops = CachedEmailOperations() # CRITICAL: Only use cache if database is actually available if not cached_ops.is_available(): logger.debug("Cache database not available, skipping cache") else: cached_result = cached_ops.list_emails_cached(...) if cached_result is not None: # 使用缓存结果 pass else: logger.debug("Cache miss or expired, fetching from IMAP") except Exception as e: # Cache failure should not break the entire operation logger.warning(f"Cache read failed (falling back to IMAP): {e}") ``` **效果**: - ✅ **检查数据库存在**: `is_available()` 检查文件是否存在 - ✅ **优雅降级**: 缓存失败时回退到 IMAP,不影响主流程 - ✅ **异常捕获**: 任何缓存错误都被捕获和记录 - ✅ **性能保护**: 不会因为缓存问题而降低性能 --- ### 修复 4: 全局移除 account_id 回退 **影响范围**: `src/legacy_operations.py` (12处) ```bash # 批量替换 sed -i 's/conn_mgr\.account_id or conn_mgr\.email/conn_mgr.account_id/g' ``` **替换位置**: - `get_mailbox_status()` - line 92 - `fetch_emails()` - lines 290, 306 - `get_email_detail()` - line 552 - `mark_email_read()` - line 589 - `delete_email()` - line 627 - `move_email_to_trash()` - lines 674, 692 - `batch_move_to_trash()` - line 749 - `batch_delete_emails()` - line 791 - `batch_mark_read()` - line 846, 900 **效果**: - ✅ **统一规范**: 所有地方都只使用 `account_id` - ✅ **消除隐患**: 不再有回退到邮箱地址的可能 - ✅ **一致性**: 整个代码库遵循同一规则 --- ## 🧪 测试验证 ### 基本功能测试 ```bash $ python test_account_id_fix.py ✅ list_emails: PASS ✅ get_email_detail: PASS ✅ batch_operations: PASS 🎉 所有测试通过! ``` ### 错误场景测试 ```python # 测试缺少 ID 的账户配置 try: conn_mgr = ConnectionManager({'email': 'test@example.com'}) except ValueError as e: print(f"✅ 正确抛出错误: {e}") # "Account config missing required 'id' field. Email: test@example.com" ``` ### 缓存层测试 ```python # 数据库不存在时 result = fetch_emails(limit=10, use_cache=True) # 日志: "Cache database not available, skipping cache" # ✅ 自动回退到 IMAP # 数据库存在但有错误时 # 日志: "Cache read failed (falling back to IMAP): no such column: last_synced" # ✅ 捕获异常,继续执行 ``` --- ## 📊 修复效果对比 ### 修复前 ❌ ```python # 账户配置 config = { 'email': 'leeguoo@qq.com', # 'id': 'leeguoo_qq' # 缺失! } # ConnectionManager self.account_id = config.get('id') or config.get('email') # → self.account_id = "leeguoo@qq.com" ❌ 邮箱地址 # 返回给前端 return {"account_id": "leeguoo@qq.com"} ❌ # 前端再次调用 get_email_detail(email_id="123", account_id="leeguoo@qq.com") # AccountManager 查找 accounts.get("leeguoo@qq.com") # → None! # → 回退到默认账户 # → 获取错误邮件或报错"Email not found" ``` ### 修复后 ✅ ```python # 账户配置 config = { 'email': 'leeguoo@qq.com', # 'id': 'leeguoo_qq' # 缺失! } # ConnectionManager self.account_id = config.get('id') # → None if not self.account_id: raise ValueError("Account config missing required 'id' field") # ✅ 立即报错,提示配置问题 # 或者正确配置 config = { 'email': 'leeguoo@qq.com', 'id': 'leeguoo_qq' # ✅ 必须有 } # → self.account_id = "leeguoo_qq" ✅ 真实 ID # 返回给前端 return {"account_id": "leeguoo_qq"} ✅ # 前端再次调用 get_email_detail(email_id="123", account_id="leeguoo_qq") # AccountManager 查找 accounts.get("leeguoo_qq") # → 成功! ✅ # → 正确的账户 # → 正确的邮件 ``` --- ## 🔒 安全保障 ### 1. Fail Fast 原则 ```python # 配置错误时立即报错,而不是默默使用错误值 if not self.account_id: raise ValueError(...) ``` ### 2. 明确的错误消息 ```python # 清楚地告诉开发者哪里出错 ValueError(f"Account config missing required 'id' field. Email: {self.email}") ``` ### 3. 优雅降级 ```python # 缓存失败时不影响主流程 try: # 尝试缓存 except Exception as e: logger.warning(...) # 继续使用 IMAP ``` ### 4. 一致性保障 ```python # 全局统一使用 account_id,无例外 return {"account_id": conn_mgr.account_id} # 不再有 "or email" ``` --- ## 📋 检查清单 在部署前,确保: - ✅ 所有账户配置都有 `id` 字段 ```json { "accounts": { "leeguoo_qq": { // ← 这是 ID "id": "leeguoo_qq", // ← 必须显式设置 "email": "leeguoo@qq.com", ... } } } ``` - ✅ 环境变量账户有默认 ID ```python # AccountManager.get_account() 中 return { 'email': email, 'password': password, 'provider': provider, 'id': 'env_default' // ✅ 默认 ID } ``` - ✅ 测试通过 ```bash python test_account_id_fix.py python test_email_lookup_fallback.py ``` - ✅ 缓存层可选 - 如果不需要缓存:`fetch_emails(use_cache=False)` - 如果需要缓存:确保 `email_sync.db` 已初始化 --- ## 🎯 关键要点 1. **No Fallback**: `account_id` 就是 `account_id`,没有回退到 `email` 2. **Fail Fast**: 配置错误立即报错,不默默失败 3. **Graceful Degradation**: 缓存失败不影响主流程 4. **Consistency**: 整个代码库统一规范 --- ## 📝 相关文件 - `src/connection_manager.py` - 强制要求 ID - `src/account_manager.py` - 环境变量 ID - `src/operations/search_operations.py` - 消除回退 - `src/legacy_operations.py` - 全局统一 --- 修复完成!🔒

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/leeguooooo/email-mcp-service'

If you have feedback or need assistance with the MCP directory API, please join our Discord server