using ZB.MOM.WW.MxGateway.Server.Security.Authentication; using ZB.MOM.WW.MxGateway.Server.Sessions; namespace ZB.MOM.WW.MxGateway.Server.Security.Authorization; /// Enforces API-key read/write constraints and records constraint denials for audit. /// /// The per-item checks return because every production check is /// synchronous (an in-memory Galaxy hierarchy lookup) and runs once per item of a bulk command: /// a return allocated a task per item for a value that was already /// known. An implementation that genuinely needs to await still can. /// public interface IConstraintEnforcer { /// /// Gets a value indicating whether any read constraint applies to an identity at all, so a /// bulk caller can hoist the question out of its per-item loop. /// /// The API key identity. /// when at least one read constraint applies; otherwise . /// /// Every per-item / call for /// an unconstrained identity allows the item, so skipping the loop removes work without /// changing a decision. The default implementation answers — an /// implementation that does not model constraints (test doubles, allow-all enforcers) keeps /// being consulted per item rather than being silently bypassed. /// bool HasReadConstraints(ApiKeyIdentity? identity) => true; /// /// Gets a value indicating whether any write constraint applies to an identity at all, the /// write-side counterpart of . /// /// The API key identity. /// when at least one write constraint applies; otherwise . /// The same conservative default as applies. bool HasWriteConstraints(ApiKeyIdentity? identity) => true; /// Checks whether a read constraint is satisfied for a tag address. /// The API key identity. /// Tag address to check. /// Token to observe for cancellation. /// The constraint failure details if denied; otherwise null. ValueTask CheckReadTagAsync( ApiKeyIdentity? identity, string tagAddress, CancellationToken cancellationToken); /// Checks whether a read constraint is satisfied for an item handle. /// The API key identity. /// The gateway session. /// The MXAccess server handle. /// The MXAccess item handle. /// Token to observe for cancellation. /// The constraint failure details if denied; otherwise null. ValueTask CheckReadHandleAsync( ApiKeyIdentity? identity, GatewaySession session, int serverHandle, int itemHandle, CancellationToken cancellationToken); /// Checks whether a write constraint is satisfied for an item handle. /// The API key identity. /// The gateway session. /// The MXAccess server handle. /// The MXAccess item handle. /// Token to observe for cancellation. /// The constraint failure details if denied; otherwise null. ValueTask CheckWriteHandleAsync( ApiKeyIdentity? identity, GatewaySession session, int serverHandle, int itemHandle, CancellationToken cancellationToken); /// Records a constraint denial for audit and metrics. /// The API key identity. /// The kind of command denied. /// The target of the denied command. /// The constraint failure details. /// /// The per-request client correlation id, if any. Stored on the audit record's /// CorrelationId when it parses as a GUID; otherwise left null. /// /// Token to observe for cancellation. /// A task that represents the asynchronous operation. Task RecordDenialAsync( ApiKeyIdentity? identity, string commandKind, string target, ConstraintFailure failure, string? correlationId, CancellationToken cancellationToken); /// /// Records every constraint denial of one bulk command as a single aggregated audit event. /// /// The API key identity. /// The kind of bulk command whose items were denied. /// The accumulated denials: count, constraint names and a bounded target sample. /// The per-request client correlation id, if any (same handling as ). /// Token to observe for cancellation. /// A task that represents the asynchronous operation. /// /// Bulk callers use this instead of one per item: the audit /// channel is bounded and drops on full, so per-item events let one bulk command evict every /// other pending audit record. /// Task RecordBulkDenialAsync( ApiKeyIdentity? identity, string commandKind, ConstraintDenialSummary summary, string? correlationId, CancellationToken cancellationToken); }