fix(secrets-cli): audit flow — cipher guard, shared actor helper, summary + branch coverage
This commit is contained in:
@@ -35,6 +35,9 @@ public sealed class ReferenceAuditFlow : IInteractiveFlow
|
||||
ArgumentNullException.ThrowIfNull(console);
|
||||
ArgumentNullException.ThrowIfNull(session);
|
||||
|
||||
ISecretCipher cipher = session.Cipher
|
||||
?? throw new InvalidOperationException("flow requires an unlocked KEK session");
|
||||
|
||||
var auditor = new ReferenceAuditor();
|
||||
IReadOnlyList<ReferenceFinding> findings = await auditor.AuditAsync(session, ct).ConfigureAwait(false);
|
||||
if (findings.Count == 0)
|
||||
@@ -72,7 +75,7 @@ public sealed class ReferenceAuditFlow : IInteractiveFlow
|
||||
continue;
|
||||
}
|
||||
|
||||
await SeedAsync(console, session, new SecretName(finding.SecretName), ct).ConfigureAwait(false);
|
||||
await SeedAsync(console, session, cipher, new SecretName(finding.SecretName), ct).ConfigureAwait(false);
|
||||
console.MarkupLineInterpolated($"[green]Sealed '{finding.SecretName}'.[/]");
|
||||
}
|
||||
|
||||
@@ -88,7 +91,7 @@ public sealed class ReferenceAuditFlow : IInteractiveFlow
|
||||
// Prompts for a masked value + content type + optional description and seals the secret under a fresh
|
||||
// per-secret DEK. Mirrors SetSecretFlow's seal-and-stamp shape without coupling to it.
|
||||
private static async Task SeedAsync(
|
||||
IAnsiConsole console, SecretsSession session, SecretName name, CancellationToken ct)
|
||||
IAnsiConsole console, SecretsSession session, ISecretCipher cipher, SecretName name, CancellationToken ct)
|
||||
{
|
||||
string value = console.Prompt(
|
||||
new TextPrompt<string>($" Value for [green]{Markup.Escape(name.Value)}[/]:").Secret());
|
||||
@@ -97,12 +100,11 @@ public sealed class ReferenceAuditFlow : IInteractiveFlow
|
||||
string description = console.Prompt(
|
||||
new TextPrompt<string>(" Description [grey](optional)[/]:").AllowEmpty());
|
||||
|
||||
string actor = string.IsNullOrWhiteSpace(Environment.UserName) ? "cli" : Environment.UserName;
|
||||
StoredSecret row = session.Cipher!.Encrypt(name, value, contentType) with
|
||||
StoredSecret row = cipher.Encrypt(name, value, contentType) with
|
||||
{
|
||||
Description = string.IsNullOrWhiteSpace(description) ? null : description,
|
||||
CreatedBy = actor,
|
||||
UpdatedBy = actor,
|
||||
CreatedBy = FlowPrompts.Actor,
|
||||
UpdatedBy = FlowPrompts.Actor,
|
||||
};
|
||||
await session.Store.UpsertAsync(row, ct).ConfigureAwait(false); // revives a tombstone: overwrite clears IsDeleted.
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user