1424a21419
Add a secret:NAME arm to GalaxySecretRef.ResolveApiKey that resolves the Galaxy gateway API key through the shared ISecretResolver — fail-closed if the secret is absent (never falls through to the cleartext literal arm), retiring the dev:/literal in-DB path for production. Because GetAsync is async the method becomes ResolveApiKeyAsync; the await cascade threads ISecretResolver by ctor injection into GalaxyDriver + GalaxyDriverBrowser and (since GalaxyDriver is built by a static factory closure, not DI) through GalaxyDriverFactoryExtensions + DriverFactoryBootstrap (which pulls the real resolver from the service provider — registered unconditionally in Slice 1). A NullSecretResolver null-object backs the parse-only/test paths only; the runtime path always gets the real resolver (verified end-to-end). TDD: 3 new secret:-arm tests (resolve / fail-closed-on-absent / no-literal-warning) RED without the arm, GREEN with it; 338 Galaxy tests pass; no sync-over-async.
27 lines
1.1 KiB
C#
27 lines
1.1 KiB
C#
using ZB.MOM.WW.Secrets.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy;
|
|
|
|
/// <summary>
|
|
/// A null-object <see cref="ISecretResolver"/> that resolves every name to <c>null</c>
|
|
/// (absent). Used as the default for the internal test ctor and the parse-only
|
|
/// <c>CreateInstance</c> path so callers that never exercise a <c>secret:</c> API-key
|
|
/// ref need not thread a real resolver. A production <c>GalaxyDriver</c> always receives
|
|
/// the DI-registered resolver via the factory; a <c>secret:</c> ref resolved against this
|
|
/// null object throws fail-closed (the secret is reported absent), which is the correct
|
|
/// behaviour for a mis-wired deployment.
|
|
/// </summary>
|
|
internal sealed class NullSecretResolver : ISecretResolver
|
|
{
|
|
/// <summary>The shared singleton instance.</summary>
|
|
public static readonly NullSecretResolver Instance = new();
|
|
|
|
private NullSecretResolver()
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public Task<string?> GetAsync(SecretName name, CancellationToken ct) =>
|
|
Task.FromResult<string?>(null);
|
|
}
|