Show target certificate validity after PFX exchange.
Reuse the source PFX password for path probes and fall back to the loaded certificate expiry for successfully exchanged targets. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -47,6 +47,7 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
private LocalSetupSelection? _localSetupSelection;
|
private LocalSetupSelection? _localSetupSelection;
|
||||||
|
|
||||||
private CertificateInfo? _loadedCertificateInfo;
|
private CertificateInfo? _loadedCertificateInfo;
|
||||||
|
private string? _loadedCertificatePassword;
|
||||||
private IReadOnlyList<DeploymentTarget> _loadedTargets = [];
|
private IReadOnlyList<DeploymentTarget> _loadedTargets = [];
|
||||||
private bool _isOperationRunning;
|
private bool _isOperationRunning;
|
||||||
private CancellationTokenSource? _runCts;
|
private CancellationTokenSource? _runCts;
|
||||||
@@ -953,7 +954,9 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CertificateInfo? certificateInfo = TryReadSelectedCertificate(selectedPath);
|
CertificateInfo? certificateInfo = TryReadSelectedCertificate(
|
||||||
|
selectedPath,
|
||||||
|
out string? certificatePassword);
|
||||||
if (certificateInfo == null)
|
if (certificateInfo == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -961,15 +964,26 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
|
|
||||||
txtCertificatePath.Text = selectedPath;
|
txtCertificatePath.Text = selectedPath;
|
||||||
_loadedCertificateInfo = certificateInfo;
|
_loadedCertificateInfo = certificateInfo;
|
||||||
|
_loadedCertificatePassword = certificatePassword;
|
||||||
SetStatus($"Zertifikat ausgewählt: {Path.GetFileName(selectedPath)}", isError: false);
|
SetStatus($"Zertifikat ausgewählt: {Path.GetFileName(selectedPath)}", isError: false);
|
||||||
DisplayCertificateInfo(certificateInfo);
|
DisplayCertificateInfo(certificateInfo);
|
||||||
UpdateToNextStep(2);
|
UpdateToNextStep(2);
|
||||||
SetFileButtonState(fileLoaded: true);
|
SetFileButtonState(fileLoaded: true);
|
||||||
RefreshActionButtonStates();
|
RefreshActionButtonStates();
|
||||||
|
|
||||||
|
// Zielpfade mit Quell-Kennwort erneut prüfen, damit Ablauf/Gültigkeit sichtbar wird
|
||||||
|
if (_loadedTargets.Count > 0)
|
||||||
|
{
|
||||||
|
_ = ProbeTargetCertificatesAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CertificateInfo? TryReadSelectedCertificate(string selectedPath)
|
private CertificateInfo? TryReadSelectedCertificate(
|
||||||
|
string selectedPath,
|
||||||
|
out string? certificatePassword)
|
||||||
{
|
{
|
||||||
|
certificatePassword = null;
|
||||||
|
|
||||||
string extension = Path.GetExtension(selectedPath);
|
string extension = Path.GetExtension(selectedPath);
|
||||||
bool needsPassword =
|
bool needsPassword =
|
||||||
extension.Equals(".pfx", StringComparison.OrdinalIgnoreCase)
|
extension.Equals(".pfx", StringComparison.OrdinalIgnoreCase)
|
||||||
@@ -991,7 +1005,9 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return ReadCertificate(selectedPath, pfxPassword);
|
CertificateInfo info = ReadCertificate(selectedPath, pfxPassword);
|
||||||
|
certificatePassword = pfxPassword;
|
||||||
|
return info;
|
||||||
}
|
}
|
||||||
catch (CryptographicException)
|
catch (CryptographicException)
|
||||||
{
|
{
|
||||||
@@ -1019,6 +1035,7 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
{
|
{
|
||||||
txtCertificatePath.Text = string.Empty;
|
txtCertificatePath.Text = string.Empty;
|
||||||
_loadedCertificateInfo = null;
|
_loadedCertificateInfo = null;
|
||||||
|
_loadedCertificatePassword = null;
|
||||||
SetStatus("Keine Datei ausgewählt", isError: false);
|
SetStatus("Keine Datei ausgewählt", isError: false);
|
||||||
|
|
||||||
lblCertificateSubject.Text = "-";
|
lblCertificateSubject.Text = "-";
|
||||||
@@ -1671,9 +1688,14 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
return merged;
|
return merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task ProbeTargetCertificatesAsync()
|
private async Task ProbeTargetCertificatesAsync(
|
||||||
|
IReadOnlySet<int>? preferLoadedCertificateForTargetIds = null)
|
||||||
{
|
{
|
||||||
CertificateProbeService probe = new();
|
CertificateProbeService probe = new();
|
||||||
|
string? password = _loadedCertificatePassword;
|
||||||
|
Func<string?>? passwordPrompt = password is null
|
||||||
|
? null
|
||||||
|
: () => password;
|
||||||
|
|
||||||
foreach (DataGridViewRow row in dgvTargets.Rows)
|
foreach (DataGridViewRow row in dgvTargets.Rows)
|
||||||
{
|
{
|
||||||
@@ -1683,7 +1705,7 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
CertificateProbeResult result = await Task.Run(
|
CertificateProbeResult result = await Task.Run(
|
||||||
() => probe.Probe(target.FullTargetPath));
|
() => probe.Probe(target.FullTargetPath, passwordPrompt));
|
||||||
|
|
||||||
if (IsDisposed || !dgvTargets.Columns.Contains("Expiry"))
|
if (IsDisposed || !dgvTargets.Columns.Contains("Expiry"))
|
||||||
{
|
{
|
||||||
@@ -1692,13 +1714,20 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
|
|
||||||
if (result.Success && result.Certificate is not null)
|
if (result.Success && result.Certificate is not null)
|
||||||
{
|
{
|
||||||
string expiry = result.Certificate.ValidUntil
|
row.Cells["Expiry"].Value = FormatCertificateExpiryCell(
|
||||||
.ToLocalTime()
|
result.Certificate);
|
||||||
.ToString("dd.MM.yyyy");
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
row.Cells["Expiry"].Value = result.Certificate.IsCurrentlyValid
|
// Nach erfolgreichem Tausch: Quellzertifikat liegt am Ziel –
|
||||||
? $"gültig bis {expiry}"
|
// Gültigkeit auch zeigen, falls Probe am Kennwort scheitert.
|
||||||
: $"abgelaufen {expiry}";
|
if (preferLoadedCertificateForTargetIds is not null
|
||||||
|
&& preferLoadedCertificateForTargetIds.Contains(target.Id)
|
||||||
|
&& _loadedCertificateInfo is not null
|
||||||
|
&& result.FileExists)
|
||||||
|
{
|
||||||
|
row.Cells["Expiry"].Value = FormatCertificateExpiryCell(
|
||||||
|
_loadedCertificateInfo);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1714,6 +1743,17 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string FormatCertificateExpiryCell(CertificateInfo certificate)
|
||||||
|
{
|
||||||
|
string expiry = certificate.ValidUntil
|
||||||
|
.ToLocalTime()
|
||||||
|
.ToString("dd.MM.yyyy");
|
||||||
|
|
||||||
|
return certificate.IsCurrentlyValid
|
||||||
|
? $"gültig bis {expiry}"
|
||||||
|
: $"abgelaufen {expiry}";
|
||||||
|
}
|
||||||
|
|
||||||
private List<DeploymentTarget> GetSelectedTargets()
|
private List<DeploymentTarget> GetSelectedTargets()
|
||||||
{
|
{
|
||||||
List<DeploymentTarget> selected = [];
|
List<DeploymentTarget> selected = [];
|
||||||
@@ -2071,6 +2111,11 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
targetResult.StatusText);
|
targetResult.StatusText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HashSet<int> exchangedTargetIds = runResult.TargetResults
|
||||||
|
.Where(result => result.Success)
|
||||||
|
.Select(result => result.TargetId)
|
||||||
|
.ToHashSet();
|
||||||
|
|
||||||
if (runResult.OverallSuccess)
|
if (runResult.OverallSuccess)
|
||||||
{
|
{
|
||||||
SetStatus(
|
SetStatus(
|
||||||
@@ -2078,7 +2123,7 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
isError: false);
|
isError: false);
|
||||||
|
|
||||||
UpdateToNextStep(4);
|
UpdateToNextStep(4);
|
||||||
await ProbeTargetCertificatesAsync();
|
await ProbeTargetCertificatesAsync(exchangedTargetIds);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2100,7 +2145,7 @@ namespace ZA.CoreService.ESBCertificateManager
|
|||||||
"Austausch fehlgeschlagen",
|
"Austausch fehlgeschlagen",
|
||||||
details);
|
details);
|
||||||
|
|
||||||
await ProbeTargetCertificatesAsync();
|
await ProbeTargetCertificatesAsync(exchangedTargetIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
|
|||||||
Reference in New Issue
Block a user