基线:
origin/test@ bc983dba · 只读核查,未改代码 · 云机环境 · 非生产验收证据
v1 现状报告:pc-rbac-verify-and-plan-20260928.md(14 维)
v2 新增取证:/tmp/rbac-verify-C.log(20 菜单逐个评估,2761 行)· /tmp/rbac-verify-D.log(品牌方/账号身份)
长官 9-28 口径:①客户可能是机构或品牌方 ②现有页面功能机构化,角色组选开放哪些 ③客户只看当前机构数据 ④Phase 58 旧方案作废,按本次重做
| # | v1 的问题 | 物理证据 | v2 改法 |
|---|---|---|---|
| 1 | 没搞清品牌方是什么 | app/models/brand_code.py:34-38 品牌码 org_id → organizations.id;app/models/organization.py 无 brand/parent 字段;全库无 brands 表 |
品牌方就是一家机构。客户账号统一绑一家机构,机构和品牌方同一套 |
| 2 | 新造 console_user 角色 |
已有 org_admin:CHECK 强制带 linked_org_id(app/models/user.py:186-191);结算端权限集为空 settlement/backend/app/auth/zhaoyang_permissions.py:156;不触发单设备踢人(只认 org_seat,app/auth/middleware.py:347/375) |
复用 org_admin,不改 CHECK、不加新角色值 |
| 3 | 把「看全部/看本机构」放在角色组上 | 同一角色组要给多家机构共用 | 数据范围跟账号走:org_admin 恒=本机构,admin/platform_staff 恒=全平台 |
| 4 | 以为结算那边改 require_menu 就够 | zhaoyang_permissions.py:250-251 非 admin/platform_staff 一律 403「Platform account source is not configured」,13 个结算路由文件都经过这一关 |
结算端身份关卡放行 org_admin,其细粒度权限按角色组菜单只映射读权限 |
| 5 | 以为「列表加个机构过滤」就行 | 20 菜单里 12+ 处 /{org_id}、/{voucher_id}、/{user_id} 路径参数全部零归属校验(C.log 汇总表) |
每个开放接口必须同时做:列表按机构过滤 + 单条按 id 校验归属 + 自动化越权测试 |
A=数据天然属于机构,可直接机构化 · B=要新做「本机构视图」· C=平台级,不开放给客户
| 菜单 | 判定 | 数据怎么挂到机构 | 要注意的 |
|---|---|---|---|
| 个人设置 system.account | A | 只返回当前登录人(app/api/me_router.py:19) |
所有账号默认有 |
| 子席位管理 platform.parent_seats | A | users.linked_org_id 1 跳 |
「功能配置」是全平台唯一配置(admin_parent_seats.py:194,207),要从客户视图摘掉;/orgs/{org_id}/detail 要补归属校验 |
| 席位活动 platform.seat_activity | A | 席位→linked_org_id |
🚨 现有过滤是假的:org_id 参数声明了但函数体没用,真正过滤的 seat_id 不校验归属(app/api/admin_activity.py:266-267,278,主会话已复核)。开放前必须先修 |
| 机构签约 settlement.stores | A | OrgSignupProfile.org_id = 机构 id(stores.py:468) |
/{org_id} 下 6+ 个子接口零校验;激活/审核是平台动作,客户只读 |
| 收款管理 settlement.payment | A | PaymentVoucher.org_id 1 跳(payment_vouchers.py:305) |
确认/驳回/退款是资金动作,客户只能看不能操作 |
| 收益账本 settlement.ledger | A | RevenueSnapshot.org_id 1 跳(revenue_ledger.py:130-131) |
加一行机构过滤即可,成本最低 |
| 用户管理 platform.users | A(技术上) | users.linked_org_id |
建议不开放:开放等于客户能改账号角色,存在提权风险;机构席位管理走下面的「我的机构」 |
| 机构管理 platform.orgs | B | 本身就是机构表 | 现有列表返回全平台机构+API Key+开关(api_v1.py:329),不能加过滤了事;要新做「我的机构资料」单页(含席位) |
| 机构洞察 platform.org_insights | B | 下钻接口按 org_id | 总览是「全机构排行」,对单机构无意义;只保留本机构下钻部分 |
| 结算列表 settlement.settlements | B | 结算单挂渠道不挂机构,2 跳 | 一张结算单混着多家机构的钱,要新做「本机构在该单的份额明细」 |
| 转发记录 settlement.share | B | ShareRecord.org_id |
表里混着平台自己的分享(org_id 为空),要先排除 |
| 看板 platform.dashboard | C | 全平台用户数/机构数 | 会暴露别家规模。如需要,另做「本机构看板」 |
| 题库审核 platform.rumor_questions | C | 题库无机构 | 审核结果影响全平台家长 |
| 结算总览 settlement.overview | C | 跨机构待办 | 平台运营工作台 |
| 渠道管理 settlement.channels | C | 渠道在机构上游 | 会看到别家渠道返点、收款账户 |
| 价格管理 settlement.prices | C | 全平台统一价目 | 改了全平台生效 |
| 客服设置 settlement.support | C | 平台统一配置 | 无机构意义 |
| 系统监控 system.monitoring | C | 服务器指标 | 暴露底层架构 |
| 审计日志 system.audit | C | 含平台管理员操作 | 安全合规工具 |
| 导演台 director.studio | C | 平台内部工具 | 注释已写「仅平台管理员」 |
合计:A 7 个(其中用户管理建议不开)· B 4 个 · C 9 个
users.role='org_admin' + linked_org_id(绑一家机构,品牌方同理)+ 新字段 console_role_group_idconsole_role_groups(名称/说明/启停/创建人)+ console_role_group_menus(角色组, 菜单)app/auth/middleware.py:121 与结算 settlement/backend/app/auth/menu_guard.py:25 的 require_menu:admin 放行 → org_admin 查角色组菜单 → 其余走老表zhaoyang_permissions.py:250 放行 org_admin;细粒度权限按角色组菜单只映射读权限(STORE_READ / LEDGER_READ 等),资金与审核类权限永远不给core_readonly.py 加镜像 + 数据库给 settlement_rw 授 SELECT(需 root)require_role("admin") 改为 require_menu(菜单)(admin 照样全过),只改开放清单里的接口/api/v1/admin/orgs)要换成本机构版本| 批 | 内容 |
|---|---|
| 0 先修 | 题库审核接口无角色校验 · 席位活动假过滤(都是现存漏洞,与本需求无关,先单独修) |
| 1 底座 | 两张表 + 账号字段 + 两端权限判定 + 结算身份放行 + 数据范围依赖 + 越权测试框架 + 审计 |
| 2 前端 | 角色组管理页 + 用户管理页 + 页面拦截 + 机构筛选锁定 |
| 3 A 类 | 子席位、席位活动、签约资料(只读)、收款记录(只读)、收益账本 逐个机构化 + 越权测试 |
| 4 B 类 | 我的机构资料、机构洞察下钻、本机构结算明细、转发记录(可按长官优先级挑) |
| 验收 | test 环境:admin 建角色组 → 给两家机构各开客户账号 → 各自只见授权菜单、只见本机构数据 → 互调对方数据全部被拒 → 停用立即失效 → admin/platform_staff 零回归 |
wecom_admin.py:238、org_config.py:49、api_keys.py:64、excel_import.py:87、org_private_knowledge.py:79)。复用 org_admin 后客户账号后端天然有这些权限(前端无入口)。如不希望,要额外加限制