docs+ui: backfill XML doc comments and finish dashboard layout pass
Adds missing <summary>/<param> XML docs across 99 server, worker, and test files so CommentChecker reports zero issues (TreatWarningsAsErrors needs the analyzer clean). Bundles in WIP dashboard work: NavSection extraction, MainLayout/site.css/js styling alignment, and DashboardOptions/Auth tweaks.
This commit is contained in:
@@ -10,12 +10,16 @@ public static class ApiKeyConstraintSerializer
|
||||
WriteIndented = false,
|
||||
};
|
||||
|
||||
/// <summary>Serializes API key constraints to JSON, or returns null if the constraints are empty.</summary>
|
||||
/// <param name="constraints">The constraints to serialize.</param>
|
||||
public static string? Serialize(ApiKeyConstraints constraints)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(constraints);
|
||||
return constraints.IsEmpty ? null : JsonSerializer.Serialize(constraints, JsonOptions);
|
||||
}
|
||||
|
||||
/// <summary>Deserializes API key constraints from JSON, or returns empty constraints if JSON is null or whitespace.</summary>
|
||||
/// <param name="json">The JSON string to deserialize.</param>
|
||||
public static ApiKeyConstraints Deserialize(string? json)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
|
||||
@@ -10,6 +10,7 @@ public sealed record ApiKeyConstraints(
|
||||
bool ReadAlarmOnly,
|
||||
bool ReadHistorizedOnly)
|
||||
{
|
||||
/// <summary>Gets an empty constraints instance with no restrictions.</summary>
|
||||
public static ApiKeyConstraints Empty { get; } = new(
|
||||
ReadSubtrees: Array.Empty<string>(),
|
||||
WriteSubtrees: Array.Empty<string>(),
|
||||
@@ -20,6 +21,7 @@ public sealed record ApiKeyConstraints(
|
||||
ReadAlarmOnly: false,
|
||||
ReadHistorizedOnly: false);
|
||||
|
||||
/// <summary>Gets a value indicating whether the constraints are empty (no restrictions).</summary>
|
||||
public bool IsEmpty =>
|
||||
ReadSubtrees.Count == 0
|
||||
&& WriteSubtrees.Count == 0
|
||||
@@ -30,12 +32,14 @@ public sealed record ApiKeyConstraints(
|
||||
&& !ReadAlarmOnly
|
||||
&& !ReadHistorizedOnly;
|
||||
|
||||
/// <summary>Gets a value indicating whether any read constraints are defined.</summary>
|
||||
public bool HasReadConstraints =>
|
||||
ReadSubtrees.Count > 0
|
||||
|| ReadTagGlobs.Count > 0
|
||||
|| ReadAlarmOnly
|
||||
|| ReadHistorizedOnly;
|
||||
|
||||
/// <summary>Gets a value indicating whether any write constraints are defined.</summary>
|
||||
public bool HasWriteConstraints =>
|
||||
WriteSubtrees.Count > 0
|
||||
|| WriteTagGlobs.Count > 0
|
||||
|
||||
@@ -7,5 +7,6 @@ public sealed record ApiKeyIdentity(
|
||||
IReadOnlySet<string> Scopes,
|
||||
ApiKeyConstraints? Constraints = null)
|
||||
{
|
||||
/// <summary>Gets the effective API key constraints (defaults to Empty if null).</summary>
|
||||
public ApiKeyConstraints EffectiveConstraints => Constraints ?? ApiKeyConstraints.Empty;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,8 @@ public sealed class AuthSqliteConnectionFactory(IOptions<GatewayOptions> options
|
||||
/// non-zero busy timeout so concurrent readers and writers degrade gracefully
|
||||
/// rather than surfacing <c>SQLITE_BUSY</c> as a hard failure.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token for the operation.</param>
|
||||
/// <returns>An opened and configured SQLite connection.</returns>
|
||||
public async Task<SqliteConnection> OpenConnectionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
SqliteConnection connection = CreateConnection();
|
||||
|
||||
@@ -9,6 +9,10 @@ public sealed class ConstraintEnforcer(
|
||||
IGalaxyHierarchyCache cache,
|
||||
IApiKeyAuditStore auditStore) : IConstraintEnforcer
|
||||
{
|
||||
/// <summary>Checks read constraints on a tag address.</summary>
|
||||
/// <param name="identity">The API key identity to check constraints for.</param>
|
||||
/// <param name="tagAddress">Tag address to validate.</param>
|
||||
/// <param name="cancellationToken">Token to observe for cancellation.</param>
|
||||
public Task<ConstraintFailure?> CheckReadTagAsync(
|
||||
ApiKeyIdentity? identity,
|
||||
string tagAddress,
|
||||
@@ -23,6 +27,12 @@ public sealed class ConstraintEnforcer(
|
||||
return Task.FromResult(CheckReadTarget(constraints, tagAddress));
|
||||
}
|
||||
|
||||
/// <summary>Checks read constraints on a server and item handle.</summary>
|
||||
/// <param name="identity">The API key identity to check constraints for.</param>
|
||||
/// <param name="session">The gateway session containing handle registrations.</param>
|
||||
/// <param name="serverHandle">The MXAccess server handle.</param>
|
||||
/// <param name="itemHandle">The MXAccess item handle.</param>
|
||||
/// <param name="cancellationToken">Token to observe for cancellation.</param>
|
||||
public Task<ConstraintFailure?> CheckReadHandleAsync(
|
||||
ApiKeyIdentity? identity,
|
||||
GatewaySession session,
|
||||
@@ -44,6 +54,12 @@ public sealed class ConstraintEnforcer(
|
||||
return Task.FromResult(CheckReadTarget(constraints, registration.TagAddress));
|
||||
}
|
||||
|
||||
/// <summary>Checks write constraints on a server and item handle.</summary>
|
||||
/// <param name="identity">The API key identity to check constraints for.</param>
|
||||
/// <param name="session">The gateway session containing handle registrations.</param>
|
||||
/// <param name="serverHandle">The MXAccess server handle.</param>
|
||||
/// <param name="itemHandle">The MXAccess item handle.</param>
|
||||
/// <param name="cancellationToken">Token to observe for cancellation.</param>
|
||||
public Task<ConstraintFailure?> CheckWriteHandleAsync(
|
||||
ApiKeyIdentity? identity,
|
||||
GatewaySession session,
|
||||
@@ -92,6 +108,12 @@ public sealed class ConstraintEnforcer(
|
||||
return Task.FromResult<ConstraintFailure?>(null);
|
||||
}
|
||||
|
||||
/// <summary>Records a constraint denial audit entry.</summary>
|
||||
/// <param name="identity">The API key identity that was denied.</param>
|
||||
/// <param name="commandKind">The command type (e.g., read, write).</param>
|
||||
/// <param name="target">The target being accessed (tag address or handle).</param>
|
||||
/// <param name="failure">The constraint failure details.</param>
|
||||
/// <param name="cancellationToken">Token to observe for cancellation.</param>
|
||||
public async Task RecordDenialAsync(
|
||||
ApiKeyIdentity? identity,
|
||||
string commandKind,
|
||||
|
||||
@@ -5,11 +5,21 @@ namespace ZB.MOM.WW.MxGateway.Server.Security.Authorization;
|
||||
|
||||
public interface IConstraintEnforcer
|
||||
{
|
||||
/// <summary>Checks whether a read constraint is satisfied for a tag address.</summary>
|
||||
/// <param name="identity">The API key identity.</param>
|
||||
/// <param name="tagAddress">Tag address to check.</param>
|
||||
/// <param name="cancellationToken">Token to observe for cancellation.</param>
|
||||
Task<ConstraintFailure?> CheckReadTagAsync(
|
||||
ApiKeyIdentity? identity,
|
||||
string tagAddress,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Checks whether a read constraint is satisfied for an item handle.</summary>
|
||||
/// <param name="identity">The API key identity.</param>
|
||||
/// <param name="session">The gateway session.</param>
|
||||
/// <param name="serverHandle">The MXAccess server handle.</param>
|
||||
/// <param name="itemHandle">The MXAccess item handle.</param>
|
||||
/// <param name="cancellationToken">Token to observe for cancellation.</param>
|
||||
Task<ConstraintFailure?> CheckReadHandleAsync(
|
||||
ApiKeyIdentity? identity,
|
||||
GatewaySession session,
|
||||
@@ -17,6 +27,12 @@ public interface IConstraintEnforcer
|
||||
int itemHandle,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Checks whether a write constraint is satisfied for an item handle.</summary>
|
||||
/// <param name="identity">The API key identity.</param>
|
||||
/// <param name="session">The gateway session.</param>
|
||||
/// <param name="serverHandle">The MXAccess server handle.</param>
|
||||
/// <param name="itemHandle">The MXAccess item handle.</param>
|
||||
/// <param name="cancellationToken">Token to observe for cancellation.</param>
|
||||
Task<ConstraintFailure?> CheckWriteHandleAsync(
|
||||
ApiKeyIdentity? identity,
|
||||
GatewaySession session,
|
||||
@@ -24,6 +40,12 @@ public interface IConstraintEnforcer
|
||||
int itemHandle,
|
||||
CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Records a constraint denial for audit and metrics.</summary>
|
||||
/// <param name="identity">The API key identity.</param>
|
||||
/// <param name="commandKind">The kind of command denied.</param>
|
||||
/// <param name="target">The target of the denied command.</param>
|
||||
/// <param name="failure">The constraint failure details.</param>
|
||||
/// <param name="cancellationToken">Token to observe for cancellation.</param>
|
||||
Task RecordDenialAsync(
|
||||
ApiKeyIdentity? identity,
|
||||
string commandKind,
|
||||
|
||||
Reference in New Issue
Block a user