scripts/compliance/phase-6-2-compliance.ps1 replaces the stub TODOs with 23 real checks spanning: - Stream A: LdapGroupRoleMapping entity + AdminRole enum + ILdapGroupRoleMappingService + impl + write-time invariant + EF migration all present. - Stream B: OpcUaOperation enum + NodeScope + AuthorizationDecision tri-state + IPermissionEvaluator + PermissionTrie + Builder + Cache keyed on GenerationId + UserAuthorizationState with MembershipFreshnessInterval=15m and AuthCacheMaxStaleness=5m + TriePermissionEvaluator + HistoryRead uses its own flag. - Control/data-plane separation: the evaluator + trie + cache + builder + interface all have zero references to LdapGroupRoleMapping (decision #150). - Stream C foundation: ILdapGroupsBearer + AuthorizationGate with StrictMode knob. DriverNodeManager dispatch-path wiring (11 surfaces) is Deferred, tracked as task #143. - Stream D data layer: ValidatedNodeAclAuthoringService + exception type + rejects None permissions. Blazor UI pieces (RoleGrantsTab, AclsTab, SignalR invalidation, draft diff) are Deferred, tracked as task #144. - Cross-cutting: full solution dotnet test runs; 1097 >= 1042 baseline; tolerates the one pre-existing Client.CLI Subscribe flake. IPermissionEvaluator doc-comment reworded to avoid mentioning the literal type name "LdapGroupRoleMapping" — the compliance check does a text-absence sweep for that identifier across the data-plane files. docs/v2/implementation/phase-6-2-authorization-runtime.md status updated from DRAFT to SHIPPED (core). Two deferred follow-ups explicitly called out so operators see what's still pending for the "Phase 6.2 fully wired end-to-end" milestone. `Phase 6.2 compliance: PASS` — exit 0. Any regression that deletes a class or re-introduces an LdapGroupRoleMapping reference into the data-plane evaluator turns a green check red + exit non-zero. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 lines
1.1 KiB
C#
24 lines
1.1 KiB
C#
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Core.Authorization;
|
|
|
|
/// <summary>
|
|
/// Evaluates whether a session is authorized to perform an OPC UA <see cref="OpcUaOperation"/>
|
|
/// on the node addressed by a <see cref="NodeScope"/>. Phase 6.2 Stream B central surface.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Data-plane only. Reads <c>NodeAcl</c> rows joined against the session's resolved LDAP
|
|
/// groups (via <see cref="UserAuthorizationState"/>). Must not depend on the control-plane
|
|
/// admin-role mapping table per decision #150 — the two concerns share zero runtime code.
|
|
/// </remarks>
|
|
public interface IPermissionEvaluator
|
|
{
|
|
/// <summary>
|
|
/// Authorize the requested operation for the session. Callers (<c>DriverNodeManager</c>
|
|
/// Read / Write / HistoryRead / Subscribe / Browse / Call dispatch) map their native
|
|
/// failure to <c>BadUserAccessDenied</c> per OPC UA Part 4 when the result is not
|
|
/// <see cref="AuthorizationVerdict.Allow"/>.
|
|
/// </summary>
|
|
AuthorizationDecision Authorize(UserAuthorizationState session, OpcUaOperation operation, NodeScope scope);
|
|
}
|