# 账号管理权限检查规格 ## ADDED Requirements ### Requirement: 三层越权防护架构 系统 SHALL 实现三层越权防护机制,确保账号管理操作的安全性。 #### Scenario: 路由层中间件拦截企业账号 - **WHEN** 企业账号(user_type=4)访问账号管理接口(/api/admin/accounts/*) - **THEN** 中间件应返回 403 错误:"无权限访问账号管理功能" #### Scenario: Service层权限检查成功 - **WHEN** 代理账号创建自己店铺的账号 - **THEN** CanManageShop 检查应通过,账号创建成功 #### Scenario: GORM层自动过滤生效 - **WHEN** 代理账号查询账号列表 - **THEN** GORM Callback 应自动添加 `shop_id IN (当前店铺+下级店铺)` 过滤条件 ### Requirement: 代理账号只能管理自己店铺及下级店铺的账号 系统 SHALL 验证代理账号对目标店铺的管理权限,禁止跨店铺越权操作。 #### Scenario: 代理创建自己店铺的账号成功 - **WHEN** 代理账号(shop_id=100)创建 shop_id=100 的账号 - **THEN** 权限检查通过,账号创建成功 #### Scenario: 代理创建下级店铺的账号成功 - **WHEN** 代理账号(shop_id=100,下级:101,102)创建 shop_id=101 的账号 - **THEN** GetSubordinateShopIDs 返回 [100,101,102],权限检查通过 #### Scenario: 代理创建其他店铺的账号失败 - **WHEN** 代理账号(shop_id=100)创建 shop_id=200 的账号 - **THEN** CanManageShop 返回错误:"无权限管理该店铺的账号",创建失败 #### Scenario: 代理创建平台账号失败 - **WHEN** 代理账号尝试创建 user_type=2 的平台账号 - **THEN** Service 层检查返回错误:"无权限创建平台账号",创建失败 ### Requirement: 平台账号和超级管理员可以管理所有账号 系统 SHALL 允许平台账号和超级管理员跳过所有权限检查,管理所有账号。 #### Scenario: 平台账号创建任意类型账号 - **WHEN** 平台账号(user_type=2)创建代理账号(user_type=3, shop_id=100) - **THEN** 权限检查跳过,账号创建成功 #### Scenario: 超级管理员创建任意类型账号 - **WHEN** 超级管理员(user_type=1)创建任意类型账号 - **THEN** 权限检查跳过,账号创建成功 #### Scenario: 平台账号查询所有账号 - **WHEN** 平台账号调用账号列表接口 - **THEN** GORM Callback 跳过过滤,返回所有账号 ### Requirement: 企业账号禁止访问账号管理接口 系统 SHALL 禁止企业账号访问所有账号管理接口。 #### Scenario: 企业账号创建账号失败(路由层拦截) - **WHEN** 企业账号(user_type=4)调用 POST /api/admin/accounts/enterprise - **THEN** 路由层中间件返回 403 错误:"无权限访问账号管理功能" #### Scenario: 企业账号更新账号失败(Service层拦截) - **WHEN** 企业账号绕过路由层,直接调用 AccountService.Update - **THEN** Service 层返回 403 错误:"企业账号不允许更新账号" ### Requirement: 统一错误返回防止信息泄露 系统 SHALL 在越权访问时统一返回模糊错误消息,防止攻击者判断资源是否存在。 #### Scenario: 查询不存在的账号返回模糊错误 - **WHEN** 用户查询不存在的账号 ID - **THEN** 返回 403 错误:"无权限操作该资源或资源不存在" #### Scenario: 查询越权的账号返回相同错误 - **WHEN** 代理账号(shop_id=100)查询 shop_id=200 的账号 - **THEN** 返回 403 错误:"无权限操作该资源或资源不存在"(与不存在的错误消息相同) ### Requirement: CanManageShop 权限检查函数 系统 SHALL 提供 CanManageShop 函数验证用户对目标店铺的管理权限。 #### Scenario: 验证代理对自己店铺的权限 - **WHEN** 调用 CanManageShop(ctx, 100, shopStore) 且当前用户 shop_id=100 - **THEN** 返回 nil(有权限) #### Scenario: 验证代理对下级店铺的权限 - **WHEN** 调用 CanManageShop(ctx, 101, shopStore) 且当前用户 shop_id=100,下级包含 101 - **THEN** GetSubordinateShopIDs 返回 [100,101,102],返回 nil(有权限) #### Scenario: 验证代理对其他店铺的权限失败 - **WHEN** 调用 CanManageShop(ctx, 200, shopStore) 且当前用户 shop_id=100 - **THEN** 返回错误:"无权限管理该店铺的账号" #### Scenario: 验证平台账号自动通过 - **WHEN** 调用 CanManageShop(ctx, 200, shopStore) 且当前用户 user_type=2(平台) - **THEN** 不调用 GetSubordinateShopIDs,直接返回 nil(有权限) ### Requirement: CanManageEnterprise 权限检查函数 系统 SHALL 提供 CanManageEnterprise 函数验证用户对目标企业的管理权限。 #### Scenario: 验证平台账号管理任意企业 - **WHEN** 调用 CanManageEnterprise(ctx, 50, enterpriseStore, shopStore) 且当前用户 user_type=2 - **THEN** 返回 nil(有权限) #### Scenario: 验证代理对归属企业的权限 - **WHEN** 调用 CanManageEnterprise(ctx, 50, enterpriseStore, shopStore) 且企业 owner_shop_id=100,当前用户 shop_id=100 - **THEN** 返回 nil(有权限) #### Scenario: 验证代理对下级店铺企业的权限 - **WHEN** 调用 CanManageEnterprise(ctx, 50, enterpriseStore, shopStore) 且企业 owner_shop_id=101,当前用户 shop_id=100,下级包含 101 - **THEN** 返回 nil(有权限) #### Scenario: 验证代理对其他店铺企业的权限失败 - **WHEN** 调用 CanManageEnterprise(ctx, 50, enterpriseStore, shopStore) 且企业 owner_shop_id=200,当前用户 shop_id=100 - **THEN** 返回错误:"无权限管理该企业的账号" ### Requirement: 权限检查性能优化 系统 SHALL 使用 Redis 缓存优化权限检查性能,确保 API 响应时间 < 200ms。 #### Scenario: GetSubordinateShopIDs 命中缓存 - **WHEN** 调用 GetSubordinateShopIDs(ctx, 100) 且缓存存在 - **THEN** 从 Redis 读取缓存,不查询数据库,耗时 < 5ms #### Scenario: GetSubordinateShopIDs 缓存未命中 - **WHEN** 调用 GetSubordinateShopIDs(ctx, 100) 且缓存不存在 - **THEN** 递归查询数据库,写入 Redis 缓存(30分钟),返回结果 #### Scenario: 权限检查总耗时 < 10ms - **WHEN** 执行完整权限检查(包含 GetSubordinateShopIDs) - **THEN** 总耗时 < 10ms(缓存命中时 < 5ms)