fix(rbac): 交易权限的 data_scope 写成了动作名,导致下单/成交静默 403
`tools/seed_test_rbac.py` 的 `PERMISSIONS` 行形状是
`(id, 权限码, resource, action, data_scope)`,而 T 段那四条写成了
`(9061, "trade:order:create", "trade", "order", "create")` ——
「resource, action」多写了一段,于是 action 落进了 `data_scope` 的位置。
## 后果是静默失效,不是放宽
`IdentityRepository.load_context` 只收集 `data_scope ∈ {self, own_customers, all}`
的权限,其余**整条丢弃**:
if row["permission_code"] and row["data_scope"] in rank:
于是客户在库里**明明有**这四个权限,`POST /api/v1/users/me/orders`、
`GET /api/v1/users/me/orders`、`GET /api/v1/users/me/transactions` 等 T 段端点
却全部返回 `403 AGENT_PERMISSION_DENIED`「缺少操作权限」。
而同一批里 `account:read:self`、`holding:read:self` 的 scope 是 `self`,照常 200 ——
现象特别像"只有交易坏了",几乎不会有人去怀疑**权限行本身写错了字段**。
因为 seed 是 `DELETE FROM sys_permission WHERE id BETWEEN 9001 AND 9099` 的**重建**语义,
**每跑一次种子就重现一次**,而 `tools/seed_demo_data.py` 的第 1 步正是它。
## 修复与守卫
- 四条改为 `"self"`,并就地写清第 5 个字段是 `data_scope`、只能取三种值;
- `tools/check_rbac_seed_consistency.py` 增加**第 5 条检查**:每行字段数必须是 5,
且 `data_scope` 取值合法。已用模拟对象确认它能抓住事故写法
(非法 scope 报 2 条、字段数不足报 1 条、合法写法通过),
并由 `tests/unit/tools/test_rbac_seed_consistency.py` 纳入门禁。
修复后实测:库内非法 `data_scope` 归零(`self` 22 → 26);
`/users/me/{account/dashboard,holdings,transactions,orders}` 全部 200;
下单成交价 4.579(真实行情);e2e 冒烟 40/40;integration 106 passed。
This commit is contained in:
+12
-4
@@ -144,11 +144,19 @@ PERMISSIONS: tuple[tuple[int, str, str, str, str], ...] = (
|
||||
# `PERMISSIONS`,同时挂在 `CUSTOMER_PERMISSIONS` 让 customer 角色自带。
|
||||
# 号段续 9060(避开 9047-9059 qyqy 风险/推广/探针/投资目标号段):与 9041-9046 客服二期间隔 1,避免与既有迁移/种子冲突。
|
||||
(9060, "account:read:self", "account", "read", "self"),
|
||||
(9061, "trade:order:create", "trade", "order", "create"),
|
||||
(9062, "trade:order:read", "trade", "order", "read"),
|
||||
(9063, "trade:order:cancel", "trade", "order", "cancel"),
|
||||
# ⚠️ 第 5 个字段是 **data_scope**,只能取 `self` / `own_customers` / `all`。
|
||||
# 这四条原先误写成 `trade, order, create` 这样的「resource, action, action」三段,
|
||||
# 于是 action 落进了 data_scope 位置(值为 'create'/'read'/'cancel')。
|
||||
# 后果不是"宽松"而是**静默失效**:`IdentityRepository.load_context` 只收集
|
||||
# data_scope 合法的权限,这四条会被整条丢掉 ⇒ 客户在**库里明明有**这四个权限,
|
||||
# 下单/委托/成交却全部 `403 AGENT_PERMISSION_DENIED`,
|
||||
# 而 T001/T006(`account:read:self`/`holding:read:self` 是 'self')照常 200,
|
||||
# 所以现象特别像"只有交易坏了",很难联想到权限码本身写错。
|
||||
(9061, "trade:order:create", "trade", "order", "self"),
|
||||
(9062, "trade:order:read", "trade", "order", "self"),
|
||||
(9063, "trade:order:cancel", "trade", "order", "self"),
|
||||
(9064, "holding:read:self", "holding", "read", "self"),
|
||||
(9065, "trade:txn:read", "trade", "txn", "read"),
|
||||
(9065, "trade:txn:read", "trade", "txn", "self"),
|
||||
)
|
||||
|
||||
# 客户:业务侧自助能力(自己的会话、反馈、转人工、自己的记忆画像)。
|
||||
|
||||
Reference in New Issue
Block a user