feat(auth.apikeys.sqlserver): package skeleton, options (schema default zbauth, validated) and connection factory

Claude-Session: https://claude.ai/code/session_013L3XdmVii9i5sY4FChU8pB
This commit is contained in:
Joseph Doherty
2026-09-02 14:08:22 -04:00
parent 3f11704d10
commit 2969805e4e
8 changed files with 201 additions and 0 deletions
@@ -0,0 +1,36 @@
namespace ZB.MOM.WW.Auth.ApiKeys.SqlServer;
/// <summary>
/// Options for the shared SQL Server API-key store (section supplied by the host, e.g.
/// <c>ScadaBridge:InboundApi:ApiKeyStore:SqlServer</c>).
/// </summary>
public sealed class SqlServerApiKeyOptions
{
/// <summary>
/// Full SQL Server connection string. Required. Never a <c>${secret:}</c> reference on hosts
/// whose secret store is itself SQL-backed.
/// </summary>
public string ConnectionString { get; set; } = string.Empty;
/// <summary>Schema that owns the three tables. Letters, digits and underscore only (it is interpolated into DDL).</summary>
public string Schema { get; set; } = "zbauth";
/// <summary>
/// Command timeout applied to every store operation. Defaults to 30 seconds — long enough for
/// a contended shared database, short enough that a hung server surfaces as an error rather
/// than stalling a resolve indefinitely.
/// </summary>
public TimeSpan CommandTimeout { get; set; } = TimeSpan.FromSeconds(30);
/// <summary>Fails fast on a blank connection string, an unsafe schema identifier, or a non-positive command timeout.</summary>
/// <exception cref="InvalidOperationException">The options are not usable.</exception>
public void Validate()
{
if (string.IsNullOrWhiteSpace(ConnectionString))
throw new InvalidOperationException("SQL Server API-key store requires a ConnectionString.");
if (string.IsNullOrEmpty(Schema) || !Schema.All(c => char.IsAsciiLetterOrDigit(c) || c == '_') || Schema.Length > 64)
throw new InvalidOperationException($"SQL Server API-key store schema name '{Schema}' is not a safe identifier.");
if (CommandTimeout <= TimeSpan.Zero)
throw new InvalidOperationException($"SQL Server API-key store CommandTimeout must be positive (was {CommandTimeout}).");
}
}