1107 lines
32 KiB
C#
1107 lines
32 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 Panel _sidebar = null!;
|
|
private Panel _contentHost = null!;
|
|
private Panel _panelStatus = null!;
|
|
private Panel _panelSystems = null!;
|
|
private Panel _panelContainers = null!;
|
|
private Panel _panelPaths = null!;
|
|
private Panel _panelProfiles = null!;
|
|
|
|
private readonly List<Button> _navButtons = [];
|
|
private Button _activeNav = null!;
|
|
|
|
private Label _lblRuntime = null!;
|
|
private Label _lblCertificate = null!;
|
|
private Label _lblDatabase = null!;
|
|
private Label _lblSelection = null!;
|
|
private Label _lblEnvironmentBadge = null!;
|
|
|
|
private ListView _lvSystems = null!;
|
|
private ListView _lvContainers = null!;
|
|
private ListView _lvPaths = null!;
|
|
|
|
private ComboBox _cmbSystem = null!;
|
|
private ComboBox _cmbCredential = null!;
|
|
private Label _lblSystemDetails = null!;
|
|
|
|
private Button _btnImportCertificate = 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;
|
|
|
|
Text = "Einstellungen";
|
|
StartPosition = FormStartPosition.CenterScreen;
|
|
Size = new Size(1180, 760);
|
|
MinimumSize = new Size(1080, 700);
|
|
BackColor = SettingsUi.Background;
|
|
ForeColor = SettingsUi.Text;
|
|
Font = new Font("Segoe UI", 10f);
|
|
DoubleBuffered = true;
|
|
|
|
BuildShell();
|
|
BuildStatusPanel();
|
|
BuildSystemsPanel();
|
|
BuildContainersPanel();
|
|
BuildPathsPanel();
|
|
BuildProfilesPanel();
|
|
ShowPanel(_panelStatus, _navButtons[0]);
|
|
|
|
Shown += async (_, _) => await RefreshAllAsync();
|
|
}
|
|
|
|
private void BuildShell()
|
|
{
|
|
_sidebar = new Panel
|
|
{
|
|
Dock = DockStyle.Left,
|
|
Width = 230,
|
|
BackColor = SettingsUi.Sidebar
|
|
};
|
|
|
|
Label brand = new()
|
|
{
|
|
Text = "ESB Certificate",
|
|
Location = new Point(22, 28),
|
|
AutoSize = true,
|
|
ForeColor = SettingsUi.Gold,
|
|
Font = new Font("Segoe UI Semibold", 11f, FontStyle.Bold)
|
|
};
|
|
|
|
Label brandSub = new()
|
|
{
|
|
Text = "Einstellungen",
|
|
Location = new Point(22, 52),
|
|
AutoSize = true,
|
|
ForeColor = SettingsUi.Text,
|
|
Font = new Font("Segoe UI Semibold", 20f, FontStyle.Bold)
|
|
};
|
|
|
|
_lblEnvironmentBadge = new Label
|
|
{
|
|
Text = _coordinator.Settings.EnvironmentCode,
|
|
Location = new Point(22, 95),
|
|
AutoSize = true,
|
|
Padding = new Padding(10, 4, 10, 4),
|
|
BackColor = Color.FromArgb(40, 208, 171, 57),
|
|
ForeColor = SettingsUi.Gold,
|
|
Font = new Font("Segoe UI Semibold", 9f, FontStyle.Bold)
|
|
};
|
|
|
|
_sidebar.Controls.Add(brand);
|
|
_sidebar.Controls.Add(brandSub);
|
|
_sidebar.Controls.Add(_lblEnvironmentBadge);
|
|
|
|
string[] navItems =
|
|
[
|
|
"Prüfung",
|
|
"Systeme",
|
|
"Container",
|
|
"Pfade",
|
|
"Profile"
|
|
];
|
|
|
|
int y = 150;
|
|
|
|
foreach (string item in navItems)
|
|
{
|
|
Button nav = CreateNavButton(item);
|
|
nav.Location = new Point(14, y);
|
|
y += 48;
|
|
_navButtons.Add(nav);
|
|
_sidebar.Controls.Add(nav);
|
|
}
|
|
|
|
_navButtons[0].Click += (_, _) =>
|
|
ShowPanel(_panelStatus, _navButtons[0]);
|
|
_navButtons[1].Click += async (_, _) =>
|
|
{
|
|
ShowPanel(_panelSystems, _navButtons[1]);
|
|
await LoadSystemsListAsync();
|
|
};
|
|
_navButtons[2].Click += async (_, _) =>
|
|
{
|
|
ShowPanel(_panelContainers, _navButtons[2]);
|
|
await LoadContainersListAsync();
|
|
};
|
|
_navButtons[3].Click += async (_, _) =>
|
|
{
|
|
ShowPanel(_panelPaths, _navButtons[3]);
|
|
await LoadPathsListAsync();
|
|
};
|
|
_navButtons[4].Click += async (_, _) =>
|
|
{
|
|
ShowPanel(_panelProfiles, _navButtons[4]);
|
|
await LoadSystemsAsync();
|
|
};
|
|
|
|
Panel footer = new()
|
|
{
|
|
Dock = DockStyle.Bottom,
|
|
Height = 72,
|
|
BackColor = SettingsUi.Background
|
|
};
|
|
|
|
Button closeButton = SettingsUi.CreateGhostButton(
|
|
_isSettingsMode ? "Schließen" : "Abbrechen");
|
|
closeButton.Location = new Point(Width - 340, 16);
|
|
closeButton.Size = new Size(120, 40);
|
|
closeButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
|
closeButton.Click += async (_, _) => await CloseAsync();
|
|
|
|
_btnFinish = SettingsUi.CreatePrimaryButton(
|
|
_isSettingsMode ? "Übernehmen" : "Fertig");
|
|
_btnFinish.Location = new Point(Width - 200, 16);
|
|
_btnFinish.Size = new Size(160, 40);
|
|
_btnFinish.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
|
_btnFinish.Enabled = false;
|
|
_btnFinish.Click += (_, _) =>
|
|
{
|
|
DialogResult = DialogResult.OK;
|
|
Close();
|
|
};
|
|
|
|
Button refresh = SettingsUi.CreateGhostButton("Aktualisieren");
|
|
refresh.Location = new Point(250, 16);
|
|
refresh.Size = new Size(130, 40);
|
|
refresh.Click += async (_, _) => await RefreshAllAsync();
|
|
|
|
footer.Controls.Add(refresh);
|
|
footer.Controls.Add(closeButton);
|
|
footer.Controls.Add(_btnFinish);
|
|
|
|
_contentHost = new Panel
|
|
{
|
|
Dock = DockStyle.Fill,
|
|
BackColor = SettingsUi.Background,
|
|
Padding = new Padding(28, 24, 28, 12)
|
|
};
|
|
|
|
Controls.Add(_contentHost);
|
|
Controls.Add(footer);
|
|
Controls.Add(_sidebar);
|
|
|
|
Resize += (_, _) =>
|
|
{
|
|
closeButton.Left = footer.Width - 340;
|
|
_btnFinish.Left = footer.Width - 200;
|
|
};
|
|
}
|
|
|
|
private Button CreateNavButton(string text)
|
|
{
|
|
Button button = new()
|
|
{
|
|
Text = " " + text,
|
|
Size = new Size(200, 42),
|
|
FlatStyle = FlatStyle.Flat,
|
|
TextAlign = ContentAlignment.MiddleLeft,
|
|
BackColor = SettingsUi.Sidebar,
|
|
ForeColor = SettingsUi.Muted,
|
|
Font = new Font("Segoe UI Semibold", 10.5f, FontStyle.Bold),
|
|
Cursor = Cursors.Hand
|
|
};
|
|
|
|
button.FlatAppearance.BorderSize = 0;
|
|
button.FlatAppearance.MouseOverBackColor = SettingsUi.CardHover;
|
|
return button;
|
|
}
|
|
|
|
private void ShowPanel(Panel panel, Button nav)
|
|
{
|
|
foreach (Control control in _contentHost.Controls)
|
|
{
|
|
control.Visible = false;
|
|
}
|
|
|
|
panel.Visible = true;
|
|
panel.BringToFront();
|
|
|
|
foreach (Button button in _navButtons)
|
|
{
|
|
button.BackColor = SettingsUi.Sidebar;
|
|
button.ForeColor = SettingsUi.Muted;
|
|
}
|
|
|
|
nav.BackColor = SettingsUi.Card;
|
|
nav.ForeColor = SettingsUi.Gold;
|
|
_activeNav = nav;
|
|
}
|
|
|
|
private Panel CreateContentPanel(string title, string subtitle)
|
|
{
|
|
Panel panel = new()
|
|
{
|
|
Dock = DockStyle.Fill,
|
|
BackColor = SettingsUi.Background,
|
|
Visible = false,
|
|
Padding = new Padding(4)
|
|
};
|
|
|
|
// Reihenfolge für Dock: Fill zuerst, dann Toolbar (Top), Header zuletzt (Top außen).
|
|
Panel header = CreateHeaderPanel(title, subtitle);
|
|
panel.Tag = header;
|
|
|
|
_contentHost.Controls.Add(panel);
|
|
return panel;
|
|
}
|
|
|
|
private static Panel CreateHeaderPanel(string title, string subtitle)
|
|
{
|
|
Panel header = new()
|
|
{
|
|
Dock = DockStyle.Top,
|
|
Height = 72,
|
|
BackColor = SettingsUi.Background
|
|
};
|
|
|
|
Label heading = new()
|
|
{
|
|
Text = title,
|
|
AutoSize = true,
|
|
Location = new Point(4, 2),
|
|
ForeColor = SettingsUi.Text,
|
|
Font = new Font("Segoe UI Semibold", 22f, FontStyle.Bold)
|
|
};
|
|
|
|
Label sub = new()
|
|
{
|
|
Text = subtitle,
|
|
AutoSize = true,
|
|
Location = new Point(8, 40),
|
|
ForeColor = SettingsUi.Muted,
|
|
Font = new Font("Segoe UI", 10f)
|
|
};
|
|
|
|
header.Controls.Add(heading);
|
|
header.Controls.Add(sub);
|
|
return header;
|
|
}
|
|
|
|
private static void FinishPanelLayout(Panel panel, Control list, Panel toolbar)
|
|
{
|
|
Panel header = (Panel)panel.Tag!;
|
|
|
|
// 1) Fill 2) Toolbar Top 3) Header Top (außen)
|
|
panel.Controls.Add(list);
|
|
panel.Controls.Add(toolbar);
|
|
panel.Controls.Add(header);
|
|
}
|
|
|
|
private void BuildStatusPanel()
|
|
{
|
|
_panelStatus = CreateContentPanel(
|
|
"Systemprüfung",
|
|
"Runtime, Zertifikat, Datenbank und aktuelle Auswahl.");
|
|
|
|
Panel card = SettingsUi.CreateCard();
|
|
card.Dock = DockStyle.Fill;
|
|
card.Padding = new Padding(12);
|
|
card.Paint += SettingsUi.PaintCardBorder;
|
|
|
|
_lblRuntime = CreateStatusLabel(20, 24);
|
|
_lblCertificate = CreateStatusLabel(20, 78);
|
|
_lblDatabase = CreateStatusLabel(20, 132);
|
|
_lblSelection = CreateStatusLabel(20, 186);
|
|
|
|
_btnImportCertificate = SettingsUi.CreatePrimaryButton("PFX importieren");
|
|
_btnImportCertificate.Location = new Point(640, 72);
|
|
_btnImportCertificate.Size = new Size(180, 38);
|
|
_btnImportCertificate.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
|
_btnImportCertificate.Click += async (_, _) =>
|
|
await ImportCertificateAsync();
|
|
|
|
Label tip = new()
|
|
{
|
|
Text =
|
|
"Tipp: Unter „Systeme“, „Container“ und „Pfade“ kannst du " +
|
|
"die Katalogdaten für die aktuelle Umgebung pflegen.",
|
|
Location = new Point(20, 235),
|
|
Size = new Size(780, 28),
|
|
ForeColor = SettingsUi.Muted
|
|
};
|
|
|
|
card.Controls.Add(_lblRuntime);
|
|
card.Controls.Add(_lblCertificate);
|
|
card.Controls.Add(_lblDatabase);
|
|
card.Controls.Add(_lblSelection);
|
|
card.Controls.Add(_btnImportCertificate);
|
|
card.Controls.Add(tip);
|
|
|
|
Panel header = (Panel)_panelStatus.Tag!;
|
|
_panelStatus.Controls.Add(card);
|
|
_panelStatus.Controls.Add(header);
|
|
}
|
|
|
|
private void BuildSystemsPanel()
|
|
{
|
|
_panelSystems = CreateContentPanel(
|
|
"Sonic-Systeme",
|
|
"Management-Verbindungen der aktuellen Umgebung.");
|
|
|
|
Panel toolbar = CreateToolbar(
|
|
"+ System hinzufügen",
|
|
async () => await AddSystemAsync());
|
|
|
|
_lvSystems = SettingsUi.CreateListView();
|
|
_lvSystems.Dock = DockStyle.Fill;
|
|
_lvSystems.Columns.Add("Name", 160);
|
|
_lvSystems.Columns.Add("Host", 180);
|
|
_lvSystems.Columns.Add("Port", 70);
|
|
_lvSystems.Columns.Add("Domain", 180);
|
|
_lvSystems.Columns.Add("Protokoll", 80);
|
|
_lvSystems.Columns.Add("URL", 180);
|
|
|
|
FinishPanelLayout(_panelSystems, _lvSystems, toolbar);
|
|
}
|
|
|
|
private void BuildContainersPanel()
|
|
{
|
|
_panelContainers = CreateContentPanel(
|
|
"Container",
|
|
"Sonic-Container je Company und System.");
|
|
|
|
Panel toolbar = CreateToolbar(
|
|
"+ Container hinzufügen",
|
|
async () => await AddContainerAsync());
|
|
|
|
_lvContainers = SettingsUi.CreateListView();
|
|
_lvContainers.Dock = DockStyle.Fill;
|
|
_lvContainers.Columns.Add("Company", 80);
|
|
_lvContainers.Columns.Add("Container", 180);
|
|
_lvContainers.Columns.Add("Anzeige", 160);
|
|
_lvContainers.Columns.Add("System", 160);
|
|
_lvContainers.Columns.Add("Timeout", 90);
|
|
|
|
FinishPanelLayout(_panelContainers, _lvContainers, toolbar);
|
|
}
|
|
|
|
private void BuildPathsPanel()
|
|
{
|
|
_panelPaths = CreateContentPanel(
|
|
"Zertifikat-Pfade",
|
|
"Zielverzeichnisse und Dateinamen für Deployments.");
|
|
|
|
Panel toolbar = CreateToolbar(
|
|
"+ Pfad hinzufügen",
|
|
async () => await AddPathAsync());
|
|
|
|
_lvPaths = SettingsUi.CreateListView();
|
|
_lvPaths.Dock = DockStyle.Fill;
|
|
_lvPaths.Columns.Add("Company", 70);
|
|
_lvPaths.Columns.Add("Container", 140);
|
|
_lvPaths.Columns.Add("Verzeichnis", 280);
|
|
_lvPaths.Columns.Add("Datei", 120);
|
|
_lvPaths.Columns.Add("Backup", 80);
|
|
_lvPaths.Columns.Add("System", 140);
|
|
|
|
FinishPanelLayout(_panelPaths, _lvPaths, toolbar);
|
|
}
|
|
|
|
private Panel CreateToolbar(
|
|
string addButtonText,
|
|
Func<Task> onAdd)
|
|
{
|
|
Panel toolbar = new()
|
|
{
|
|
Dock = DockStyle.Top,
|
|
Height = 56,
|
|
BackColor = SettingsUi.Background,
|
|
Padding = new Padding(8, 8, 8, 8)
|
|
};
|
|
|
|
Button add = SettingsUi.CreatePrimaryButton(addButtonText);
|
|
add.Dock = DockStyle.Left;
|
|
add.Width = 230;
|
|
add.Click += async (_, _) => await onAdd();
|
|
|
|
toolbar.Controls.Add(add);
|
|
return toolbar;
|
|
}
|
|
|
|
private void BuildProfilesPanel()
|
|
{
|
|
_panelProfiles = CreateContentPanel(
|
|
"Profil & Auswahl",
|
|
"Aktives Sonic-System und Benutzerprofil für Neustarts.");
|
|
|
|
Panel card = SettingsUi.CreateCard();
|
|
card.Dock = DockStyle.Fill;
|
|
card.Padding = new Padding(12);
|
|
card.Paint += SettingsUi.PaintCardBorder;
|
|
|
|
Label systemLabel = SettingsUi.CreateFieldLabel("Sonic-System");
|
|
systemLabel.Location = new Point(24, 24);
|
|
|
|
_cmbSystem = SettingsUi.CreateComboBox();
|
|
_cmbSystem.Location = new Point(24, 48);
|
|
_cmbSystem.Width = 340;
|
|
_cmbSystem.SelectedIndexChanged += async (_, _) =>
|
|
await SystemChangedAsync();
|
|
|
|
Label credentialLabel = SettingsUi.CreateFieldLabel("Benutzerprofil");
|
|
credentialLabel.Location = new Point(24, 100);
|
|
|
|
_cmbCredential = SettingsUi.CreateComboBox();
|
|
_cmbCredential.Location = new Point(24, 124);
|
|
_cmbCredential.Width = 340;
|
|
|
|
_btnAddCredential = SettingsUi.CreateGhostButton("Profil hinzufügen");
|
|
_btnAddCredential.Location = new Point(380, 122);
|
|
_btnAddCredential.Size = new Size(160, 34);
|
|
_btnAddCredential.Click += async (_, _) =>
|
|
await AddCredentialAsync();
|
|
|
|
_lblSystemDetails = new Label
|
|
{
|
|
Location = new Point(24, 180),
|
|
Size = new Size(780, 50),
|
|
ForeColor = SettingsUi.Muted
|
|
};
|
|
|
|
_btnSaveSelection = SettingsUi.CreatePrimaryButton("Auswahl übernehmen");
|
|
_btnSaveSelection.Location = new Point(600, 220);
|
|
_btnSaveSelection.Size = new Size(220, 40);
|
|
_btnSaveSelection.Click += async (_, _) =>
|
|
await SaveSelectionAsync();
|
|
|
|
card.Controls.Add(systemLabel);
|
|
card.Controls.Add(_cmbSystem);
|
|
card.Controls.Add(credentialLabel);
|
|
card.Controls.Add(_cmbCredential);
|
|
card.Controls.Add(_btnAddCredential);
|
|
card.Controls.Add(_lblSystemDetails);
|
|
card.Controls.Add(_btnSaveSelection);
|
|
|
|
Panel header = (Panel)_panelProfiles.Tag!;
|
|
_panelProfiles.Controls.Add(card);
|
|
_panelProfiles.Controls.Add(header);
|
|
}
|
|
|
|
private static Label CreateStatusLabel(int x, int y)
|
|
{
|
|
return new Label
|
|
{
|
|
Location = new Point(x, y),
|
|
Size = new Size(600, 40),
|
|
ForeColor = SettingsUi.Muted,
|
|
Font = new Font("Segoe UI", 10.5f)
|
|
};
|
|
}
|
|
|
|
private async Task RefreshAllAsync()
|
|
{
|
|
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();
|
|
await LoadSystemsListAsync();
|
|
await LoadContainersListAsync();
|
|
await LoadPathsListAsync();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(
|
|
this,
|
|
ex.Message,
|
|
"Einstellungen",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Error);
|
|
}
|
|
finally
|
|
{
|
|
SetRunning(false);
|
|
}
|
|
}
|
|
|
|
private async Task LoadSystemsListAsync()
|
|
{
|
|
try
|
|
{
|
|
_systems = await _coordinator.LoadSystemsAsync();
|
|
_lvSystems.Items.Clear();
|
|
|
|
foreach (SonicSystemOption system in _systems)
|
|
{
|
|
ListViewItem item = new(system.ConnectionName);
|
|
item.SubItems.Add(system.ManagementHost);
|
|
item.SubItems.Add(system.ManagementPort.ToString());
|
|
item.SubItems.Add(system.DomainName);
|
|
item.SubItems.Add(system.ConnectionProtocol);
|
|
item.SubItems.Add(system.ConnectionUrl);
|
|
item.Tag = system;
|
|
_lvSystems.Items.Add(item);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ShowError(ex.Message);
|
|
}
|
|
}
|
|
|
|
private async Task LoadContainersListAsync()
|
|
{
|
|
try
|
|
{
|
|
IReadOnlyList<ContainerOption> containers =
|
|
await _coordinator.LoadContainersAsync();
|
|
|
|
_lvContainers.Items.Clear();
|
|
|
|
foreach (ContainerOption container in containers)
|
|
{
|
|
ListViewItem item = new(container.CompanyCode);
|
|
item.SubItems.Add(container.ContainerName);
|
|
item.SubItems.Add(container.ContainerDisplayName ?? "—");
|
|
item.SubItems.Add(container.ConnectionName);
|
|
item.SubItems.Add(container.RestartTimeoutSeconds + " s");
|
|
item.Tag = container;
|
|
_lvContainers.Items.Add(item);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ShowError(ex.Message);
|
|
}
|
|
}
|
|
|
|
private async Task LoadPathsListAsync()
|
|
{
|
|
try
|
|
{
|
|
IReadOnlyList<CertificateTargetOption> targets =
|
|
await _coordinator.LoadCertificateTargetsAsync();
|
|
|
|
_lvPaths.Items.Clear();
|
|
|
|
foreach (CertificateTargetOption target in targets)
|
|
{
|
|
ListViewItem item = new(target.CompanyCode);
|
|
item.SubItems.Add(target.ContainerName);
|
|
item.SubItems.Add(target.TargetDirectory);
|
|
item.SubItems.Add(target.TargetFileName);
|
|
item.SubItems.Add(
|
|
target.BackupEnabled
|
|
? target.BackupDirectoryName
|
|
: "aus");
|
|
item.SubItems.Add(target.ConnectionName);
|
|
item.Tag = target;
|
|
_lvPaths.Items.Add(item);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
ShowError(ex.Message);
|
|
}
|
|
}
|
|
|
|
private async Task AddSystemAsync()
|
|
{
|
|
using AddSonicSystemForm dialog = new(_coordinator);
|
|
|
|
if (dialog.ShowDialog(this) != DialogResult.OK
|
|
|| dialog.CreatedSonicConnectionId is not int createdId)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await LoadSystemsListAsync();
|
|
await LoadSystemsAsync();
|
|
await RefreshAllAsync();
|
|
|
|
bool visible = _lvSystems.Items
|
|
.Cast<ListViewItem>()
|
|
.Any(item =>
|
|
item.Tag is SonicSystemOption system
|
|
&& system.SonicConnectionId == createdId);
|
|
|
|
if (!visible)
|
|
{
|
|
ShowError(
|
|
$"Anlage-Prüfung fehlgeschlagen: System-Id {createdId} " +
|
|
"ist nach dem Speichern nicht in der Liste.");
|
|
return;
|
|
}
|
|
|
|
SelectListItem(
|
|
_lvSystems,
|
|
item =>
|
|
item.Tag is SonicSystemOption system
|
|
&& system.SonicConnectionId == createdId);
|
|
|
|
MessageBox.Show(
|
|
this,
|
|
$"System wurde gespeichert und geprüft (Id {createdId}).",
|
|
"Prüfung OK",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Information);
|
|
}
|
|
|
|
private async Task AddContainerAsync()
|
|
{
|
|
int? preferred = null;
|
|
|
|
if (_lvSystems.SelectedItems.Count > 0
|
|
&& _lvSystems.SelectedItems[0].Tag is SonicSystemOption system)
|
|
{
|
|
preferred = system.SonicConnectionId;
|
|
}
|
|
|
|
using AddContainerForm dialog = new(_coordinator, preferred);
|
|
|
|
if (dialog.ShowDialog(this) != DialogResult.OK
|
|
|| dialog.CreatedSonicContainerId is not int createdId)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await LoadContainersListAsync();
|
|
await LoadSystemsListAsync();
|
|
await RefreshAllAsync();
|
|
|
|
bool visible = _lvContainers.Items
|
|
.Cast<ListViewItem>()
|
|
.Any(item =>
|
|
item.Tag is ContainerOption container
|
|
&& container.SonicContainerId == createdId);
|
|
|
|
if (!visible)
|
|
{
|
|
ShowError(
|
|
$"Anlage-Prüfung fehlgeschlagen: Container-Id {createdId} " +
|
|
"ist nach dem Speichern nicht in der Liste.");
|
|
return;
|
|
}
|
|
|
|
SelectListItem(
|
|
_lvContainers,
|
|
item =>
|
|
item.Tag is ContainerOption container
|
|
&& container.SonicContainerId == createdId);
|
|
|
|
MessageBox.Show(
|
|
this,
|
|
$"Container wurde gespeichert und geprüft (Id {createdId}).",
|
|
"Prüfung OK",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Information);
|
|
}
|
|
|
|
private async Task AddPathAsync()
|
|
{
|
|
int? preferred = null;
|
|
|
|
if (_lvContainers.SelectedItems.Count > 0
|
|
&& _lvContainers.SelectedItems[0].Tag is ContainerOption container)
|
|
{
|
|
preferred = container.SonicContainerId;
|
|
}
|
|
|
|
using AddTargetPathForm dialog = new(_coordinator, preferred);
|
|
|
|
if (dialog.ShowDialog(this) != DialogResult.OK
|
|
|| dialog.CreatedCertificateTargetId is not int createdId)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await LoadPathsListAsync();
|
|
await RefreshAllAsync();
|
|
|
|
bool visible = _lvPaths.Items
|
|
.Cast<ListViewItem>()
|
|
.Any(item =>
|
|
item.Tag is CertificateTargetOption target
|
|
&& target.CertificateTargetId == createdId);
|
|
|
|
if (!visible)
|
|
{
|
|
ShowError(
|
|
$"Anlage-Prüfung fehlgeschlagen: Pfad-Id {createdId} " +
|
|
"ist nach dem Speichern nicht in der Liste.");
|
|
return;
|
|
}
|
|
|
|
SelectListItem(
|
|
_lvPaths,
|
|
item =>
|
|
item.Tag is CertificateTargetOption target
|
|
&& target.CertificateTargetId == createdId);
|
|
|
|
MessageBox.Show(
|
|
this,
|
|
$"Zertifikat-Pfad wurde gespeichert und geprüft (Id {createdId}).",
|
|
"Prüfung OK",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Information);
|
|
}
|
|
|
|
private static void SelectListItem(
|
|
ListView listView,
|
|
Func<ListViewItem, bool> match)
|
|
{
|
|
foreach (ListViewItem item in listView.Items)
|
|
{
|
|
if (!match(item))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
item.Selected = true;
|
|
item.EnsureVisible();
|
|
listView.Focus();
|
|
return;
|
|
}
|
|
}
|
|
|
|
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 vorhanden. Lege zuerst unter „Systeme“ eines an.";
|
|
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 (_cmbSystem.SelectedItem is not SonicSystemOption system)
|
|
{
|
|
ShowWarning("Bitte zuerst ein Sonic-System auswählen.");
|
|
return;
|
|
}
|
|
|
|
using AddCredentialProfileForm dialog =
|
|
new(_coordinator, system);
|
|
|
|
if (dialog.ShowDialog(this) != DialogResult.OK
|
|
|| dialog.CreatedProfile is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await SystemChangedAsync();
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
MessageBox.Show(
|
|
this,
|
|
"Profil geladen. Jetzt „Auswahl übernehmen“ klicken.",
|
|
"Benutzerprofil",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Information);
|
|
}
|
|
|
|
private async Task SystemChangedAsync()
|
|
{
|
|
if (_cmbSystem.SelectedItem is not SonicSystemOption system)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_lblSystemDetails.Text =
|
|
$"Domain: {system.DomainName} · {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
|
|
+ "Noch kein Benutzerprofil — bitte 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
|
|
{
|
|
selectedIndex = _profiles
|
|
.Select((profile, index) => new { profile, index })
|
|
.Where(item => item.profile.IsDefault)
|
|
.Select(item => item.index)
|
|
.FirstOrDefault();
|
|
}
|
|
|
|
_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,
|
|
"Auswahl gespeichert.",
|
|
"Einstellungen",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Information);
|
|
|
|
await RefreshAllAsync();
|
|
}
|
|
|
|
private async Task ImportCertificateAsync()
|
|
{
|
|
using OpenFileDialog dialog = new()
|
|
{
|
|
Title = "Always-Encrypted-PFX auswählen",
|
|
Filter = "PFX-Zertifikat (*.pfx)|*.pfx",
|
|
CheckFileExists = true
|
|
};
|
|
|
|
if (dialog.ShowDialog(this) != DialogResult.OK)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string? password = PromptForPassword();
|
|
|
|
if (password is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
_coordinator.CertificateService.ImportPfx(
|
|
dialog.FileName,
|
|
password);
|
|
|
|
await RefreshAllAsync();
|
|
}
|
|
finally
|
|
{
|
|
password = string.Empty;
|
|
}
|
|
}
|
|
|
|
private async Task CloseAsync()
|
|
{
|
|
if (_isSettingsMode)
|
|
{
|
|
SetupCheckResult check = await _coordinator.CheckAsync();
|
|
DialogResult = check.IsReady
|
|
? DialogResult.OK
|
|
: DialogResult.Cancel;
|
|
}
|
|
else
|
|
{
|
|
DialogResult = DialogResult.Cancel;
|
|
}
|
|
|
|
Close();
|
|
}
|
|
|
|
private static string? PromptForPassword()
|
|
{
|
|
using Form form = new()
|
|
{
|
|
Text = "PFX-Kennwort",
|
|
Size = new Size(390, 170),
|
|
StartPosition = FormStartPosition.CenterParent,
|
|
FormBorderStyle = FormBorderStyle.FixedDialog,
|
|
BackColor = SettingsUi.Background,
|
|
ForeColor = SettingsUi.Text
|
|
};
|
|
|
|
TextBox textBox = SettingsUi.CreateTextBox();
|
|
textBox.Location = new Point(20, 40);
|
|
textBox.Width = 330;
|
|
textBox.UseSystemPasswordChar = true;
|
|
|
|
Button ok = SettingsUi.CreatePrimaryButton("OK");
|
|
ok.Location = new Point(160, 85);
|
|
ok.Size = new Size(90, 34);
|
|
ok.DialogResult = DialogResult.OK;
|
|
|
|
Button cancel = SettingsUi.CreateGhostButton("Abbrechen");
|
|
cancel.Location = new Point(260, 85);
|
|
cancel.Size = new Size(90, 34);
|
|
cancel.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;
|
|
UseWaitCursor = running;
|
|
}
|
|
|
|
private void ShowWarning(string message)
|
|
{
|
|
MessageBox.Show(
|
|
this,
|
|
message,
|
|
"Einstellungen",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Warning);
|
|
}
|
|
|
|
private void ShowError(string message)
|
|
{
|
|
MessageBox.Show(
|
|
this,
|
|
message,
|
|
"Einstellungen",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Error);
|
|
}
|
|
|
|
private static void SetStatus(
|
|
Label label,
|
|
string category,
|
|
bool success,
|
|
string message)
|
|
{
|
|
label.Text =
|
|
$"{(success ? "●" : "○")} {category}\n {message}";
|
|
|
|
label.ForeColor = success
|
|
? SettingsUi.Green
|
|
: SettingsUi.Red;
|
|
}
|
|
}
|