fix(secrets-cli): doctor flow — contained old-key errors, corrupt-row + rewrap-failure coverage
This commit is contained in:
@@ -106,11 +106,31 @@ public sealed class KekDoctorFlow : IInteractiveFlow
|
||||
private static async Task RunRewrapAsync(
|
||||
IAnsiConsole console, SecretsSession session, KekDoctor doctor, KekDoctorReport report, CancellationToken ct)
|
||||
{
|
||||
IMasterKeyProvider oldKek = PromptForOldKek(console);
|
||||
// Acquire the old KEK and resolve its id under their OWN guard: a malformed pasted key throws
|
||||
// ArgumentException from LiteralMasterKeyProvider, and an env/file source lazily throws
|
||||
// MasterKeyUnavailableException the moment KekId is read (an unset var, a missing file). Both must
|
||||
// render a friendly line and return here — not escape to the shell — so the closing re-diagnosis
|
||||
// in RunAsync still runs. This is distinct from the rewrap guard below (a wrong key vs a valid one).
|
||||
IMasterKeyProvider oldKek;
|
||||
string oldKekId;
|
||||
try
|
||||
{
|
||||
oldKek = PromptForOldKek(console);
|
||||
oldKekId = oldKek.KekId;
|
||||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
console.MarkupLineInterpolated($"[red]Invalid old KEK:[/] {ex.Message}");
|
||||
return;
|
||||
}
|
||||
catch (MasterKeyUnavailableException ex)
|
||||
{
|
||||
console.MarkupLineInterpolated($"[red]Old KEK unavailable:[/] {ex.Message}");
|
||||
return;
|
||||
}
|
||||
|
||||
// Prompt and confirm OUTSIDE the guard: only the rewrap call itself is caught, so a stray
|
||||
// Confirm OUTSIDE the rewrap guard: only the rewrap call itself is caught there, so a stray
|
||||
// ArgumentException from setup/prompt code is never mis-reported as a "rewrap failed" message.
|
||||
string oldKekId = oldKek.KekId;
|
||||
int moving = report.Rows.Count(r => string.Equals(r.RowKekId, oldKekId, StringComparison.Ordinal));
|
||||
|
||||
string confirmText =
|
||||
@@ -222,7 +242,9 @@ public sealed class KekDoctorFlow : IInteractiveFlow
|
||||
SecretContentType contentType = console.Prompt(
|
||||
new SelectionPrompt<SecretContentType>().Title(" Content type").AddChoices(Enum.GetValues<SecretContentType>()));
|
||||
|
||||
StoredSecret row = session.Cipher!.Encrypt(name, value, contentType) with
|
||||
ISecretCipher cipher = session.Cipher
|
||||
?? throw new InvalidOperationException("flow requires an unlocked KEK session");
|
||||
StoredSecret row = cipher.Encrypt(name, value, contentType) with
|
||||
{
|
||||
CreatedBy = FlowPrompts.Actor,
|
||||
UpdatedBy = FlowPrompts.Actor,
|
||||
|
||||
Reference in New Issue
Block a user