fix: 修复授权记录备注修改权限问题
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m42s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m42s
- 实现备注权限检查逻辑(authorization_service.go) - 添加备注权限验证存储层(authorization_store.go) - 新增集成测试覆盖备注权限场景 - 归档 fix-authorization-remark-permission 变更 - 同步 enterprise-card-authorization spec 规范
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
schema: spec-driven
|
||||
created: 2026-01-29
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
# 授权记录备注修改权限修复 - 设计
|
||||
|
||||
## 目标
|
||||
|
||||
1. 代理用户无法修改非本人创建的授权记录备注。
|
||||
2. 企业用户无法修改任何授权记录备注。
|
||||
3. 平台/超级管理员可修改任意授权记录备注。
|
||||
4. 任何情况下都必须满足数据可见性(代理只能在自己店铺企业范围内操作)。
|
||||
|
||||
## 现状与风险点
|
||||
|
||||
- 备注更新当前仅按 `id` 更新,缺少“创建者/可见性”约束。
|
||||
- 现有数据权限 callback 主要作用于 Query,不覆盖 Update,因此必须在业务链路显式校验。
|
||||
|
||||
## 方案
|
||||
|
||||
### 1) Service 层统一鉴权
|
||||
|
||||
在 `AuthorizationService.UpdateRecordRemark` 内新增权限判断:
|
||||
|
||||
- 取当前用户信息(user_id/user_type/shop_id/enterprise_id)
|
||||
- 先通过 `GetByIDWithJoin` 获取授权记录详情(包含 `authorized_by`、`enterprise_id` 等)
|
||||
- 按规则判断:
|
||||
- 平台/超级管理员:允许
|
||||
- 代理:
|
||||
- 必须 `record.AuthorizedBy == 当前 user_id`
|
||||
- 且授权记录对应企业必须属于当前店铺(`enterprise.owner_shop_id == shop_id`,可通过 join 查询或使用现有原生 SQL 结果)
|
||||
- 企业:直接拒绝
|
||||
|
||||
### 2) Store 层更新增加约束(防御性)
|
||||
|
||||
提供一个“带约束”的更新方法(示例语义):
|
||||
- 平台路径:`UpdateRemarkByID(id, remark)`
|
||||
- 代理路径:`UpdateRemarkByIDAndAuthorizedBy(id, remark, userID)`(必要时再加 enterprise 范围约束)
|
||||
|
||||
确保即使上层遗漏判断,也难以越权更新成功。
|
||||
|
||||
### 3) 错误与返回
|
||||
|
||||
- 无权限:返回统一错误码(例如 `CodeForbidden`),错误信息使用中文并可被前端直接展示。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 平台用户可修改任意授权记录备注。
|
||||
- 代理用户仅可修改自己创建的授权记录备注;修改他人创建的记录必须失败。
|
||||
- 企业用户调用修改备注接口必须失败。
|
||||
- 新增/更新用例后相关集成测试通过。
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# 授权记录备注修改权限修复
|
||||
|
||||
## Why
|
||||
|
||||
当前“授权记录备注修改”链路缺少明确的权限边界校验:代理用户可能通过接口修改不属于自己创建的授权记录备注;企业用户也需要被明确禁止修改。
|
||||
|
||||
该问题会导致越权修改、审计信息失真,属于高风险权限缺陷。
|
||||
|
||||
## What Changes
|
||||
|
||||
- **权限规则落地**:
|
||||
- 平台/超级管理员:可修改任意授权记录备注
|
||||
- 代理:仅可修改“自己创建的授权记录”的备注(且必须在其可见数据范围内)
|
||||
- 企业:禁止修改授权记录备注
|
||||
- **服务端强校验**:在 Service 层统一做权限判断与可见性校验,Store 层更新语句增加必要约束,避免仅凭 `id` 更新造成越权。
|
||||
- **补充测试**:新增集成测试覆盖平台/代理/企业三种用户场景,确保规则稳定。
|
||||
|
||||
## Impact
|
||||
|
||||
涉及文件(预期):
|
||||
- Handler:`internal/handler/admin/authorization.go`
|
||||
- Service:`internal/service/enterprise_card/authorization_service.go`
|
||||
- Store:`internal/store/postgres/enterprise_card_authorization_store.go`
|
||||
- 测试:`tests/integration/authorization_test.go`(或新增对应用例文件)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 授权记录备注修改权限
|
||||
|
||||
系统 SHALL 对授权记录备注修改操作实施严格的权限控制,确保只有有权限的用户才能修改授权记录的备注信息。
|
||||
|
||||
**权限规则**:
|
||||
- **超级管理员/平台用户**:可以修改任意授权记录的备注
|
||||
- **代理账号**:仅可修改自己创建的授权记录的备注(authorized_by 等于自己的账号 ID)
|
||||
- **企业账号**:禁止修改授权记录备注(即使是授权给自己企业的记录)
|
||||
|
||||
**实施方式**:
|
||||
- Service 层 MUST 在 `UpdateRecordRemark` 方法中校验用户权限和创建者匹配
|
||||
- Store 层 MUST 在更新语句中增加 `authorized_by` 约束条件(对代理用户)
|
||||
- Handler 层 MUST 将权限失败场景返回统一错误码和中文错误消息
|
||||
|
||||
**错误处理**:
|
||||
- 代理尝试修改他人创建的记录:返回错误码 `CodePermissionDenied`(1003),消息"无权修改该授权记录的备注"
|
||||
- 企业用户尝试修改:返回错误码 `CodePermissionDenied`(1003),消息"企业用户无权修改授权记录备注"
|
||||
- 记录不存在或不在可见范围:返回错误码 `CodeRecordNotFound`(2001),消息"授权记录不存在"
|
||||
|
||||
#### Scenario: 平台用户修改任意授权记录备注
|
||||
|
||||
- **WHEN** 平台用户调用备注修改接口,指定任意授权记录 ID 和新备注内容
|
||||
- **THEN** 系统成功更新该授权记录的 `remark` 字段,返回成功响应
|
||||
|
||||
#### Scenario: 代理修改自己创建的授权记录备注
|
||||
|
||||
- **WHEN** 代理账号(account_id=100)调用备注修改接口,修改自己创建的授权记录(authorized_by=100)的备注
|
||||
- **THEN** 系统成功更新该授权记录的 `remark` 字段,返回成功响应
|
||||
|
||||
#### Scenario: 代理尝试修改他人创建的授权记录备注
|
||||
|
||||
- **WHEN** 代理账号(account_id=100)调用备注修改接口,尝试修改其他代理创建的授权记录(authorized_by=200)的备注
|
||||
- **THEN** 系统拒绝操作,返回错误码 `1003`,错误消息"无权修改该授权记录的备注",不执行任何更新
|
||||
|
||||
#### Scenario: 企业用户尝试修改授权记录备注
|
||||
|
||||
- **WHEN** 企业账号调用备注修改接口,尝试修改授权给自己企业的授权记录的备注
|
||||
- **THEN** 系统拒绝操作,返回错误码 `1003`,错误消息"企业用户无权修改授权记录备注",不执行任何更新
|
||||
|
||||
#### Scenario: 代理修改不存在或不可见的授权记录备注
|
||||
|
||||
- **WHEN** 代理账号调用备注修改接口,指定的授权记录 ID 不存在或不在其数据权限范围内
|
||||
- **THEN** 系统返回错误码 `2001`,错误消息"授权记录不存在",不执行任何更新
|
||||
@@ -0,0 +1,18 @@
|
||||
# 授权记录备注修改权限修复 - 实现任务
|
||||
|
||||
## 1. 权限规则实现
|
||||
|
||||
- [x] 1.1 在 `internal/service/enterprise_card/authorization_service.go` 中为 `UpdateRecordRemark` 增加权限校验:平台全量、代理仅本人创建、企业禁止
|
||||
- [x] 1.2 在 `internal/store/postgres/enterprise_card_authorization_store.go` 增加带约束的更新方法(至少支持 `id + authorized_by` 约束)
|
||||
- [x] 1.3 更新 `internal/handler/admin/authorization.go`:将权限失败场景返回统一错误(中文错误消息)
|
||||
|
||||
## 2. 测试
|
||||
|
||||
- [x] 2.1 为平台用户新增集成测试:可修改任意授权记录备注
|
||||
- [x] 2.2 为代理用户新增集成测试:可修改本人创建记录、不可修改他人创建记录
|
||||
- [x] 2.3 为企业用户新增集成测试:调用修改备注接口必须失败
|
||||
|
||||
## 3. 验证
|
||||
|
||||
- [x] 3.1 运行 `go test ./...` 确保通过
|
||||
|
||||
Reference in New Issue
Block a user