docs(mesh-phase4): add Task 1b (driver-only LDAP mapper) discovered during Task 1
Gating ConfigDb on hasAdmin exposed a 6th driver-side ConfigDb consumer the §6.1 audit missed: OtOpcUaGroupRoleMapper's ILdapGroupRoleMappingService dep. Task 7 gains a fused-node ordering pin (Task 1b review gap). Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW
This commit is contained in:
@@ -129,6 +129,49 @@ node: "driver-only node — no ConfigDb registered; config via ConfigSource:Mode
|
||||
|
||||
---
|
||||
|
||||
## Task 1b: driver-only `ILdapGroupRoleMappingService` — empty (appsettings-only group→role) — DISCOVERED during Task 1
|
||||
|
||||
**Classification:** small
|
||||
**Estimated implement time:** ~4 min
|
||||
**Parallelizable with:** Task 5
|
||||
|
||||
**Files:**
|
||||
- Create: `src/Server/ZB.MOM.WW.OtOpcUa.Security/Ldap/NullLdapGroupRoleMappingService.cs` (or a Host-side
|
||||
driver-only impl — place it beside `OtOpcUaGroupRoleMapper`)
|
||||
- Modify: `src/Server/ZB.MOM.WW.OtOpcUa.Host/Program.cs:317-327` (the `hasDriver` auth block — register the
|
||||
empty service with `TryAddScoped` so a fused node keeps the real EF one; fix the now-false comment at
|
||||
322-323)
|
||||
- Test: `tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests/` (or wherever `OtOpcUaGroupRoleMapper` is tested)
|
||||
|
||||
**Context — a 6th ConfigDb consumer the §6.1 audit missed.** `OtOpcUaGroupRoleMapper` (the OPC UA
|
||||
data-path group→role mapper, `IGroupRoleMapper<string>`, registered at `Program.cs:327`) merges the
|
||||
appsettings `Security:Ldap:GroupToRole` baseline (always available) with **system-wide DB grants** from
|
||||
`ILdapGroupRoleMappingService` — which is registered **only** inside `AddOtOpcUaConfigDb`. Task 1 gated
|
||||
that on `hasAdmin`, so a driver-only node now cannot resolve `IGroupRoleMapper<string>` at OPC UA login
|
||||
(lazy scoped resolve — `Build()` does not surface it; the auth path does). `LdapGroupRoleMapping` rows are
|
||||
**not** in the deployment artifact (`ConfigComposer` never composes them), so driver nodes never received
|
||||
DB grants via config in the first place. The honest fix: a driver-only `ILdapGroupRoleMappingService` whose
|
||||
`GetByGroupsAsync` returns empty (CRUD methods throw `NotSupportedException` — never called with no AdminUI),
|
||||
registered via `TryAddScoped` in the `hasDriver` block so the fused node's real EF impl still wins.
|
||||
**Behavior reduction to document (Task 8):** DB-backed LDAP group→role grants (the AdminUI RoleGrants page)
|
||||
apply only where ConfigDb is present (admin/fused nodes); driver-only site nodes map groups→roles from
|
||||
`Security:Ldap:GroupToRole` appsettings only.
|
||||
|
||||
**Step 1: Write the failing test** — resolve `IGroupRoleMapper<string>` in a driver-only service graph and
|
||||
call `MapAsync(["some-group"])` → returns the appsettings baseline with no throw (today it throws:
|
||||
`ILdapGroupRoleMappingService` unresolvable).
|
||||
|
||||
**Step 2:** Run — fails.
|
||||
|
||||
**Step 3: Implement** the empty service + `TryAddScoped` registration in the `hasDriver` block; correct the
|
||||
`Program.cs:322-323` comment to state the driver-only node uses the empty impl and why.
|
||||
|
||||
**Step 4:** Run tests + build.
|
||||
|
||||
**Step 5: Commit** — `fix(mesh-phase4): driver-only nodes map LDAP groups from appsettings (no ConfigDb grants)`.
|
||||
|
||||
---
|
||||
|
||||
## Task 2: `DbHealthProbeActor` — do not spawn on driver-only; `DbReachable=true` constant
|
||||
|
||||
**Classification:** high-risk
|
||||
@@ -346,7 +389,12 @@ that the driver-only node never serves login (it hosts no AdminUI — see the to
|
||||
**Step 1: Write the failing test** — a "driver-only DI graph resolves nothing ConfigDb-bound" test:
|
||||
build the `hasDriver && !hasAdmin` service provider and assert
|
||||
`GetService<IDbContextFactory<OtOpcUaConfigDbContext>>()` is null AND that spawning the runtime actors
|
||||
does not throw.
|
||||
does not throw. **Also pin the Task-1b fused-node ordering** (Task 1b review gap): build the
|
||||
`hasAdmin && hasDriver` graph through the same `AddOtOpcUaConfigDb` + `hasDriver` TryAdd sequence and assert
|
||||
`GetService<ILdapGroupRoleMappingService>()` resolves the **real** `LdapGroupRoleMappingService`, not the
|
||||
`Null…` — so a later reorder of the role blocks (or switching `AddOtOpcUaConfigDb` to a TryAdd) fails a
|
||||
red test instead of silently stripping DB-backed role grants from central. Also resolve
|
||||
`IGroupRoleMapper<string>` in a driver-only scope to catch the lazy auth-path break Task 1b fixed.
|
||||
|
||||
**Step 2:** Run — fix whatever it catches.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user