Simplify DB to six tables and load credentials via Always Encrypted SonicCredential.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Security.Cryptography.X509Certificates;
|
||||
using ZA.CoreService.ESBCertificateManager.Configuration;
|
||||
using ZA.CoreService.ESBCertificateManager.Models;
|
||||
using ZA.CoreService.ESBCertificateManager.Services;
|
||||
using ZA.CoreService.ESBCertificateManager.Setup;
|
||||
using Microsoft.Data.SqlClient;
|
||||
|
||||
namespace ZA.CoreService.ESBCertificateManager
|
||||
@@ -34,10 +35,17 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
private DeploymentOrchestrator? _orchestrator;
|
||||
private readonly SonicConnectionRepository _sonicConnectionRepository;
|
||||
private readonly DeploymentTargetRepository _deploymentTargetRepository;
|
||||
private readonly SonicSetupRepository _sonicSetupRepository;
|
||||
private readonly LocalSetupSelectionStore _localSetupSelectionStore;
|
||||
|
||||
private IReadOnlyList<DatabaseSonicConnection>
|
||||
_databaseSonicConnections = [];
|
||||
|
||||
private readonly Dictionary<int, SonicCredentialProfile>
|
||||
_credentialsByConnectionId = new();
|
||||
|
||||
private LocalSetupSelection? _localSetupSelection;
|
||||
|
||||
private CertificateInfo? _loadedCertificateInfo;
|
||||
private IReadOnlyList<DeploymentTarget> _loadedTargets = [];
|
||||
private bool _isOperationRunning;
|
||||
@@ -89,6 +97,11 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
_deploymentTargetRepository = new DeploymentTargetRepository(
|
||||
_settings.Database.ConnectionString);
|
||||
|
||||
_sonicSetupRepository = new SonicSetupRepository(
|
||||
_settings.Database.ConnectionString);
|
||||
|
||||
_localSetupSelectionStore = new LocalSetupSelectionStore();
|
||||
|
||||
BuildDesign();
|
||||
|
||||
Shown += async (_, _) => await InitializeApplicationAsync();
|
||||
@@ -135,6 +148,52 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
dragStartPoint = e.Location;
|
||||
}
|
||||
}
|
||||
private async Task OpenSettingsAsync()
|
||||
{
|
||||
if (_isOperationRunning)
|
||||
{
|
||||
MessageBox.Show(
|
||||
this,
|
||||
"Während einer laufenden Aktion können die Einstellungen nicht geöffnet werden.",
|
||||
"Einstellungen",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
SetupCoordinator coordinator = new(
|
||||
_settings,
|
||||
new SonicSetupRepository(
|
||||
_settings.Database.ConnectionString));
|
||||
|
||||
using SetupWizardForm settingsForm = new(
|
||||
coordinator,
|
||||
isSettingsMode: true);
|
||||
|
||||
if (settingsForm.ShowDialog(this) != DialogResult.OK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetStatus(
|
||||
"Einstellungen übernommen. Anwendung wird aktualisiert ...",
|
||||
isError: false);
|
||||
|
||||
await InitializeApplicationAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(
|
||||
this,
|
||||
ex.Message,
|
||||
"Einstellungen",
|
||||
MessageBoxButtons.OK,
|
||||
MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InitializeApplicationAsync()
|
||||
{
|
||||
|
||||
@@ -163,16 +222,32 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
}
|
||||
try
|
||||
{
|
||||
_databaseSonicConnections =
|
||||
await _sonicConnectionRepository.GetActiveAsync();
|
||||
_localSetupSelection =
|
||||
_localSetupSelectionStore.Load();
|
||||
|
||||
List<SonicConnection> runtimeConnections =
|
||||
_databaseSonicConnections
|
||||
.Where(connection => connection.HasCredentials)
|
||||
.Select(connection =>
|
||||
_databaseSonicConnections =
|
||||
await _sonicConnectionRepository.GetActiveAsync(
|
||||
_settings.EnvironmentCode);
|
||||
|
||||
await LoadCredentialsForConnectionsAsync();
|
||||
|
||||
List<SonicConnection> runtimeConnections = [];
|
||||
|
||||
foreach (DatabaseSonicConnection connection
|
||||
in _databaseSonicConnections)
|
||||
{
|
||||
if (!_credentialsByConnectionId.TryGetValue(
|
||||
connection.Id,
|
||||
out SonicCredentialProfile? credential))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
runtimeConnections.Add(
|
||||
connection.ToRuntimeConnection(
|
||||
_settings.Runtime))
|
||||
.ToList();
|
||||
_settings.Runtime,
|
||||
credential));
|
||||
}
|
||||
|
||||
_orchestrator = new DeploymentOrchestrator(
|
||||
_settings,
|
||||
@@ -195,12 +270,13 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
|
||||
SetStatus(
|
||||
$"{_databaseSonicConnections.Count} aktive Sonic-Verbindung(en) " +
|
||||
$"aus SQL und {_loadedTargets.Count} lokale Testziele geladen.",
|
||||
$"aus SQL und {_loadedTargets.Count} Bereitstellungsziel(e) geladen.",
|
||||
isError: false);
|
||||
}
|
||||
catch (SqlException ex)
|
||||
{
|
||||
_databaseSonicConnections = [];
|
||||
_credentialsByConnectionId.Clear();
|
||||
|
||||
SetStatus(
|
||||
$"SQL-Zugriff fehlgeschlagen: {ex.Message}",
|
||||
@@ -485,12 +561,12 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
progressPanel.Controls.Add(progressTitle);
|
||||
|
||||
// -----------------------------
|
||||
// 3. Footer unten: Version
|
||||
// 3. Footer unten: Einstellungen + Version
|
||||
// -----------------------------
|
||||
Panel footerPanel = new Panel
|
||||
{
|
||||
Dock = DockStyle.Bottom,
|
||||
Height = 70,
|
||||
Height = 118,
|
||||
Padding = new Padding(18, 8, 12, 8)
|
||||
};
|
||||
|
||||
@@ -501,13 +577,36 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
BackColor = BorderColor
|
||||
};
|
||||
|
||||
Button btnSettings = new Button
|
||||
{
|
||||
Text = " Einstellungen",
|
||||
Location = new Point(14, 14),
|
||||
Size = new Size(176, 36),
|
||||
FlatStyle = FlatStyle.Flat,
|
||||
FlatAppearance =
|
||||
{
|
||||
BorderSize = 1,
|
||||
BorderColor = BorderColor,
|
||||
MouseOverBackColor = Color.FromArgb(37, 52, 74)
|
||||
},
|
||||
BackColor = SidebarColor,
|
||||
ForeColor = TextColor,
|
||||
Font = new Font("Segoe UI", 9, FontStyle.Bold),
|
||||
TextAlign = ContentAlignment.MiddleLeft,
|
||||
Cursor = Cursors.Hand,
|
||||
Enabled = !_isOperationRunning
|
||||
};
|
||||
|
||||
btnSettings.Click += async (_, _) =>
|
||||
await OpenSettingsAsync();
|
||||
|
||||
Label versionLabel = new Label
|
||||
{
|
||||
Text = "INTERNAL TOOL",
|
||||
ForeColor = MutedTextColor,
|
||||
Font = new Font("Segoe UI", 7.5f, FontStyle.Bold),
|
||||
AutoSize = true,
|
||||
Location = new Point(18, 17)
|
||||
Location = new Point(18, 62)
|
||||
};
|
||||
|
||||
Label versionNumber = new Label
|
||||
@@ -516,10 +615,11 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
ForeColor = BlueColor,
|
||||
Font = new Font("Segoe UI", 8),
|
||||
AutoSize = true,
|
||||
Location = new Point(18, 37)
|
||||
Location = new Point(18, 82)
|
||||
};
|
||||
|
||||
footerPanel.Controls.Add(footerSeparator);
|
||||
footerPanel.Controls.Add(btnSettings);
|
||||
footerPanel.Controls.Add(versionLabel);
|
||||
footerPanel.Controls.Add(versionNumber);
|
||||
|
||||
@@ -1428,7 +1528,8 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
isError: false);
|
||||
|
||||
_loadedTargets =
|
||||
await _deploymentTargetRepository.GetActiveAsync();
|
||||
await _deploymentTargetRepository.GetActiveAsync(
|
||||
_settings.EnvironmentCode);
|
||||
|
||||
BindTargetsToGrid(_loadedTargets);
|
||||
|
||||
@@ -1943,6 +2044,42 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
// ---------------------------------------------------------------
|
||||
// Sonic – Status (KnownContainers aus appsettings)
|
||||
// ---------------------------------------------------------------
|
||||
private async Task LoadCredentialsForConnectionsAsync()
|
||||
{
|
||||
_credentialsByConnectionId.Clear();
|
||||
|
||||
foreach (DatabaseSonicConnection connection
|
||||
in _databaseSonicConnections)
|
||||
{
|
||||
IReadOnlyList<SonicCredentialProfile> profiles =
|
||||
await _sonicSetupRepository.GetCredentialsAsync(
|
||||
connection.Id);
|
||||
|
||||
SonicCredentialProfile? selected = null;
|
||||
|
||||
if (_localSetupSelection is not null
|
||||
&& _localSetupSelection.SonicConnectionId
|
||||
== connection.Id
|
||||
&& _localSetupSelection.SonicCredentialId > 0)
|
||||
{
|
||||
selected = profiles.FirstOrDefault(
|
||||
profile =>
|
||||
profile.SonicCredentialId
|
||||
== _localSetupSelection.SonicCredentialId);
|
||||
}
|
||||
|
||||
selected ??=
|
||||
profiles.FirstOrDefault(profile => profile.IsDefault)
|
||||
?? profiles.FirstOrDefault();
|
||||
|
||||
if (selected is not null && selected.IsComplete)
|
||||
{
|
||||
_credentialsByConnectionId[connection.Id] =
|
||||
selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void BindDatabaseSonicConnections()
|
||||
{
|
||||
cmbSonicConnection.Items.Clear();
|
||||
@@ -1953,13 +2090,34 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
cmbSonicConnection.Items.Add(connection.Name);
|
||||
}
|
||||
|
||||
if (cmbSonicConnection.Items.Count > 0)
|
||||
if (cmbSonicConnection.Items.Count == 0)
|
||||
{
|
||||
cmbSonicConnection.SelectedIndex = 0;
|
||||
RefreshSonicStatusLine();
|
||||
return;
|
||||
}
|
||||
|
||||
RefreshSonicStatusLine();
|
||||
int preferredIndex = 0;
|
||||
|
||||
if (_localSetupSelection is not null
|
||||
&& !string.IsNullOrWhiteSpace(
|
||||
_localSetupSelection.ConnectionName))
|
||||
{
|
||||
for (int index = 0;
|
||||
index < cmbSonicConnection.Items.Count;
|
||||
index++)
|
||||
{
|
||||
if (string.Equals(
|
||||
cmbSonicConnection.Items[index]?.ToString(),
|
||||
_localSetupSelection.ConnectionName,
|
||||
StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
preferredIndex = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmbSonicConnection.SelectedIndex = preferredIndex;
|
||||
}
|
||||
private void BuildSonicDiscoveryRow(Panel card)
|
||||
{
|
||||
@@ -2036,14 +2194,19 @@ namespace ZA.CoreService.ESBCertificateManager
|
||||
{
|
||||
string connectionUrl = connection.BuildConnectionUrl();
|
||||
|
||||
bool hasCredentialReference =
|
||||
!string.IsNullOrWhiteSpace(connection.CredentialReference);
|
||||
bool hasCredential =
|
||||
_credentialsByConnectionId.TryGetValue(
|
||||
connection.Id,
|
||||
out SonicCredentialProfile? credential);
|
||||
|
||||
lblSonicStatus.Text = hasCredentialReference
|
||||
? $"{connection.Name}: {connectionUrl}, Credential-Referenz vorhanden"
|
||||
: $"{connection.Name}: {connectionUrl}, sichere Zugangsdaten noch nicht konfiguriert";
|
||||
string credentialInfo = hasCredential
|
||||
? $"Profil '{credential!.CredentialName}'"
|
||||
: "sichere Zugangsdaten noch nicht konfiguriert";
|
||||
|
||||
lblSonicStatus.ForeColor = hasCredentialReference
|
||||
lblSonicStatus.Text =
|
||||
$"{connection.Name}: {connectionUrl}, {credentialInfo}";
|
||||
|
||||
lblSonicStatus.ForeColor = hasCredential
|
||||
? GreenColor
|
||||
: GoldColor;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user