Improve certificate path probing with demo UNC target and remove Sonic container scan.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,16 +1,22 @@
|
||||
using ZA.CoreService.ESBCertificateManager.Models;
|
||||
using ZA.CoreService.ESBCertificateManager.Services;
|
||||
|
||||
namespace ZA.CoreService.ESBCertificateManager.Setup;
|
||||
|
||||
public sealed class AddTargetPathForm : Form
|
||||
{
|
||||
private readonly SetupCoordinator _coordinator;
|
||||
private readonly CertificateProbeService _probeService = new();
|
||||
|
||||
private readonly ComboBox _cmbContainer;
|
||||
private readonly TextBox _txtDirectory;
|
||||
private readonly TextBox _txtFileName;
|
||||
private readonly TextBox _txtFullPath;
|
||||
private readonly TextBox _txtBackupFolder;
|
||||
private readonly CheckBox _chkBackup;
|
||||
private readonly Label _lblProbeResult;
|
||||
private readonly Button _btnProbe;
|
||||
private readonly Button _btnSave;
|
||||
|
||||
private CertificateProbeResult? _lastProbe;
|
||||
private bool _running;
|
||||
|
||||
public int? CreatedCertificateTargetId { get; private set; }
|
||||
@@ -27,15 +33,15 @@ public sealed class AddTargetPathForm : Form
|
||||
MaximizeBox = false;
|
||||
MinimizeBox = false;
|
||||
ShowInTaskbar = false;
|
||||
ClientSize = new Size(560, 450);
|
||||
ClientSize = new Size(640, 560);
|
||||
BackColor = SettingsUi.Background;
|
||||
ForeColor = SettingsUi.Text;
|
||||
Font = new Font("Segoe UI", 10f);
|
||||
|
||||
Label title = new()
|
||||
{
|
||||
Text = "Neuer Zertifikat-Pfad",
|
||||
Location = new Point(28, 22),
|
||||
Text = "Zertifikat-Datei-Pfad",
|
||||
Location = new Point(28, 18),
|
||||
AutoSize = true,
|
||||
Font = new Font("Segoe UI Semibold", 18f, FontStyle.Bold),
|
||||
ForeColor = SettingsUi.Text
|
||||
@@ -44,23 +50,45 @@ public sealed class AddTargetPathForm : Form
|
||||
Label subtitle = new()
|
||||
{
|
||||
Text =
|
||||
"Zielverzeichnis und Dateiname für die Zertifikatsablage.",
|
||||
Location = new Point(30, 58),
|
||||
"UNC- oder lokaler Dateipfad zur .cer/.crt/.pem/.pfx/.p12-Datei. "
|
||||
+ "Der Container ist nur das Neustart-Ziel.",
|
||||
Location = new Point(30, 54),
|
||||
MaximumSize = new Size(580, 40),
|
||||
AutoSize = true,
|
||||
ForeColor = SettingsUi.Muted
|
||||
};
|
||||
|
||||
Panel card = SettingsUi.CreateCard();
|
||||
card.Location = new Point(28, 95);
|
||||
card.Size = new Size(504, 270);
|
||||
card.Location = new Point(28, 100);
|
||||
card.Size = new Size(584, 360);
|
||||
card.Paint += SettingsUi.PaintCardBorder;
|
||||
|
||||
_txtFullPath = SettingsUi.CreateTextBox();
|
||||
_txtFullPath.Text = DemoCertificatePath.FullPath;
|
||||
_txtFullPath.PlaceholderText = DemoCertificatePath.FullPath;
|
||||
|
||||
Button browse = SettingsUi.CreateGhostButton("…");
|
||||
browse.Size = new Size(40, 32);
|
||||
browse.Click += (_, _) => BrowseForFile();
|
||||
|
||||
_btnProbe = SettingsUi.CreateGhostButton("Prüfen");
|
||||
_btnProbe.Size = new Size(100, 32);
|
||||
_btnProbe.Click += (_, _) => RunProbe();
|
||||
|
||||
_lblProbeResult = new Label
|
||||
{
|
||||
AutoSize = false,
|
||||
Size = new Size(548, 52),
|
||||
ForeColor = SettingsUi.Muted,
|
||||
Font = new Font("Segoe UI", 9f),
|
||||
Text =
|
||||
"Noch nicht geprüft. Bitte Pfad prüfen – bei vorhandener "
|
||||
+ "Datei wird der Ablauf angezeigt."
|
||||
};
|
||||
|
||||
_cmbContainer = SettingsUi.CreateComboBox();
|
||||
_txtDirectory = SettingsUi.CreateTextBox();
|
||||
_txtFileName = SettingsUi.CreateTextBox();
|
||||
_txtBackupFolder = SettingsUi.CreateTextBox();
|
||||
_txtBackupFolder.Text = "Backup";
|
||||
_txtFileName.Text = "server.crt";
|
||||
|
||||
_chkBackup = new CheckBox
|
||||
{
|
||||
@@ -71,21 +99,54 @@ public sealed class AddTargetPathForm : Form
|
||||
Font = new Font("Segoe UI", 9.5f)
|
||||
};
|
||||
|
||||
AddField(card, "Container", _cmbContainer, 18, 18, 460);
|
||||
AddField(card, "Zielverzeichnis", _txtDirectory, 18, 78, 460);
|
||||
AddField(card, "Dateiname", _txtFileName, 18, 138, 220);
|
||||
AddField(card, "Backup-Ordner", _txtBackupFolder, 258, 138, 220);
|
||||
Label pathLabel = SettingsUi.CreateFieldLabel(
|
||||
"Vollständiger Pfad zur Zertifikatsdatei");
|
||||
pathLabel.Location = new Point(18, 16);
|
||||
_txtFullPath.Location = new Point(18, 38);
|
||||
_txtFullPath.Width = 370;
|
||||
browse.Location = new Point(394, 38);
|
||||
_btnProbe.Location = new Point(440, 38);
|
||||
|
||||
_chkBackup.Location = new Point(18, 210);
|
||||
_lblProbeResult.Location = new Point(18, 78);
|
||||
|
||||
Label containerLabel = SettingsUi.CreateFieldLabel(
|
||||
"Neustart-Ziel (Sonic-Container) – nicht der Dateipfad");
|
||||
containerLabel.Location = new Point(18, 140);
|
||||
_cmbContainer.Location = new Point(18, 162);
|
||||
_cmbContainer.Width = 548;
|
||||
|
||||
Label hint = new()
|
||||
{
|
||||
Text =
|
||||
"Nach dem Austausch wird dieser Container über MfApi "
|
||||
+ "neu gestartet. Der Pfad oben ist unabhängig davon.",
|
||||
Location = new Point(18, 202),
|
||||
MaximumSize = new Size(548, 36),
|
||||
AutoSize = true,
|
||||
ForeColor = SettingsUi.Muted,
|
||||
Font = new Font("Segoe UI", 8.5f)
|
||||
};
|
||||
|
||||
AddField(card, "Backup-Ordner", _txtBackupFolder, 18, 250, 220);
|
||||
_chkBackup.Location = new Point(258, 272);
|
||||
card.Controls.Add(_chkBackup);
|
||||
|
||||
card.Controls.Add(pathLabel);
|
||||
card.Controls.Add(_txtFullPath);
|
||||
card.Controls.Add(browse);
|
||||
card.Controls.Add(_btnProbe);
|
||||
card.Controls.Add(_lblProbeResult);
|
||||
card.Controls.Add(containerLabel);
|
||||
card.Controls.Add(_cmbContainer);
|
||||
card.Controls.Add(hint);
|
||||
|
||||
_btnSave = SettingsUi.CreatePrimaryButton("Pfad anlegen");
|
||||
_btnSave.Location = new Point(312, 385);
|
||||
_btnSave.Location = new Point(392, 490);
|
||||
_btnSave.Size = new Size(220, 40);
|
||||
_btnSave.Click += async (_, _) => await SaveAsync();
|
||||
|
||||
Button cancel = SettingsUi.CreateGhostButton("Abbrechen");
|
||||
cancel.Location = new Point(190, 385);
|
||||
cancel.Location = new Point(270, 490);
|
||||
cancel.Size = new Size(110, 40);
|
||||
cancel.Click += (_, _) =>
|
||||
{
|
||||
@@ -103,6 +164,64 @@ public sealed class AddTargetPathForm : Form
|
||||
await LoadContainersAsync(preferredSonicContainerId);
|
||||
}
|
||||
|
||||
private void BrowseForFile()
|
||||
{
|
||||
using OpenFileDialog dialog = new()
|
||||
{
|
||||
Title = "Vorhandene Zertifikatsdatei wählen",
|
||||
Filter =
|
||||
"Zertifikate (*.cer;*.crt;*.pem;*.pfx;*.p12)|"
|
||||
+ "*.cer;*.crt;*.pem;*.pfx;*.p12|"
|
||||
+ "Alle Dateien (*.*)|*.*",
|
||||
CheckFileExists = false,
|
||||
Multiselect = false
|
||||
};
|
||||
|
||||
if (dialog.ShowDialog(this) != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_txtFullPath.Text = dialog.FileName;
|
||||
RunProbe();
|
||||
}
|
||||
|
||||
private void RunProbe()
|
||||
{
|
||||
_lastProbe = _probeService.Probe(
|
||||
_txtFullPath.Text,
|
||||
() => PromptForPassword(this));
|
||||
|
||||
if (!_lastProbe.Success)
|
||||
{
|
||||
_lblProbeResult.ForeColor = Color.FromArgb(220, 100, 100);
|
||||
_lblProbeResult.Text = _lastProbe.Message;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_lastProbe.FileExists)
|
||||
{
|
||||
_lblProbeResult.ForeColor = Color.FromArgb(230, 180, 80);
|
||||
_lblProbeResult.Text =
|
||||
_lastProbe.Message
|
||||
+ " Pfad kann trotzdem gespeichert werden "
|
||||
+ "(erstes Deployment).";
|
||||
return;
|
||||
}
|
||||
|
||||
CertificateInfo cert = _lastProbe.Certificate!;
|
||||
string expiry = cert.ValidUntil.ToLocalTime()
|
||||
.ToString("dd.MM.yyyy HH:mm");
|
||||
|
||||
_lblProbeResult.ForeColor = cert.IsCurrentlyValid
|
||||
? Color.FromArgb(90, 200, 140)
|
||||
: Color.FromArgb(220, 100, 100);
|
||||
|
||||
_lblProbeResult.Text =
|
||||
$"Datei vorhanden · Subject: {cert.Subject}\n"
|
||||
+ $"Ablauf: {expiry} · Fingerprint: {cert.FingerprintSha256}";
|
||||
}
|
||||
|
||||
private async Task LoadContainersAsync(int? preferredSonicContainerId)
|
||||
{
|
||||
try
|
||||
@@ -151,13 +270,59 @@ public sealed class AddTargetPathForm : Form
|
||||
{
|
||||
MessageBox.Show(
|
||||
this,
|
||||
"Bitte einen Container wählen.",
|
||||
"Bitte ein Neustart-Ziel (Sonic-Container) wählen.",
|
||||
"Zertifikat-Pfad",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CertificateProbeService.TrySplitTargetPath(
|
||||
_txtFullPath.Text,
|
||||
out string directory,
|
||||
out string fileName,
|
||||
out string? splitError))
|
||||
{
|
||||
MessageBox.Show(
|
||||
this,
|
||||
splitError ?? "Ungültiger Pfad.",
|
||||
"Zertifikat-Pfad",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Vor dem Speichern immer prüfen
|
||||
RunProbe();
|
||||
|
||||
if (_lastProbe is null || !_lastProbe.Success)
|
||||
{
|
||||
MessageBox.Show(
|
||||
this,
|
||||
_lastProbe?.Message
|
||||
?? "Pfad konnte nicht geprüft werden.",
|
||||
"Zertifikat-Pfad",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_lastProbe.FileExists)
|
||||
{
|
||||
DialogResult confirm = MessageBox.Show(
|
||||
this,
|
||||
"Am Ziel liegt noch keine Zertifikatsdatei.\n\n"
|
||||
+ "Pfad trotzdem speichern?",
|
||||
"Datei fehlt",
|
||||
MessageBoxButtons.YesNo,
|
||||
MessageBoxIcon.Question);
|
||||
|
||||
if (confirm != DialogResult.Yes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_running = true;
|
||||
_btnSave.Enabled = false;
|
||||
Cursor = Cursors.WaitCursor;
|
||||
@@ -167,8 +332,8 @@ public sealed class AddTargetPathForm : Form
|
||||
CreatedCertificateTargetId =
|
||||
await _coordinator.AddCertificateTargetAsync(
|
||||
container.SonicContainerId,
|
||||
_txtDirectory.Text,
|
||||
_txtFileName.Text,
|
||||
directory,
|
||||
fileName,
|
||||
_chkBackup.Checked,
|
||||
_txtBackupFolder.Text);
|
||||
|
||||
@@ -192,6 +357,57 @@ public sealed class AddTargetPathForm : Form
|
||||
}
|
||||
}
|
||||
|
||||
private static string? PromptForPassword(IWin32Window owner)
|
||||
{
|
||||
using Form dialog = new()
|
||||
{
|
||||
Text = "PFX/P12-Kennwort",
|
||||
FormBorderStyle = FormBorderStyle.FixedDialog,
|
||||
StartPosition = FormStartPosition.CenterParent,
|
||||
ClientSize = new Size(360, 140),
|
||||
MaximizeBox = false,
|
||||
MinimizeBox = false,
|
||||
ShowInTaskbar = false,
|
||||
BackColor = SettingsUi.Background,
|
||||
ForeColor = SettingsUi.Text
|
||||
};
|
||||
|
||||
Label label = new()
|
||||
{
|
||||
Text = "Kennwort für die Zertifikatsdatei:",
|
||||
Location = new Point(16, 16),
|
||||
AutoSize = true
|
||||
};
|
||||
|
||||
TextBox txtPwd = new()
|
||||
{
|
||||
Location = new Point(16, 44),
|
||||
Width = 320,
|
||||
UseSystemPasswordChar = true
|
||||
};
|
||||
|
||||
Button btnOk = SettingsUi.CreatePrimaryButton("OK");
|
||||
btnOk.Location = new Point(196, 90);
|
||||
btnOk.Size = new Size(140, 32);
|
||||
btnOk.DialogResult = DialogResult.OK;
|
||||
|
||||
Button btnCancel = SettingsUi.CreateGhostButton("Abbrechen");
|
||||
btnCancel.Location = new Point(100, 90);
|
||||
btnCancel.Size = new Size(90, 32);
|
||||
btnCancel.DialogResult = DialogResult.Cancel;
|
||||
|
||||
dialog.Controls.Add(label);
|
||||
dialog.Controls.Add(txtPwd);
|
||||
dialog.Controls.Add(btnOk);
|
||||
dialog.Controls.Add(btnCancel);
|
||||
dialog.AcceptButton = btnOk;
|
||||
dialog.CancelButton = btnCancel;
|
||||
|
||||
return dialog.ShowDialog(owner) == DialogResult.OK
|
||||
? txtPwd.Text
|
||||
: null;
|
||||
}
|
||||
|
||||
private static void AddField(
|
||||
Control parent,
|
||||
string label,
|
||||
|
||||
Reference in New Issue
Block a user