Skip to content

[Membership] DataScope 无法作为行权事实源:Role.Valid 吞掉「全部」、DataScopeInterceptor 校验失败仍 return true、User/Department/Log 未挂载 #98

Description

@Xusp

背景

XCode 已具备数据范围模型:DataScopes(全部=0 … 自定义=4)、Role.DataScope / DataDepartmentIds / ViewSensitive,以及 DataScopeContextDataScopeHelper.GetFilter/CanAccessDataScopeInterceptor

NewLife.Cube WebAPI版本( 前后端分离 ) 希望行级权限唯一跟角色 DataScope 走。当前 Cube 只能用 [DataPermission(null, "ID={#userId}")] 做成「非系统仅本人」,忽略 DataScope。要把行权接到 GetFilter,下列问题必须在 XCode 修:Cube 无法跨程序集给 User/Department/Log 补 partial 接口,也无法挡住 Role.ValidInsert/Update 时把 0 改写成「本部门」。

消费方已锁定:

  1. 实现 IDataScope / IUserScope / IDepartmentScope 的实体自动按 DataScope 过滤。
  2. IUserScope、无部门列的表(日志等):本部门/自定义 不要 join 用户表放大成同事数据。
  3. 普通角色允许把 DataScope 存成全部(0)。
  4. IFieldScope 脱敏由 Cube 调用现有 MaskSensitiveFields

问题 1(P0):Role.ValidDataScope==0 当成未设置

文件:XCode/Membership/角色.Biz.cs(约 133–142 行)

DataScopes.全部 == 0。普通角色保存「全部」时,entity.Valid 会改成「本部门」或「本部门及下级」。Cube 控制器无法覆盖(Save 会再跑一遍 Valid)。

期望:Insert 且 DataScope 不在脏数据中 时按 Type 填默认;Update 或已显式赋值时,0 就是全部。


问题 2(P0):拦截器校验失败仍 return true

文件:XCode/Membership/DataScopeModule.cs OnValid(约 52–79 行)

无权时 throw InvalidOperationException,被 catch 写日志后 return true。挂上拦截器后,越权写入仍成功。

期望: return false 或继续抛出。无上下文时保持不校验。


问题 3(P0):内置实体未挂载,GetFilter 无效

实体 现状 期望
User 已有 IDataScope + FieldProvider,无 DataScopeInterceptor 修完问题 2 后 Add<DataScopeInterceptor>()
Department ITenantScope IDepartmentScope(DepartmentId→ID)+ FieldProvider + 拦截器
Log 无接口,列是 CreateUserID IUserScope 显式映射 + GetUserField() => _.CreateUserID + 拦截器

问题 4(P1):仅 IDepartmentScope + 仅本人 → 空表

仅本人AccessibleDepartmentIds 为空数组,BuildDepartmentFilter 变成 Equal(-1)CanAccess 也对空数组返回 false。部门表「一行一个部门」时,仅本人/本部门应为 ID = 当前用户.DepartmentID。不要改 IDataScope(User)仅本人走 UserId 的语义。


问题 5(P1):纯 IUserScope 保持按用户过滤

非全部时 userField.Equal(当前用户) 请保持,并写进注释:无部门列时本部门不会变成同事可见。


问题 6(P1):缓存键没有 DepartmentID

DataScope:{userId}:{scope} 导致调岗后最多 5 分钟仍用旧部门列表。key 应含 userId+deptId+scopeClearCache(userId) 需清掉该用户新旧两种键。


问题 7(P2):菜单 DataScope 默认 0 会覆盖成「全部」

列注释是 -1=使用角色默认,枚举默认却是 0=全部。SetMenu>=0 时覆盖角色。新建/未配置菜单应保持 -1,不要让未配置变成全部。不必把「继承」加进角色下拉枚举。


建议改动

  1. 角色.Biz.cs — Insert 未赋值才写默认 DataScope
  2. DataScopeModule.cs — OnValid 失败不放行
  3. DataScopeContext.cs — 缓存键与 ClearCache
  4. DataScopeHelper — 部门仅本人≡本部门;IUserScope 注释
  5. 用户.Biz.cs / 部门.Biz.cs / 日志.Biz.cs — 接口 + 拦截器
  6. DataScopeTests.cs — 见下方验收

Cube 会自己:CreateWhere 合并 GetFilter、拆除仅本人 DataPermission、给 Cube 程序集内 Token 等挂 IUserScope


验收(XCode 单测)

  1. 普通角色 DataScope=全部,Update 后仍为全部
  2. Insert 未赋 DataScope 时仍有 Type 默认值
  3. 仅本人上下文,拦截器拒绝改他人 IDataScope 数据
  4. User:本部门滤 DepartmentID,仅本人滤 ID
  5. Log:本部门仍滤 CreateUserID
  6. Department:仅本人滤 ID=当前部门,不是 -1
  7. 同一用户更换 DepartmentID 后部门列表立即更新(或 ClearCache 后必新)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions