Skip to content

[Membership] Make role DataScope the single source of truth for row-level access - #99

Draft
nnhy with Copilot wants to merge 3 commits into
masterfrom
copilot/fix-datascope-validation-issue
Draft

[Membership] Make role DataScope the single source of truth for row-level access#99
nnhy with Copilot wants to merge 3 commits into
masterfrom
copilot/fix-datascope-validation-issue

Conversation

Copilot AI commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

DataScope could not drive row-level permissions: Role.Valid rewrote "全部"(0) on every save, DataScopeInterceptor.OnValid swallowed access failures and returned true, and User/Department/Log were not wired into GetFilter. This makes the role DataScope field the authoritative row-permission source, which XCode must own since Cube cannot patch these across assemblies.

Validation (P0)

  • 角色.Biz.cs — Default DataScope from Type only on Insert when the field is not dirty. On Update or explicit assignment, 0 means "全部" and is left untouched.
  • DataScopeModule.csOnValid now returns false (after writing the audit log) when an access check throws, instead of returning true. No-context still skips validation.

Entity wiring (P0)

  • User — register DataScopeInterceptor.
  • Department — implement IDepartmentScope (DepartmentId→ID) + IDataScopeFieldProvider + interceptor.
  • Log — implement IUserScope (→CreateUserID), GetUserField() => _.CreateUserID + interceptor.

Filter semantics (P1)

  • Pure IDepartmentScope (one row per department): 仅本人 filters ID = current department instead of the always-false Equal(-1); other scopes reuse BuildDepartmentFilter. CanAccess(IDepartmentScope) mirrors this. IDataScope (User) 仅本人-by-UserId semantics are unchanged.
  • Pure IUserScope (no department column, e.g. Log): non-全部 stays userField = currentUser, so 本部门/自定义 do not widen to colleagues' rows.

Cache (P1)

  • DataScopeContext — cache key is now userId+deptId+scope so a department change takes effect immediately; ClearCache(userId) removes both old and new keys by prefix (best-effort).

Menu default (P2)

  • 菜单.Biz.cs — new/unconfigured menus keep DataScope = -1 (use role default) rather than persisting 0 and overriding the role to "全部".

Example

// Log: no department column → 本部门 filters by creator, not colleagues
DataScopeContext.Current = new DataScopeContext
{
    UserId = 100, DepartmentId = 200,
    DataScope = DataScopes.本部门, AccessibleDepartmentIds = [200]
};
var filter = DataScopeHelper.GetFilter<Log>();   // CreateUserID = 100

// Department: 仅本人 → own department row, not an empty table
DataScopeContext.Current = new DataScopeContext { UserId = 100, DepartmentId = 200, DataScope = DataScopes.仅本人 };
var deptFilter = DataScopeHelper.GetFilter<Department>();   // ID = 200 (was ID = -1)

Adds 7 acceptance tests in DataScopeTests.cs covering the criteria above, and corrects one existing test that relied on the swallowed-exception behavior.

Copilot AI and others added 2 commits August 27, 2026 15:39
Co-authored-by: nnhy <506367+nnhy@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix DataScope validation issue in XCode [Membership] Make role DataScope the single source of truth for row-level access Aug 27, 2026
Copilot AI requested a review from nnhy August 27, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants