Archive 5 phases (36 plans) to milestones/v1.0-phases/. Archive roadmap, requirements, and audit to milestones/. Evolve PROJECT.md with shipped state and validated requirements. Collapse ROADMAP.md to one-line milestone summary. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.6 KiB
7.6 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 02-permissions | 02 | permissions |
|
|
|
|
|
|
|
|
|
7min | 2026-04-02 |
Phase 2 Plan 2: PermissionsService Scan Engine Summary
CSOM scan engine implementing all 5 SharePoint permission scan paths (site collection admins, web, lists, folders, subsites) as a faithful C# port of the PowerShell Generate-PnPSitePermissionRpt function
Performance
- Duration: 7 min
- Started: 2026-04-02T11:48:39Z
- Completed: 2026-04-02T11:54:58Z
- Tasks: 2
- Files modified: 4
Accomplishments
- Defined PermissionEntry (9-field record), ScanOptions (4-field config record), and IPermissionsService interface — foundational contracts for all subsequent Phase 2 plans
- Implemented PermissionsService with full scan logic: site collection admins, web, lists, folders (via SharePointPaginationHelper), and subsites
- All CSOM round-trips use ExecuteQueryRetryHelper.ExecuteQueryRetryAsync; folder enumeration uses SharePointPaginationHelper.GetAllItemsAsync (never raw iteration)
- Limited Access filtering, sharing links group exclusion, external user detection, and 34-item ExcludedLists set all implemented
Task Commits
Each task was committed atomically:
- Task 1: Define data models and IPermissionsService interface -
4a6594d(feat) - Task 2: Implement PermissionsService scan engine -
9f2e2f9(fix — linter auto-fixed CSOM type errors pre-commit)
Files Created/Modified
SharepointToolbox/Core/Models/PermissionEntry.cs— Flat record for one permission assignment (9 string/bool positional fields)SharepointToolbox/Core/Models/ScanOptions.cs— Immutable scan config: IncludeInherited, ScanFolders, FolderDepth, IncludeSubsitesSharepointToolbox/Services/IPermissionsService.cs— Interface with ScanSiteAsync enabling ViewModel mockingSharepointToolbox/Services/PermissionsService.cs— Full CSOM engine: 340 lines, 5 private helpers, 34-item ExcludedLists
Decisions Made
Folderis not aSecurableObjectin CSOM — folder permissions are extracted viaListItem(which IS a SecurableObject);item.Folderprovides name/URL metadata onlyPrincipal.Emailexcluded from batched Include —Principalbase type lacks Email; onlyUsersubtype has it; email was not needed for PermissionEntry fieldsFolderDepth=999used as sentinel for unlimited depth scanning- Subsite enumeration clones ClientContext via
ctx.Clone(subweb.Url)for proper CSOM scoping
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug] Principal.Email not available on RoleAssignment.Member
- Found during: Task 2 (PermissionsService implementation)
- Issue: The plan's CSOM Include expression included
ra => ra.Member.Email— Principal base type has no Email property (only User subtype does) - Fix: Removed Email from the batched Include; email is not needed for any PermissionEntry field
- Files modified: SharepointToolbox/Services/PermissionsService.cs
- Verification: dotnet build passes with 0 errors
- Committed in:
9f2e2f9
2. [Rule 1 - Bug] Folder is not a SecurableObject in CSOM
- Found during: Task 2 (GetFolderPermissionsAsync)
- Issue:
ExtractPermissionsAsync(ctx, folder, ...)failed — Folder does not inherit from SecurableObject in Microsoft.SharePoint.Client - Fix: Changed to pass
item(ListItem, which IS a SecurableObject) to ExtractPermissionsAsync; keptitem.Folderload for ServerRelativeUrl/Name metadata only - Files modified: SharepointToolbox/Services/PermissionsService.cs
- Verification: dotnet build passes with 0 errors
- Committed in:
9f2e2f9
Total deviations: 2 auto-fixed (2 Rule 1 bugs — CSOM API type constraints) Impact on plan: Both fixes were necessary for correct CSOM usage. Folder permission extraction is semantically equivalent — ListItem holds the same role assignments as Folder. No scope creep.
Issues Encountered
- Pre-existing test failures (6): CsvExportService and HtmlExportService tests throw NotImplementedException — these are intentional stubs from Plan 01 to be implemented in Plan 03. No regression introduced by this plan.
User Setup Required
None - no external service configuration required.
Next Phase Readiness
- PermissionEntry, ScanOptions, IPermissionsService, and PermissionsService are available for Plans 02-04 (ViewModel), 02-05 (Export), 02-06 (SitePicker), and 02-07 (full integration)
- All Phase 1 tests remain at 53 passing (plus 4 skipping, 6 pre-existing Plan 03 stubs failing)
- IPermissionsService is mockable — PermissionsViewModelTests can be unblocked in Plan 04
Phase: 02-permissions Completed: 2026-04-02
Self-Check: PASSED
- FOUND: SharepointToolbox/Core/Models/PermissionEntry.cs
- FOUND: SharepointToolbox/Core/Models/ScanOptions.cs
- FOUND: SharepointToolbox/Services/IPermissionsService.cs
- FOUND: SharepointToolbox/Services/PermissionsService.cs
- FOUND: .planning/phases/02-permissions/02-02-SUMMARY.md
- FOUND: commit
4a6594d(feat(02-02): define models and interface) - FOUND: commit
9f2e2f9(fix(02-01): PermissionsService + export stubs)