Simplify DB to six tables and load credentials via Always Encrypted SonicCredential.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Data.SqlClient;
|
||||
using System.Data;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using ZA.CoreService.ESBCertificateManager.Models;
|
||||
|
||||
namespace ZA.CoreService.ESBCertificateManager.Services;
|
||||
@@ -20,65 +21,57 @@ public sealed class DeploymentTargetRepository
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<DeploymentTarget>> GetActiveAsync(
|
||||
string environmentCode,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(environmentCode))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Der EnvironmentCode fehlt.",
|
||||
nameof(environmentCode));
|
||||
}
|
||||
|
||||
const string sql = """
|
||||
SELECT
|
||||
target.CertificateTargetId,
|
||||
target.TargetDirectory,
|
||||
target.TargetFileName,
|
||||
target.BackupEnabled,
|
||||
target.BackupDirectoryName,
|
||||
target.BackupRetentionDays,
|
||||
target.IsActive AS TargetIsActive,
|
||||
target.[CertificateTargetId],
|
||||
target.[TargetDirectory],
|
||||
target.[TargetFileName],
|
||||
target.[BackupEnabled],
|
||||
target.[BackupDirectoryName],
|
||||
target.[IsActive] AS [TargetIsActive],
|
||||
|
||||
container.SonicContainerId,
|
||||
container.ContainerName,
|
||||
container.ContainerDisplayName,
|
||||
container.RestartTimeoutSeconds,
|
||||
container.[SonicContainerId],
|
||||
container.[ContainerName],
|
||||
container.[ContainerDisplayName],
|
||||
container.[RestartTimeoutSeconds],
|
||||
|
||||
connection.ConnectionName,
|
||||
connection.[ConnectionName],
|
||||
|
||||
service.ServiceCode,
|
||||
service.ServiceName,
|
||||
environment.[EnvironmentCode],
|
||||
environment.[SortOrder] AS [EnvironmentSortOrder],
|
||||
|
||||
environment.EnvironmentCode,
|
||||
environment.SortOrder AS EnvironmentSortOrder,
|
||||
|
||||
company.CompanyCode,
|
||||
country.CountryCode
|
||||
FROM dbo.CertificateTarget AS target
|
||||
INNER JOIN dbo.SonicContainer AS container
|
||||
ON container.SonicContainerId = target.SonicContainerId
|
||||
INNER JOIN dbo.SonicConnection AS connection
|
||||
ON connection.SonicConnectionId = container.SonicConnectionId
|
||||
INNER JOIN dbo.EsbService AS service
|
||||
ON service.EsbServiceId = container.EsbServiceId
|
||||
INNER JOIN dbo.Company AS company
|
||||
ON company.CompanyId = service.CompanyId
|
||||
LEFT JOIN dbo.Country AS country
|
||||
ON country.CountryId = service.CountryId
|
||||
INNER JOIN dbo.Environment AS environment
|
||||
ON environment.EnvironmentId = service.EnvironmentId
|
||||
WHERE target.IsActive = 1
|
||||
AND container.IsActive = 1
|
||||
AND connection.IsActive = 1
|
||||
AND service.IsActive = 1
|
||||
AND company.IsActive = 1
|
||||
AND environment.IsActive = 1
|
||||
AND
|
||||
(
|
||||
country.CountryId IS NULL
|
||||
OR country.IsActive = 1
|
||||
)
|
||||
company.[CompanyCode]
|
||||
FROM [dbo].[CertificateTarget] AS target
|
||||
INNER JOIN [dbo].[SonicContainer] AS container
|
||||
ON container.[SonicContainerId] = target.[SonicContainerId]
|
||||
INNER JOIN [dbo].[SonicConnection] AS connection
|
||||
ON connection.[SonicConnectionId] = container.[SonicConnectionId]
|
||||
INNER JOIN [dbo].[Environment] AS environment
|
||||
ON environment.[EnvironmentId] = connection.[EnvironmentId]
|
||||
INNER JOIN [dbo].[Company] AS company
|
||||
ON company.[CompanyId] = container.[CompanyId]
|
||||
WHERE target.[IsActive] = 1
|
||||
AND container.[IsActive] = 1
|
||||
AND connection.[IsActive] = 1
|
||||
AND company.[IsActive] = 1
|
||||
AND environment.[IsActive] = 1
|
||||
AND environment.[EnvironmentCode] = @EnvironmentCode
|
||||
ORDER BY
|
||||
company.CompanyCode,
|
||||
country.CountryCode,
|
||||
environment.SortOrder,
|
||||
service.ServiceCode,
|
||||
container.ContainerName,
|
||||
target.TargetDirectory,
|
||||
target.TargetFileName;
|
||||
company.[CompanyCode],
|
||||
environment.[SortOrder],
|
||||
container.[ContainerName],
|
||||
target.[TargetDirectory],
|
||||
target.[TargetFileName];
|
||||
""";
|
||||
|
||||
List<DeploymentTarget> targets = [];
|
||||
@@ -88,6 +81,17 @@ public sealed class DeploymentTargetRepository
|
||||
|
||||
await using SqlCommand command = new(sql, connection);
|
||||
|
||||
command.Parameters.Add(
|
||||
new SqlParameter(
|
||||
"@EnvironmentCode",
|
||||
SqlDbType.NVarChar,
|
||||
30)
|
||||
{
|
||||
Value = environmentCode
|
||||
.Trim()
|
||||
.ToUpperInvariant()
|
||||
});
|
||||
|
||||
await using SqlDataReader reader =
|
||||
await command.ExecuteReaderAsync(cancellationToken);
|
||||
|
||||
@@ -106,9 +110,6 @@ public sealed class DeploymentTargetRepository
|
||||
int backupDirectoryNameOrdinal =
|
||||
reader.GetOrdinal("BackupDirectoryName");
|
||||
|
||||
int backupRetentionDaysOrdinal =
|
||||
reader.GetOrdinal("BackupRetentionDays");
|
||||
|
||||
int targetIsActiveOrdinal =
|
||||
reader.GetOrdinal("TargetIsActive");
|
||||
|
||||
@@ -124,12 +125,6 @@ public sealed class DeploymentTargetRepository
|
||||
int connectionNameOrdinal =
|
||||
reader.GetOrdinal("ConnectionName");
|
||||
|
||||
int serviceCodeOrdinal =
|
||||
reader.GetOrdinal("ServiceCode");
|
||||
|
||||
int serviceNameOrdinal =
|
||||
reader.GetOrdinal("ServiceName");
|
||||
|
||||
int environmentCodeOrdinal =
|
||||
reader.GetOrdinal("EnvironmentCode");
|
||||
|
||||
@@ -139,9 +134,6 @@ public sealed class DeploymentTargetRepository
|
||||
int companyCodeOrdinal =
|
||||
reader.GetOrdinal("CompanyCode");
|
||||
|
||||
int countryCodeOrdinal =
|
||||
reader.GetOrdinal("CountryCode");
|
||||
|
||||
while (await reader.ReadAsync(cancellationToken))
|
||||
{
|
||||
string containerName =
|
||||
@@ -152,34 +144,19 @@ public sealed class DeploymentTargetRepository
|
||||
reader,
|
||||
containerDisplayNameOrdinal);
|
||||
|
||||
string serviceCode =
|
||||
reader.GetString(serviceCodeOrdinal);
|
||||
|
||||
string serviceName =
|
||||
reader.GetString(serviceNameOrdinal);
|
||||
|
||||
string companyCode =
|
||||
reader.GetString(companyCodeOrdinal);
|
||||
|
||||
string? countryCode =
|
||||
ReadNullableString(reader, countryCodeOrdinal);
|
||||
|
||||
string displayName =
|
||||
string.IsNullOrWhiteSpace(containerDisplayName)
|
||||
? containerName
|
||||
: containerDisplayName;
|
||||
|
||||
string locationCode =
|
||||
string.IsNullOrWhiteSpace(countryCode)
|
||||
? companyCode
|
||||
: $"{companyCode}/{countryCode}";
|
||||
|
||||
targets.Add(new DeploymentTarget
|
||||
{
|
||||
Id = reader.GetInt32(targetIdOrdinal),
|
||||
|
||||
Name =
|
||||
$"{locationCode} / {serviceName} / {displayName}",
|
||||
Name = $"{companyCode} / {displayName}",
|
||||
|
||||
Environment =
|
||||
reader.GetString(environmentCodeOrdinal),
|
||||
@@ -199,10 +176,7 @@ public sealed class DeploymentTargetRepository
|
||||
BackupDirectoryName =
|
||||
reader.GetString(backupDirectoryNameOrdinal),
|
||||
|
||||
BackupRetentionDays =
|
||||
ReadNullableInt32(
|
||||
reader,
|
||||
backupRetentionDaysOrdinal),
|
||||
BackupRetentionDays = null,
|
||||
|
||||
ContainerName = containerName,
|
||||
|
||||
@@ -238,13 +212,4 @@ public sealed class DeploymentTargetRepository
|
||||
? null
|
||||
: reader.GetString(ordinal);
|
||||
}
|
||||
|
||||
private static int? ReadNullableInt32(
|
||||
SqlDataReader reader,
|
||||
int ordinal)
|
||||
{
|
||||
return reader.IsDBNull(ordinal)
|
||||
? null
|
||||
: reader.GetInt32(ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ public sealed class LocalSetupSelectionStore
|
||||
catch
|
||||
{
|
||||
// Eine beschädigte lokale Auswahl darf den Start
|
||||
// nicht verhindern. Das Setup wird erneut angezeigt.
|
||||
// nicht verhindern. Die Einstellungen werden erneut angezeigt.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public sealed class LocalSetupSelectionStore
|
||||
if (string.IsNullOrWhiteSpace(directory))
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Der lokale Setup-Ordner konnte nicht bestimmt werden.");
|
||||
"Der lokale Einstellungen-Ordner konnte nicht bestimmt werden.");
|
||||
}
|
||||
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
@@ -23,26 +23,31 @@ public sealed class SonicConnectionRepository
|
||||
|
||||
public async Task<IReadOnlyList<DatabaseSonicConnection>>
|
||||
GetActiveAsync(
|
||||
string? environmentCode = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
const string sql = """
|
||||
SELECT
|
||||
SonicConnectionId,
|
||||
ConnectionName,
|
||||
ManagementHost,
|
||||
ManagementPort,
|
||||
ConnectionProtocol,
|
||||
DomainName,
|
||||
CredentialUserName,
|
||||
CredentialReference,
|
||||
CredentialSecret,
|
||||
JavaHomePath,
|
||||
SonicHomePath,
|
||||
Notes,
|
||||
IsActive
|
||||
FROM dbo.SonicConnection
|
||||
WHERE IsActive = 1
|
||||
ORDER BY ConnectionName;
|
||||
connection.[SonicConnectionId],
|
||||
connection.[ConnectionName],
|
||||
connection.[ManagementHost],
|
||||
connection.[ManagementPort],
|
||||
connection.[ConnectionProtocol],
|
||||
connection.[DomainName],
|
||||
environment.[EnvironmentCode],
|
||||
connection.[IsActive]
|
||||
FROM [dbo].[SonicConnection] AS connection
|
||||
INNER JOIN [dbo].[Environment] AS environment
|
||||
ON environment.[EnvironmentId] =
|
||||
connection.[EnvironmentId]
|
||||
WHERE connection.[IsActive] = 1
|
||||
AND environment.[IsActive] = 1
|
||||
AND
|
||||
(
|
||||
@EnvironmentCode IS NULL
|
||||
OR environment.[EnvironmentCode] = @EnvironmentCode
|
||||
)
|
||||
ORDER BY connection.[ConnectionName];
|
||||
""";
|
||||
|
||||
List<DatabaseSonicConnection> connections = [];
|
||||
@@ -55,6 +60,22 @@ public sealed class SonicConnectionRepository
|
||||
await using SqlCommand command =
|
||||
new(sql, connection);
|
||||
|
||||
string? normalizedEnvironmentCode =
|
||||
string.IsNullOrWhiteSpace(environmentCode)
|
||||
? null
|
||||
: environmentCode.Trim().ToUpperInvariant();
|
||||
|
||||
command.Parameters.Add(
|
||||
new SqlParameter(
|
||||
"@EnvironmentCode",
|
||||
SqlDbType.NVarChar,
|
||||
30)
|
||||
{
|
||||
Value = normalizedEnvironmentCode is null
|
||||
? DBNull.Value
|
||||
: normalizedEnvironmentCode
|
||||
});
|
||||
|
||||
await using SqlDataReader reader =
|
||||
await command.ExecuteReaderAsync(
|
||||
cancellationToken);
|
||||
@@ -77,23 +98,8 @@ public sealed class SonicConnectionRepository
|
||||
int domainOrdinal =
|
||||
reader.GetOrdinal("DomainName");
|
||||
|
||||
int userNameOrdinal =
|
||||
reader.GetOrdinal("CredentialUserName");
|
||||
|
||||
int credentialReferenceOrdinal =
|
||||
reader.GetOrdinal("CredentialReference");
|
||||
|
||||
int credentialSecretOrdinal =
|
||||
reader.GetOrdinal("CredentialSecret");
|
||||
|
||||
int javaHomeOrdinal =
|
||||
reader.GetOrdinal("JavaHomePath");
|
||||
|
||||
int sonicHomeOrdinal =
|
||||
reader.GetOrdinal("SonicHomePath");
|
||||
|
||||
int notesOrdinal =
|
||||
reader.GetOrdinal("Notes");
|
||||
int environmentCodeOrdinal =
|
||||
reader.GetOrdinal("EnvironmentCode");
|
||||
|
||||
int isActiveOrdinal =
|
||||
reader.GetOrdinal("IsActive");
|
||||
@@ -112,9 +118,7 @@ public sealed class SonicConnectionRepository
|
||||
reader.GetString(hostOrdinal),
|
||||
|
||||
ManagementPort =
|
||||
ReadNullableInt32(
|
||||
reader,
|
||||
portOrdinal),
|
||||
reader.GetInt32(portOrdinal),
|
||||
|
||||
ConnectionProtocol =
|
||||
ReadNullableString(
|
||||
@@ -126,35 +130,10 @@ public sealed class SonicConnectionRepository
|
||||
reader,
|
||||
domainOrdinal),
|
||||
|
||||
CredentialUserName =
|
||||
EnvironmentCode =
|
||||
ReadNullableString(
|
||||
reader,
|
||||
userNameOrdinal),
|
||||
|
||||
CredentialReference =
|
||||
ReadNullableString(
|
||||
reader,
|
||||
credentialReferenceOrdinal),
|
||||
|
||||
CredentialSecret =
|
||||
ReadNullableString(
|
||||
reader,
|
||||
credentialSecretOrdinal),
|
||||
|
||||
JavaHomePath =
|
||||
ReadNullableString(
|
||||
reader,
|
||||
javaHomeOrdinal),
|
||||
|
||||
SonicHomePath =
|
||||
ReadNullableString(
|
||||
reader,
|
||||
sonicHomeOrdinal),
|
||||
|
||||
Notes =
|
||||
ReadNullableString(
|
||||
reader,
|
||||
notesOrdinal),
|
||||
environmentCodeOrdinal),
|
||||
|
||||
IsActive =
|
||||
reader.GetBoolean(
|
||||
@@ -165,154 +144,6 @@ public sealed class SonicConnectionRepository
|
||||
return connections;
|
||||
}
|
||||
|
||||
public async Task SaveCredentialsAsync(
|
||||
int sonicConnectionId,
|
||||
string credentialUserName,
|
||||
string credentialSecret,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (sonicConnectionId <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(sonicConnectionId),
|
||||
"Die SonicConnectionId ist ungültig.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(
|
||||
credentialUserName))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Der Sonic-Benutzername fehlt.",
|
||||
nameof(credentialUserName));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(
|
||||
credentialSecret))
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Das Sonic-Kennwort fehlt.",
|
||||
nameof(credentialSecret));
|
||||
}
|
||||
|
||||
string normalizedUserName =
|
||||
credentialUserName.Trim();
|
||||
|
||||
if (normalizedUserName.Length > 256)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Der Sonic-Benutzername darf maximal 256 Zeichen enthalten.",
|
||||
nameof(credentialUserName));
|
||||
}
|
||||
|
||||
if (credentialSecret.Length > 512)
|
||||
{
|
||||
throw new ArgumentException(
|
||||
"Das Sonic-Kennwort darf maximal 512 Zeichen enthalten.",
|
||||
nameof(credentialSecret));
|
||||
}
|
||||
|
||||
const string sql = """
|
||||
UPDATE dbo.SonicConnection
|
||||
SET
|
||||
CredentialUserName = @CredentialUserName,
|
||||
CredentialSecret = @CredentialSecret,
|
||||
UpdatedAtUtc = SYSUTCDATETIME()
|
||||
WHERE SonicConnectionId = @SonicConnectionId
|
||||
AND IsActive = 1;
|
||||
""";
|
||||
|
||||
await using SqlConnection connection =
|
||||
new(_connectionString);
|
||||
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
await using SqlCommand command =
|
||||
new(sql, connection);
|
||||
|
||||
command.Parameters.Add(
|
||||
new SqlParameter(
|
||||
"@CredentialUserName",
|
||||
SqlDbType.NVarChar,
|
||||
256)
|
||||
{
|
||||
Value = normalizedUserName
|
||||
});
|
||||
|
||||
command.Parameters.Add(
|
||||
new SqlParameter(
|
||||
"@CredentialSecret",
|
||||
SqlDbType.NVarChar,
|
||||
512)
|
||||
{
|
||||
Value = credentialSecret
|
||||
});
|
||||
|
||||
command.Parameters.Add(
|
||||
new SqlParameter(
|
||||
"@SonicConnectionId",
|
||||
SqlDbType.Int)
|
||||
{
|
||||
Value = sonicConnectionId
|
||||
});
|
||||
|
||||
int affectedRows =
|
||||
await command.ExecuteNonQueryAsync(
|
||||
cancellationToken);
|
||||
|
||||
if (affectedRows != 1)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Die aktive Sonic-Verbindung wurde nicht eindeutig gefunden.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ClearCredentialsAsync(
|
||||
int sonicConnectionId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (sonicConnectionId <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(sonicConnectionId),
|
||||
"Die SonicConnectionId ist ungültig.");
|
||||
}
|
||||
|
||||
const string sql = """
|
||||
UPDATE dbo.SonicConnection
|
||||
SET
|
||||
CredentialUserName = NULL,
|
||||
CredentialSecret = NULL,
|
||||
UpdatedAtUtc = SYSUTCDATETIME()
|
||||
WHERE SonicConnectionId = @SonicConnectionId;
|
||||
""";
|
||||
|
||||
await using SqlConnection connection =
|
||||
new(_connectionString);
|
||||
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
await using SqlCommand command =
|
||||
new(sql, connection);
|
||||
|
||||
command.Parameters.Add(
|
||||
new SqlParameter(
|
||||
"@SonicConnectionId",
|
||||
SqlDbType.Int)
|
||||
{
|
||||
Value = sonicConnectionId
|
||||
});
|
||||
|
||||
int affectedRows =
|
||||
await command.ExecuteNonQueryAsync(
|
||||
cancellationToken);
|
||||
|
||||
if (affectedRows != 1)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Die Sonic-Verbindung wurde nicht eindeutig gefunden.");
|
||||
}
|
||||
}
|
||||
|
||||
private static string? ReadNullableString(
|
||||
SqlDataReader reader,
|
||||
int ordinal)
|
||||
@@ -321,13 +152,4 @@ public sealed class SonicConnectionRepository
|
||||
? null
|
||||
: reader.GetString(ordinal);
|
||||
}
|
||||
|
||||
private static int? ReadNullableInt32(
|
||||
SqlDataReader reader,
|
||||
int ordinal)
|
||||
{
|
||||
return reader.IsDBNull(ordinal)
|
||||
? null
|
||||
: reader.GetInt32(ordinal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public sealed class SonicMfApiExecutor
|
||||
null,
|
||||
"Für die Sonic-Verbindung sind keine " +
|
||||
"vollständigen Zugangsdaten eingerichtet. " +
|
||||
"Bitte das Setup ausführen.");
|
||||
"Bitte die Einstellungen öffnen und Zugangsdaten hinterlegen.");
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(
|
||||
@@ -145,8 +145,8 @@ public sealed class SonicMfApiExecutor
|
||||
* übergeben. Dadurch erscheint das Kennwort nicht in
|
||||
* der Prozessargumentliste.
|
||||
*
|
||||
* CredentialSecret wurde zuvor durch Microsoft.Data.SqlClient
|
||||
* clientseitig entschlüsselt und als Laufzeitwert in
|
||||
* Das Kennwort stammt aus dbo.SonicCredential (Always Encrypted),
|
||||
* wurde clientseitig entschlüsselt und als Laufzeitwert in
|
||||
* SonicConnection.Password übernommen.
|
||||
*/
|
||||
startInfo.Environment[
|
||||
|
||||
@@ -33,40 +33,36 @@ public sealed class SonicSetupRepository
|
||||
|
||||
const string sql = """
|
||||
SELECT
|
||||
connection.SonicConnectionId,
|
||||
connection.ConnectionName,
|
||||
environment.EnvironmentCode,
|
||||
connection.DomainName,
|
||||
connection.ManagementHost,
|
||||
connection.ManagementPort,
|
||||
connection.ConnectionProtocol,
|
||||
MIN(container.ContainerName)
|
||||
AS ValidationContainerName
|
||||
FROM dbo.SonicConnection AS connection
|
||||
INNER JOIN dbo.SonicContainer AS container
|
||||
ON container.SonicConnectionId =
|
||||
connection.SonicConnectionId
|
||||
INNER JOIN dbo.EsbService AS service
|
||||
ON service.EsbServiceId =
|
||||
container.EsbServiceId
|
||||
INNER JOIN dbo.Environment AS environment
|
||||
ON environment.EnvironmentId =
|
||||
service.EnvironmentId
|
||||
WHERE connection.IsActive = 1
|
||||
AND container.IsActive = 1
|
||||
AND service.IsActive = 1
|
||||
AND environment.IsActive = 1
|
||||
AND environment.EnvironmentCode =
|
||||
connection.[SonicConnectionId],
|
||||
connection.[ConnectionName],
|
||||
environment.[EnvironmentCode],
|
||||
connection.[DomainName],
|
||||
connection.[ManagementHost],
|
||||
connection.[ManagementPort],
|
||||
connection.[ConnectionProtocol],
|
||||
MIN(container.[ContainerName])
|
||||
AS [ValidationContainerName]
|
||||
FROM [dbo].[SonicConnection] AS connection
|
||||
INNER JOIN [dbo].[Environment] AS environment
|
||||
ON environment.[EnvironmentId] =
|
||||
connection.[EnvironmentId]
|
||||
INNER JOIN [dbo].[SonicContainer] AS container
|
||||
ON container.[SonicConnectionId] =
|
||||
connection.[SonicConnectionId]
|
||||
WHERE connection.[IsActive] = 1
|
||||
AND container.[IsActive] = 1
|
||||
AND environment.[IsActive] = 1
|
||||
AND environment.[EnvironmentCode] =
|
||||
@EnvironmentCode
|
||||
GROUP BY
|
||||
connection.SonicConnectionId,
|
||||
connection.ConnectionName,
|
||||
environment.EnvironmentCode,
|
||||
connection.DomainName,
|
||||
connection.ManagementHost,
|
||||
connection.ManagementPort,
|
||||
connection.ConnectionProtocol
|
||||
ORDER BY connection.ConnectionName;
|
||||
connection.[SonicConnectionId],
|
||||
connection.[ConnectionName],
|
||||
environment.[EnvironmentCode],
|
||||
connection.[DomainName],
|
||||
connection.[ManagementHost],
|
||||
connection.[ManagementPort],
|
||||
connection.[ConnectionProtocol]
|
||||
ORDER BY connection.[ConnectionName];
|
||||
""";
|
||||
|
||||
List<SonicSystemOption> systems = [];
|
||||
@@ -119,11 +115,6 @@ public sealed class SonicSetupRepository
|
||||
|
||||
while (await reader.ReadAsync(cancellationToken))
|
||||
{
|
||||
if (reader.IsDBNull(managementPortOrdinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
systems.Add(
|
||||
new SonicSystemOption
|
||||
{
|
||||
@@ -248,13 +239,14 @@ public sealed class SonicSetupRepository
|
||||
if (isDefault)
|
||||
{
|
||||
const string clearDefaultSql = """
|
||||
UPDATE dbo.SonicCredential
|
||||
UPDATE [dbo].[SonicCredential]
|
||||
SET
|
||||
IsDefault = 0,
|
||||
UpdatedAtUtc = SYSUTCDATETIME()
|
||||
WHERE SonicConnectionId =
|
||||
[IsDefault] = 0,
|
||||
[ModifiedDateTime] = SYSUTCDATETIME(),
|
||||
[ModifiedBy] = SUSER_SNAME()
|
||||
WHERE [SonicConnectionId] =
|
||||
@SonicConnectionId
|
||||
AND IsDefault = 1;
|
||||
AND [IsDefault] = 1;
|
||||
""";
|
||||
|
||||
await using SqlCommand clearDefaultCommand =
|
||||
@@ -276,18 +268,20 @@ public sealed class SonicSetupRepository
|
||||
}
|
||||
|
||||
const string insertSql = """
|
||||
INSERT INTO dbo.SonicCredential
|
||||
INSERT INTO [dbo].[SonicCredential]
|
||||
(
|
||||
SonicConnectionId,
|
||||
CredentialName,
|
||||
CredentialUserName,
|
||||
CredentialSecret,
|
||||
IsDefault,
|
||||
IsActive,
|
||||
CreatedAtUtc,
|
||||
UpdatedAtUtc
|
||||
[SonicConnectionId],
|
||||
[CredentialName],
|
||||
[CredentialUserName],
|
||||
[CredentialSecret],
|
||||
[IsDefault],
|
||||
[IsActive],
|
||||
[CreationDateTime],
|
||||
[CreatedBy],
|
||||
[ModifiedDateTime],
|
||||
[ModifiedBy]
|
||||
)
|
||||
OUTPUT INSERTED.SonicCredentialId
|
||||
OUTPUT INSERTED.[SonicCredentialId]
|
||||
VALUES
|
||||
(
|
||||
@SonicConnectionId,
|
||||
@@ -297,6 +291,8 @@ public sealed class SonicSetupRepository
|
||||
@IsDefault,
|
||||
1,
|
||||
SYSUTCDATETIME(),
|
||||
SUSER_SNAME(),
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
""";
|
||||
@@ -397,19 +393,19 @@ public sealed class SonicSetupRepository
|
||||
|
||||
const string sql = """
|
||||
SELECT
|
||||
SonicCredentialId,
|
||||
SonicConnectionId,
|
||||
CredentialName,
|
||||
CredentialUserName,
|
||||
CredentialSecret,
|
||||
IsDefault,
|
||||
IsActive
|
||||
FROM dbo.SonicCredential
|
||||
WHERE SonicConnectionId = @SonicConnectionId
|
||||
AND IsActive = 1
|
||||
[SonicCredentialId],
|
||||
[SonicConnectionId],
|
||||
[CredentialName],
|
||||
[CredentialUserName],
|
||||
[CredentialSecret],
|
||||
[IsDefault],
|
||||
[IsActive]
|
||||
FROM [dbo].[SonicCredential]
|
||||
WHERE [SonicConnectionId] = @SonicConnectionId
|
||||
AND [IsActive] = 1
|
||||
ORDER BY
|
||||
IsDefault DESC,
|
||||
CredentialName;
|
||||
[IsDefault] DESC,
|
||||
[CredentialName];
|
||||
""";
|
||||
|
||||
List<SonicCredentialProfile> profiles = [];
|
||||
@@ -502,4 +498,101 @@ public sealed class SonicSetupRepository
|
||||
|
||||
return profiles;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<SonicCredentialProfile?> GetCredentialByIdAsync(
|
||||
int sonicCredentialId,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (sonicCredentialId <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(
|
||||
nameof(sonicCredentialId));
|
||||
}
|
||||
|
||||
const string sql = """
|
||||
SELECT
|
||||
[SonicCredentialId],
|
||||
[SonicConnectionId],
|
||||
[CredentialName],
|
||||
[CredentialUserName],
|
||||
[CredentialSecret],
|
||||
[IsDefault],
|
||||
[IsActive]
|
||||
FROM [dbo].[SonicCredential]
|
||||
WHERE [SonicCredentialId] = @SonicCredentialId
|
||||
AND [IsActive] = 1;
|
||||
""";
|
||||
|
||||
await using SqlConnection connection =
|
||||
new(_connectionString);
|
||||
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
|
||||
await using SqlCommand command =
|
||||
new(sql, connection);
|
||||
|
||||
command.Parameters.Add(
|
||||
new SqlParameter(
|
||||
"@SonicCredentialId",
|
||||
SqlDbType.Int)
|
||||
{
|
||||
Value = sonicCredentialId
|
||||
});
|
||||
|
||||
await using SqlDataReader reader =
|
||||
await command.ExecuteReaderAsync(cancellationToken);
|
||||
|
||||
if (!await reader.ReadAsync(cancellationToken))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int userNameOrdinal =
|
||||
reader.GetOrdinal("CredentialUserName");
|
||||
|
||||
int secretOrdinal =
|
||||
reader.GetOrdinal("CredentialSecret");
|
||||
|
||||
string? userName =
|
||||
reader.IsDBNull(userNameOrdinal)
|
||||
? null
|
||||
: reader.GetString(userNameOrdinal);
|
||||
|
||||
string? secret =
|
||||
reader.IsDBNull(secretOrdinal)
|
||||
? null
|
||||
: reader.GetString(secretOrdinal);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(userName)
|
||||
|| string.IsNullOrEmpty(secret))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SonicCredentialProfile
|
||||
{
|
||||
SonicCredentialId =
|
||||
reader.GetInt32(
|
||||
reader.GetOrdinal("SonicCredentialId")),
|
||||
|
||||
SonicConnectionId =
|
||||
reader.GetInt32(
|
||||
reader.GetOrdinal("SonicConnectionId")),
|
||||
|
||||
CredentialName =
|
||||
reader.GetString(
|
||||
reader.GetOrdinal("CredentialName")),
|
||||
|
||||
UserName = userName,
|
||||
Secret = secret,
|
||||
|
||||
IsDefault =
|
||||
reader.GetBoolean(
|
||||
reader.GetOrdinal("IsDefault")),
|
||||
|
||||
IsActive =
|
||||
reader.GetBoolean(
|
||||
reader.GetOrdinal("IsActive"))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user