# 审计问题修复计划(按优先级) ## Context 2026-04-18 系统全面审计发现多个问题(详见 `docs/audit-2026-04-18.md`)。当前系统因 Redis 未安装且限流策略为 fail-closed,**所有 API 请求返回 429**,系统完全不可用。本计划按优先级逐步修复,恢复系统可用性。 --- ## Fix 1: 限流中间件改为 fail-open(P0-3) **问题**: Redis 未安装时,fail-closed 策略拒绝所有请求,系统完全不可用。 **文件**: `crates/erp-server/src/middleware/rate_limit.rs` **改动**: - `apply_rate_limit()` 中 3 处 Redis 不可达时的处理,从返回 429 改为放行(调用 `next.run(req).await`) - 仅保留 tracing::warn 日志,不阻断业务 - 超限计数本身仍按原逻辑:Redis 可达时正常限流,不可达时放行 **涉及行**: 约第 121-129 行、第 138-147 行、第 151-158 行 --- ## Fix 2: 插件权限自动分配给 admin 角色(P0-1) **问题**: 插件安装时注册权限到 `permissions` 表,但不分配给 admin 角色,导致 JWT 中缺少插件权限码,所有插件数据页面返回 403。 **文件**: `crates/erp-plugin/src/service.rs` **改动**: 1. 新增 `grant_permissions_to_admin()` 函数(约第 766 行 `register_plugin_permissions` 之后): - 查询 admin 角色 ID - 查询当前插件的所有权限 ID(按 manifest_id 前缀匹配) - INSERT INTO role_permissions,跳过已存在的记录(ON CONFLICT DO NOTHING) - 参考 `crates/erp-auth/src/service/seed.rs` 中的 SQL 模式 2. 在 `install()` 函数(约第 81 行)中,`register_plugin_permissions()` 调用之后,调用 `grant_permissions_to_admin()` 3. 在 `enable()` 函数(约第 191 行)中也调用 `grant_permissions_to_admin()`,确保启用时权限也已分配 **参考文件**: - `crates/erp-auth/src/service/seed.rs` — 已有的 admin 权限授予模式 - `crates/erp-server/migration/src/m20260417_000034_seed_plugin_permissions.rs` — 迁移中的 SQL 模式 - `crates/erp-plugin/src/handler/data_handler.rs:75` — `compute_permission_code()` 权限码格式 --- ## Fix 3: CRM 插件 WASM 数据修复(P0-2) **问题**: 数据库中存储的 CRM 插件 WASM 是错误的测试插件二进制(110KB),而非真正的 CRM 插件(~22KB)。导致服务器重启后插件恢复失败。 **步骤**: 1. 重新编译 CRM 插件 WASM Component 2. 通过插件升级 API 上传正确的二进制 3. 验证插件恢复成功 **命令**: ```bash cargo build -p erp-plugin-crm --target wasm32-unknown-unknown --release wasm-tools component new target/wasm32-unknown-unknown/release/erp_plugin_crm.wasm -o target/erp_plugin_crm.component.wasm ``` --- ## Fix 4: `/roles/permissions` 路由冲突(P1) **问题**: `GET /api/v1/roles/permissions` 被 `GET /api/v1/roles/{id}` 路由拦截,`permissions` 被当作 UUID 解析失败。 **文件**: `crates/erp-auth/src/module.rs` **改动**: - 在 `register_routes()` 中(约第 64-82 行),将 `/roles/permissions` 精确匹配路由放在 `:id` 参数路由**之前** - Axum 路由匹配按注册顺序,精确路径优先于参数路径 --- ## 验证计划 每个 Fix 完成后独立验证: 1. **Fix 1 验证**: 启动后端,`curl http://localhost:3000/api/v1/health` 返回 200(不再 429) 2. **Fix 2 验证**: 重新安装/启用 CRM 插件,用 admin 登录后访问 CRM 数据页面不再 403 3. **Fix 3 验证**: 重启后端,日志显示 `Plugins recovered: 1`(而非 0) 4. **Fix 4 验证**: `curl -H "Authorization: Bearer " http://localhost:3000/api/v1/roles/permissions` 返回权限列表(非 UUID 错误) **最终验证**: - `cargo check` 编译通过 - `cargo test --workspace` 全部通过 - 前端页面正常访问,CRM 数据可操作