The Phase 6.2 evaluator was wired but received no input in production:
RoleBasedIdentity (the IUserIdentity our LDAP path produces) implemented
IRoleBearer but not ILdapGroupsBearer, so AuthorizationGate.BuildSessionState
always returned null and the gate lax-mode-allowed every request. UserAuthResult
also never carried the resolved LDAP groups, only the role-mapped strings.
Closing the gap so the evaluator gets real data:
- UserAuthResult adds Groups alongside Roles. LdapUserAuthenticator now
surfaces the raw RDN values (ReadOnly / WriteOperate / ...) it already
collected during the directory query. Roles stay separate per decision #150
(control-plane Admin role mapping vs data-plane NodeAcl key).
- RoleBasedIdentity implements ILdapGroupsBearer so AuthorizationGate sees
the groups via the same seam unit tests already use.
ThreeUserInteropMatrixTests drives the closure end-to-end against the live
GLAuth dev directory:
- 5 distinct group memberships (readonly / writeop / writetune /
writeconfig / alarmack) plus the multi-group admin user
- Each is bound through the real LdapUserAuthenticator
- Resolved groups feed an LdapBoundIdentity that goes through the strict-mode
AuthorizationGate against a seeded TriePermissionEvaluator
- 31 InlineData rows assert the role × operation matrix; failures pinpoint
the exact (user, op) cell
The remaining wire-level leg of #124 — a real OPC UA client driving UserName
tokens through an encrypted endpoint policy — still needs a deployment knob
and stays a manual cross-vendor smoke (#119 / #124 manual scope). The doc
audit note in admin-ui-phase-6-status.md is updated to reflect what's now
auto'd vs what stays manual.
33/33 new tests pass against live GLAuth; existing 270 non-LiveLdap tests
in Server.Tests still pass; Core.Tests 205/205, Admin.Tests 109/109. The 7
integration-test failures observed during this run pre-exist this commit
(NodeId-scheme regression from #134) and are tracked separately as #135.
Task-by-task audit of the Admin UI quartet shows every page listed in
the task descriptions is already built, routed, DI-wired, SignalR-live,
and covered by Admin.Tests (112/112 green):
- #128 /hosts — Hosts.razor 233 LOC with ConsecutiveFailures +
LastCircuitBreakerOpenUtc + Stale/Faulted/Running cards
- #129 RoleGrants + AclsTab + Probe — RoleGrants.razor (192 LOC),
AclsTab.razor (279 LOC) with the embedded Probe form at line 38
- #130 RedundancyTab — RedundancyTab.razor 175 LOC with peer
reachability / ServiceLevel / apply-lease / failover button
- #131 Draft/Publish/Diff/Identification — DraftEditor (105 LOC) +
Generations (73 LOC) + DiffViewer (87 LOC) + IdentificationFields
(49 LOC), all wired to GenerationService / DraftValidationService
Shipping docs/v2/implementation/admin-ui-phase-6-status.md as the
canonical reference. Each task's required features are listed with the
exact file / LOC / routing + DI injection so future auditors don't
need to re-derive the status.
No code change in this commit — doc-only.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>