# 任务012:补充权限校验 ## 目标 为 cabinets.rs、projects.rs、organizations.rs 三个模块补充完整的权限校验。 ## 问题描述 第二轮代码审查发现这3个模块的handler函数签名中缺少 `CurrentUser` 参数,导致无法进行权限校验。任何登录用户都可以访问这些敏感接口。 ## 修复清单 ### 1. 权限码定义 首先在权限表中添加缺失的权限码: ```sql -- 组织管理 INSERT INTO permissions (code, name) VALUES ('org:view', '查看组织'); INSERT INTO permissions (code, name) VALUES ('org:create', '创建组织'); INSERT INTO permissions (code, name) VALUES ('org:edit', '编辑组织'); INSERT INTO permissions (code, name) VALUES ('org:delete', '删除组织'); -- 项目管理 INSERT INTO permissions (code, name) VALUES ('project:view', '查看项目'); INSERT INTO permissions (code, name) VALUES ('project:create', '创建项目'); INSERT INTO permissions (code, name) VALUES ('project:edit', '编辑项目'); INSERT INTO permissions (code, name) VALUES ('project:delete', '删除项目'); -- 设备管理(补充) INSERT INTO permissions (code, name) VALUES ('device:edit', '编辑设备'); ``` ### 2. organizations.rs 修复 **文件:** `src/routes/organizations.rs` **修改内容:** - 所有handler函数签名添加 `user: CurrentUser` 参数 - 每个handler开头调用 `check_permission` ```rust // 示例:获取组织列表 #[get("/api/organizations")] async fn list_organizations( user: CurrentUser, // 新增 pool: State, ) -> Result>> { auth::check_permission(&user, "org:view")?; // 新增 // ... 原有逻辑 } // 示例:创建组织 #[post("/api/organizations")] async fn create_organization( user: CurrentUser, // 新增 pool: State, json: Json, ) -> Result> { auth::check_permission(&user, "org:create")?; // 新增 // ... 原有逻辑 } ``` **需要修复的端点:** - `GET /api/organizations` → `org:view` - `POST /api/organizations` → `org:create` - `PUT /api/organizations/:id` → `org:edit` - `DELETE /api/organizations/:id` → `org:delete` ### 3. projects.rs 修复 **文件:** `src/routes/projects.rs` **修改内容:** - 所有handler函数签名添加 `user: CurrentUser` 参数 - 每个handler开头调用 `check_permission` **需要修复的端点:** - `GET /api/organizations/:org_id/projects` → `project:view` - `POST /api/organizations/:org_id/projects` → `project:create` - `PUT /api/projects/:id` → `project:edit` - `DELETE /api/projects/:id` → `project:delete` ### 4. cabinets.rs 修复 **文件:** `src/routes/cabinets.rs` **修改内容:** - 所有handler函数签名添加 `user: CurrentUser` 参数 - 每个handler开头调用 `check_permission` - `list_cabinets` 和 `get_cabinet` 需要额外验证用户是否有权访问该项目 **需要修复的端点:** - `GET /api/projects/:project_id/cabinets` → `device:view` + 项目权限验证 - `POST /api/cabinets` → `device:create` - `PUT /api/cabinets/:id` → `device:edit` - `DELETE /api/cabinets/:id` → `device:delete` - `POST /api/cabinets/:id/regenerate-auth` → `device:edit` - `GET /api/cabinets/:id` → `device:view` + 项目权限验证 - `GET /api/cabinets/options` → `device:view` - `GET /api/cabin-boards/options` → `device:view` - `GET /api/compartments/options` → `device:view` **项目权限验证逻辑:** ```rust // 验证用户是否有权访问指定项目 async fn check_project_access( user: &CurrentUser, pool: &MySqlPool, project_id: i64, ) -> Result<()> { if user.role_level >= 2 { // 总管理员可访问所有项目 return Ok(()); } if let Some(org_id) = user.organization_id { // 验证项目是否属于用户的组织 let project: Option<(i64,)> = sqlx::query_as( "SELECT id FROM projects WHERE id = ? AND organization_id = ?" ) .bind(project_id) .bind(org_id) .fetch_optional(pool) .await?; if project.is_none() { return Err(AppError::Forbidden("无权访问该项目".into())); } } else { return Err(AppError::Forbidden("无组织关联".into())); } Ok(()) } ``` ### 5. users.rs 修复(额外) **文件:** `src/routes/users.rs` **修改内容:** - `list_users` 添加组织隔离,企业管理员只能看到本组织的用户 ```rust // 修改 list_users 查询 let users = if user.role_level >= 2 { // 总管理员看所有用户 sqlx::query_as("SELECT * FROM users") .fetch_all(&pool) .await? } else if let Some(org_id) = user.organization_id { // 企业管理员只看本组织用户 sqlx::query_as("SELECT * FROM users WHERE organization_id = ?") .bind(org_id) .fetch_all(&pool) .await? } else { vec![] // 无组织用户看不到任何人 }; ``` ## 质量约束 1. 完成代码后执行 `cargo check` + `cargo clippy`,零报错零警告 2. 分层拆分,单函数≤80行,命名语义化,完整注释 3. 所有外部IO/网络请求异常捕获,禁止裸panic 4. 分支逻辑全覆盖,不遗漏兜底分支 5. 常量抽离,不使用废弃API 6. Rust内存安全,合理管理所有权,禁用unsafe无合理理由 7. 修复后重新运行 `cargo test`(如有测试)确保无回归