Files
123123/ZA.CoreService.ESBCertificateManager/Setup/SetupWizardForm.cs
T

822 lines
21 KiB
C#

using ZA.CoreService.ESBCertificateManager.Models;
namespace ZA.CoreService.ESBCertificateManager.Setup;
public sealed class SetupWizardForm : Form
{
private readonly SetupCoordinator _coordinator;
private readonly bool _isSettingsMode;
private readonly Color _backgroundColor =
Color.FromArgb(10, 18, 34);
private readonly Color _cardColor =
Color.FromArgb(16, 38, 65);
private readonly Color _textColor =
Color.FromArgb(241, 245, 249);
private readonly Color _mutedTextColor =
Color.FromArgb(169, 184, 200);
private readonly Color _goldColor =
Color.FromArgb(208, 171, 57);
private readonly Color _greenColor =
Color.FromArgb(60, 203, 127);
private readonly Color _redColor =
Color.FromArgb(239, 106, 106);
private Label _lblRuntime = null!;
private Label _lblCertificate = null!;
private Label _lblDatabase = null!;
private Label _lblSelection = null!;
private Label _lblEnvironment = null!;
private Label _lblSystemDetails = null!;
private ComboBox _cmbSystem = null!;
private ComboBox _cmbCredential = null!;
private Button _btnImportCertificate = null!;
private Button _btnRefresh = null!;
private Button _btnSaveSelection = null!;
private Button _btnFinish = null!;
private Button _btnAddCredential = null!;
private IReadOnlyList<SonicSystemOption> _systems = [];
private IReadOnlyList<SonicCredentialProfile> _profiles = [];
private bool _running;
public SetupWizardForm(
SetupCoordinator coordinator,
bool isSettingsMode = false)
{
_coordinator = coordinator;
_isSettingsMode = isSettingsMode;
BuildInterface();
Shown += async (_, _) =>
await InitializeAsync();
}
private void BuildInterface()
{
Text = "Einstellungen";
StartPosition = FormStartPosition.CenterScreen;
Size = new Size(950, 690);
MinimumSize = new Size(900, 650);
MaximizeBox = false;
BackColor = _backgroundColor;
ForeColor = _textColor;
Font = new Font("Segoe UI", 10);
Label title = new()
{
Text = "Einstellungen",
AutoSize = true,
Location = new Point(38, 25),
ForeColor = _textColor,
Font = new Font(
"Segoe UI",
24,
FontStyle.Bold)
};
Label subtitle = new()
{
Text = _isSettingsMode
? "Runtime, Zertifikat, System und Benutzerprofil anpassen."
: "Runtime, Datenbank, Zertifikat und Systemauswahl prüfen.",
AutoSize = true,
Location = new Point(42, 70),
ForeColor = _mutedTextColor
};
Panel checkCard = CreateCard(
new Point(38, 105),
new Size(870, 225));
Label checkTitle = CreateTitle(
"Systemprüfung",
new Point(20, 16));
_lblRuntime = CreateStatus(
new Point(20, 55));
_lblCertificate = CreateStatus(
new Point(20, 95));
_lblDatabase = CreateStatus(
new Point(20, 135));
_lblSelection = CreateStatus(
new Point(20, 175));
_btnImportCertificate = CreateButton(
"PFX importieren");
_btnImportCertificate.Location =
new Point(680, 90);
_btnImportCertificate.Size =
new Size(160, 38);
_btnImportCertificate.Click +=
async (_, _) =>
await ImportCertificateAsync();
_cmbCredential = new ComboBox
{
Location = new Point(185, 133),
Size = new Size(300, 30),
DropDownStyle =
ComboBoxStyle.DropDownList
};
checkCard.Controls.Add(checkTitle);
checkCard.Controls.Add(_lblRuntime);
checkCard.Controls.Add(_lblCertificate);
checkCard.Controls.Add(_lblDatabase);
checkCard.Controls.Add(_lblSelection);
checkCard.Controls.Add(_btnImportCertificate);
Panel selectionCard = CreateCard(
new Point(38, 350),
new Size(870, 205));
Label selectionTitle = CreateTitle(
"System auswählen",
new Point(20, 16));
_lblEnvironment = new Label
{
Text =
$"Umgebung: {_coordinator.Settings.EnvironmentCode}",
AutoSize = true,
Location = new Point(22, 55),
ForeColor = _goldColor,
Font = new Font(
"Segoe UI",
10,
FontStyle.Bold)
};
Label systemLabel = CreateLabel(
"Sonic-System",
new Point(22, 92));
_cmbSystem = new ComboBox
{
Location = new Point(185, 88),
Size = new Size(300, 30),
DropDownStyle =
ComboBoxStyle.DropDownList
};
_cmbSystem.SelectedIndexChanged +=
async (_, _) =>
await SystemChangedAsync();
Label credentialLabel = CreateLabel(
"Benutzerprofil",
new Point(22, 137));
_cmbCredential = new ComboBox
{
Location = new Point(185, 133),
Size = new Size(300, 30),
DropDownStyle =
ComboBoxStyle.DropDownList
};
_lblSystemDetails = new Label
{
Location = new Point(515, 88),
Size = new Size(325, 72),
ForeColor = _mutedTextColor
};
_btnSaveSelection = CreateButton(
"Auswahl übernehmen");
_btnSaveSelection.Location =
new Point(640, 153);
_btnSaveSelection.Size =
new Size(200, 38);
_btnSaveSelection.Click +=
async (_, _) =>
await SaveSelectionAsync();
_btnAddCredential = CreateButton(
"Profil hinzufügen");
_btnAddCredential.Location =
new Point(495, 132);
_btnAddCredential.Size =
new Size(140, 32);
_btnAddCredential.Click +=
async (_, _) =>
await AddCredentialAsync();
selectionCard.Controls.Add(selectionTitle);
selectionCard.Controls.Add(_lblEnvironment);
selectionCard.Controls.Add(systemLabel);
selectionCard.Controls.Add(_cmbSystem);
selectionCard.Controls.Add(credentialLabel);
selectionCard.Controls.Add(credentialLabel);
selectionCard.Controls.Add(_cmbCredential);
selectionCard.Controls.Add(_btnAddCredential);
selectionCard.Controls.Add(_lblSystemDetails);
selectionCard.Controls.Add(_btnSaveSelection);
_btnRefresh = CreateButton(
"Erneut prüfen");
_btnRefresh.Location =
new Point(525, 580);
_btnRefresh.Size =
new Size(140, 42);
_btnRefresh.Click +=
async (_, _) =>
await InitializeAsync();
Button cancelButton = CreateButton(
_isSettingsMode ? "Schließen" : "Abbrechen");
cancelButton.Location =
new Point(675, 580);
cancelButton.Size =
new Size(110, 42);
cancelButton.Click += async (_, _) =>
{
if (_isSettingsMode)
{
// Nach gespeicherter Auswahl die Hauptansicht aktualisieren.
SetupCheckResult check =
await _coordinator.CheckAsync();
DialogResult = check.IsReady
? DialogResult.OK
: DialogResult.Cancel;
}
else
{
DialogResult = DialogResult.Cancel;
}
Close();
};
_btnFinish = CreateButton(
_isSettingsMode
? "Übernehmen"
: "Fertig");
_btnFinish.Location =
new Point(795, 580);
_btnFinish.Size =
new Size(140, 42);
_btnFinish.Enabled = false;
_btnFinish.Click += (_, _) =>
{
DialogResult = DialogResult.OK;
Close();
};
Controls.Add(title);
Controls.Add(subtitle);
Controls.Add(checkCard);
Controls.Add(selectionCard);
Controls.Add(_btnRefresh);
Controls.Add(cancelButton);
Controls.Add(_btnFinish);
}
private async Task InitializeAsync()
{
if (_running)
{
return;
}
SetRunning(true);
try
{
SetupCheckResult result =
await _coordinator.CheckAsync();
SetStatus(
_lblRuntime,
"Runtime",
result.RuntimeReady,
result.RuntimeMessage);
SetStatus(
_lblCertificate,
"Always Encrypted",
result.CertificateReady,
result.CertificateMessage);
SetStatus(
_lblDatabase,
"Datenbank",
result.DatabaseReady,
result.DatabaseMessage);
SetStatus(
_lblSelection,
"Auswahl",
result.CredentialsReady,
result.CredentialsMessage);
_btnImportCertificate.Visible =
!result.CertificateReady;
_btnFinish.Enabled =
result.IsReady;
if (result.CertificateReady)
{
await LoadSystemsAsync();
}
}
catch (Exception ex)
{
MessageBox.Show(
this,
ex.Message,
"Einstellungen fehlgeschlagen",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
SetRunning(false);
}
}
private async Task LoadSystemsAsync()
{
LocalSetupSelection? previousSelection =
_coordinator.LoadSelection();
_systems =
await _coordinator.LoadSystemsAsync();
_cmbSystem.Items.Clear();
_cmbCredential.Items.Clear();
foreach (SonicSystemOption system in _systems)
{
_cmbSystem.Items.Add(system);
}
if (_systems.Count == 0)
{
_lblSystemDetails.Text =
"Kein System für die gewählte Umgebung gefunden.";
return;
}
int selectedIndex = 0;
if (previousSelection is not null)
{
for (int index = 0;
index < _systems.Count;
index++)
{
if (_systems[index].SonicConnectionId ==
previousSelection.SonicConnectionId)
{
selectedIndex = index;
break;
}
}
}
_cmbSystem.SelectedIndex = selectedIndex;
}
private async Task AddCredentialAsync()
{
if (_running)
{
return;
}
if (_cmbSystem.SelectedItem
is not SonicSystemOption system)
{
ShowWarning(
"Bitte zuerst ein Sonic-System auswählen.");
return;
}
using AddCredentialProfileForm dialog =
new(
_coordinator,
system);
DialogResult dialogResult =
dialog.ShowDialog(this);
if (dialogResult != DialogResult.OK
|| dialog.CreatedProfile is null)
{
return;
}
SetRunning(true);
try
{
_profiles =
await _coordinator.LoadCredentialsAsync(
system.SonicConnectionId);
_cmbCredential.Items.Clear();
foreach (SonicCredentialProfile profile
in _profiles)
{
_cmbCredential.Items.Add(profile);
}
for (int index = 0;
index < _cmbCredential.Items.Count;
index++)
{
if (_cmbCredential.Items[index]
is SonicCredentialProfile profile
&& profile.SonicCredentialId
== dialog.CreatedProfile.SonicCredentialId)
{
_cmbCredential.SelectedIndex =
index;
break;
}
}
_lblSystemDetails.Text =
$"Domain: {system.DomainName}"
+ Environment.NewLine
+ $"Adresse: {system.ConnectionUrl}"
+ Environment.NewLine
+ $"Profil: {dialog.CreatedProfile.CredentialName}";
MessageBox.Show(
this,
"Das geprüfte Benutzerprofil wurde geladen. " +
"Klicke jetzt auf „Auswahl übernehmen“.",
"Benutzerprofil hinzugefügt",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show(
this,
ex.Message,
"Benutzerprofile konnten nicht neu geladen werden",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
SetRunning(false);
}
}
private async Task SystemChangedAsync()
{
if (_cmbSystem.SelectedItem
is not SonicSystemOption system)
{
return;
}
_lblSystemDetails.Text =
$"Domain: {system.DomainName}" +
Environment.NewLine +
$"Adresse: {system.ConnectionUrl}";
_profiles =
await _coordinator.LoadCredentialsAsync(
system.SonicConnectionId);
_cmbCredential.Items.Clear();
foreach (SonicCredentialProfile profile
in _profiles)
{
_cmbCredential.Items.Add(profile);
}
if (_profiles.Count == 0)
{
_lblSystemDetails.Text +=
Environment.NewLine
+ "Kein Benutzerprofil vorhanden. "
+ "Bitte ein neues Profil hinzufügen.";
_btnSaveSelection.Enabled = false;
return;
}
_btnSaveSelection.Enabled = true;
LocalSetupSelection? selection =
_coordinator.LoadSelection();
int selectedIndex = 0;
if (selection is not null)
{
for (int index = 0;
index < _profiles.Count;
index++)
{
if (_profiles[index].SonicCredentialId ==
selection.SonicCredentialId)
{
selectedIndex = index;
break;
}
}
}
else
{
int defaultIndex =
_profiles
.Select(
(profile, index) =>
new
{
profile,
index
})
.Where(item =>
item.profile.IsDefault)
.Select(item => item.index)
.FirstOrDefault();
selectedIndex = defaultIndex;
}
_cmbCredential.SelectedIndex =
selectedIndex;
}
private async Task SaveSelectionAsync()
{
if (_cmbSystem.SelectedItem
is not SonicSystemOption system)
{
ShowWarning(
"Bitte ein Sonic-System auswählen.");
return;
}
if (_cmbCredential.SelectedItem
is not SonicCredentialProfile profile)
{
ShowWarning(
"Bitte ein Benutzerprofil auswählen.");
return;
}
_coordinator.SaveSelection(
system,
profile);
MessageBox.Show(
this,
"System und Benutzerprofil wurden ausgewählt.",
"Einstellungen",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
await InitializeAsync();
}
private async Task ImportCertificateAsync()
{
using OpenFileDialog dialog = new()
{
Title =
"Always-Encrypted-PFX auswählen",
Filter =
"PFX-Zertifikat (*.pfx)|*.pfx",
CheckFileExists = true,
Multiselect = false
};
if (dialog.ShowDialog(this)
!= DialogResult.OK)
{
return;
}
string? password =
PromptForPassword();
if (password is null)
{
return;
}
try
{
_coordinator.CertificateService.ImportPfx(
dialog.FileName,
password);
password = string.Empty;
await InitializeAsync();
}
finally
{
password = string.Empty;
}
}
private static string? PromptForPassword()
{
using Form form = new()
{
Text = "PFX-Kennwort",
Size = new Size(390, 160),
StartPosition =
FormStartPosition.CenterParent,
FormBorderStyle =
FormBorderStyle.FixedDialog
};
TextBox textBox = new()
{
Location = new Point(15, 35),
Width = 340,
UseSystemPasswordChar = true
};
Button ok = new()
{
Text = "OK",
Location = new Point(190, 75),
DialogResult = DialogResult.OK
};
Button cancel = new()
{
Text = "Abbrechen",
Location = new Point(275, 75),
DialogResult = DialogResult.Cancel
};
form.Controls.Add(textBox);
form.Controls.Add(ok);
form.Controls.Add(cancel);
form.AcceptButton = ok;
form.CancelButton = cancel;
return form.ShowDialog()
== DialogResult.OK
? textBox.Text
: null;
}
private void SetRunning(bool running)
{
_running = running;
_cmbSystem.Enabled = !running;
_cmbCredential.Enabled = !running;
_btnAddCredential.Enabled = !running;
_btnSaveSelection.Enabled = !running;
_btnRefresh.Enabled = !running;
_btnImportCertificate.Enabled = !running;
Cursor =
running
? Cursors.WaitCursor
: Cursors.Default;
}
private void ShowWarning(string message)
{
MessageBox.Show(
this,
message,
"Einstellungen",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
}
private Panel CreateCard(
Point location,
Size size)
{
return new Panel
{
Location = location,
Size = size,
BackColor = _cardColor,
BorderStyle =
BorderStyle.FixedSingle
};
}
private Label CreateTitle(
string text,
Point location)
{
return new Label
{
Text = text,
Location = location,
AutoSize = true,
ForeColor = _textColor,
Font = new Font(
"Segoe UI",
14,
FontStyle.Bold)
};
}
private Label CreateLabel(
string text,
Point location)
{
return new Label
{
Text = text,
Location = location,
AutoSize = true,
ForeColor = _mutedTextColor
};
}
private Label CreateStatus(
Point location)
{
return new Label
{
Location = location,
Size = new Size(620, 32),
ForeColor = _mutedTextColor
};
}
private Button CreateButton(string text)
{
return new Button
{
Text = text,
BackColor = _goldColor,
ForeColor =
Color.FromArgb(30, 25, 10),
FlatStyle = FlatStyle.Flat,
Font = new Font(
"Segoe UI",
9,
FontStyle.Bold),
Cursor = Cursors.Hand
};
}
private void SetStatus(
Label label,
string category,
bool success,
string message)
{
label.Text =
$"{(success ? "" : "")} " +
$"{category}: {message}";
label.ForeColor =
success
? _greenColor
: _redColor;
}
}