feat(auth.apikeys.sqlserver): zbauth schema v1 + concurrent-boot-safe migrator (retry on 1205/2714/1913/2627, newer-version fail-closed); live tests gated on AUTH_SQLSERVER_CONNSTR
Claude-Session: https://claude.ai/code/session_013L3XdmVii9i5sY4FChU8pB
This commit is contained in:
@@ -28,9 +28,38 @@ public sealed class SqlServerApiKeyOptions
|
||||
{
|
||||
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.");
|
||||
|
||||
ValidateIdentifier(Schema);
|
||||
|
||||
if (CommandTimeout <= TimeSpan.Zero)
|
||||
throw new InvalidOperationException($"SQL Server API-key store CommandTimeout must be positive (was {CommandTimeout}).");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strict allow-list for a SQL identifier that will be interpolated into DDL or query text.
|
||||
/// Rejects everything that is not <c>[A-Za-z_][A-Za-z0-9_]{0,63}</c> — no brackets, quotes, dots
|
||||
/// or spaces — so no bracket-escape (<c>]]</c>) trick can break out of the quoting applied at the
|
||||
/// use site. Uses the ASCII-only character tests deliberately, so homoglyph and full-width
|
||||
/// look-alikes are rejected rather than accepted as "letters".
|
||||
/// </summary>
|
||||
/// <param name="schemaName">The candidate identifier.</param>
|
||||
/// <returns>The same value, once validated.</returns>
|
||||
/// <exception cref="InvalidOperationException">The value is not a plain identifier.</exception>
|
||||
/// <remarks>
|
||||
/// Public because <see cref="SqlServerAuthSchema.CreateSchemaDdl(string)"/> is public and must
|
||||
/// defend itself rather than trust that every caller routed through <see cref="Validate"/>.
|
||||
/// </remarks>
|
||||
public static string ValidateIdentifier(string schemaName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(schemaName)
|
||||
|| schemaName.Length > 64
|
||||
|| (!char.IsAsciiLetter(schemaName[0]) && schemaName[0] != '_')
|
||||
|| !schemaName.All(c => char.IsAsciiLetterOrDigit(c) || c == '_'))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"SQL Server API-key store schema name '{schemaName}' is not a safe identifier.");
|
||||
}
|
||||
|
||||
return schemaName;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user