Skip to content

fix(AC0031): treat object-level AccessByPermission as permission coverage - #567

Merged
Arthurvdv merged 3 commits into
mainfrom
fix/ac0031-accessbypermission-coverage
Sep 27, 2026
Merged

Arthurvdv merged 3 commits into
mainfrom
fix/ac0031-accessbypermission-coverage

Conversation

@Arthurvdv

@Arthurvdv Arthurvdv commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Problem

A report with AccessByPermission = tabledata "Incoming Document" = RM; and a dataitem on that table gets AC0031 ("does not declare permission 'r' for tabledata 'Incoming Document'"). The object already states that it is only meant for users who hold that permission on the table, so the Info-level suggestion to add Permissions next to it is noise.

Platform facts

  • Permissions grants the object extra table permissions at runtime. AccessByPermission is only a UI-visibility mask: the report or page is removed from Tell Me, menus and role centers when the user lacks the mask. It grants nothing and does not change the runtime data-access checks.
  • Both properties bind through the same Binder.BindPermissionPropertyValue, so the value is a PermissionPropertyValueSyntax in both cases. Outside permission sets the SDK upper-cases the chars, so casing carries no meaning. The object-level property is registered only for pages and reports.
  • The mask is OR-evaluated (with RIMD the user needs at least one char). It applies only when UI Elements Removal is LicenseFile or LicenseFileAndUserPermissions, and the object can still be run from code or a RunObject action.

Change

PermissionResolver.IsCovered now also reads the object-level AccessByPermission property through the existing ObjectPermissionCovers. That method already filters to tabledata, matches the table by name, qualified name or ID, and compares chars case-insensitively. Adds EnumProvider.PropertyKind.AccessByPermission. AC0032 is unchanged.

Decision Choice
Target form tabledata only. AccessByPermission = table X = X (permission to run the object) does not cover data operations.
Mask policy Only the chars in the mask cover, case-insensitively. RD covers r and d; a Modify() in the same object is still reported.
Reach The object-level property on reports and pages only. Field-, part- and action-level AccessByPermission stay out of scope.
AC0032 No change. AccessByPermission is neither a Permissions entry nor a table use. A Permissions entry that duplicates the mask is still reported when the table is never accessed (pinned by a fixture).

Corpus evidence (Base App W1 28.5)

29 reports and 31 pages declare an object-level AccessByPermission = tabledata. 18 of those 29 reports have a dataitem on that table, and none of the 18 also declares Permissions for it. Report 299 "Delete Invoiced Sales Orders" (AccessByPermission = TableData "Sales Header" = RD;) has exactly the shape reported in the issue. The object-level table X = X form does not occur in the corpus.

Tests

  • First commit (TDD): four NoDiagnostic regressions that fail before the fix. They cover the issue shape, report 299's RD plus Delete() in OnAfterGetRecord, a page whose mask names a table other than its SourceTable, and a lowercase mask.
  • HasDiagnostic boundaries: a missing char (R plus Modify()), a mask on a different table, and the table X = X form.
  • AC0032 guards: a mask next to a matching Permissions entry is not reported; a mask does not count as a table use; a duplicated but unused entry is still reported.
  • dotnet test ALCops.sln is green. dotnet format --verify-no-changes is clean. Common and ApplicationCop build for netstandard2.1, net8.0 and net10.0 with no warnings.

Review

/code-review high reported no correctness findings. It raised two other findings:

  1. The AC0032 rule doc implied that a Permissions entry duplicating the mask is suppressed. The bullet now describes the actual behaviour, and the ReportAccessByPermissionDuplicateUnused HasDiagnostic fixture pins it.
  2. A stale header comment in .vscode/Copy-BinToALAnalyzers.ps1. No action: that file is an unrelated uncommitted local change and is not part of this branch.

Docs: ALCops/alcops.dev#192

Closes #312

🤖 Generated with Claude Code

Arthurvdv and others added 3 commits September 27, 2026 09:45
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rage

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ission is still reported when unused

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Arthurvdv
Arthurvdv merged commit f2df4c9 into main Sep 27, 2026
40 checks passed
@Arthurvdv
Arthurvdv deleted the fix/ac0031-accessbypermission-coverage branch September 27, 2026 08:25
@Arthurvdv Arthurvdv added part of upcoming release Available in alpha/beta and waiting to be included in the next stable release and removed part of upcoming release Available in alpha/beta and waiting to be included in the next stable release labels Sep 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AC0031 Special Case for Objects with AccessByPermission

1 participant