using ZB.MOM.WW.OtOpcUa.Core.Abstractions; using ZB.MOM.WW.OtOpcUa.Configuration.Enums; namespace ZB.MOM.WW.OtOpcUa.Core.Authorization; /// /// Tri-state result of an call, per decision /// #149. Phase 6.2 only produces and /// ; the /// variant exists in the model so v2.1 Explicit Deny lands without an API break. Provenance /// carries the matched grants (or empty when not granted) for audit + the Admin UI "Probe /// this permission" diagnostic. /// public sealed record AuthorizationDecision( AuthorizationVerdict Verdict, IReadOnlyList Provenance) { public bool IsAllowed => Verdict == AuthorizationVerdict.Allow; /// Convenience constructor for the common "no grants matched" outcome. public static AuthorizationDecision NotGranted() => new(AuthorizationVerdict.NotGranted, []); /// Allow with the list of grants that matched. public static AuthorizationDecision Allowed(IReadOnlyList provenance) => new(AuthorizationVerdict.Allow, provenance); } /// Three-valued authorization outcome. public enum AuthorizationVerdict { /// At least one grant matches the requested (operation, scope) pair. Allow, /// No grant matches. Phase 6.2 default — treated as deny at the OPC UA surface. NotGranted, /// Explicit deny grant matched. Reserved for v2.1; never produced by Phase 6.2. Denied, } /// One grant that contributed to an Allow verdict — for audit / UI diagnostics. /// LDAP group the matched grant belongs to. /// Where in the hierarchy the grant was anchored. /// The bitmask the grant contributed. public sealed record MatchedGrant( string LdapGroup, NodeAclScopeKind Scope, NodePermissions PermissionFlags);