505 lines
15 KiB
C#
505 lines
15 KiB
C#
using System.Data;
|
|
using Microsoft.Data.SqlClient;
|
|
using ZA.CoreService.ESBCertificateManager.Models;
|
|
|
|
namespace ZA.CoreService.ESBCertificateManager.Services;
|
|
|
|
public sealed class SonicSetupRepository
|
|
{
|
|
private readonly string _connectionString;
|
|
|
|
public SonicSetupRepository(string connectionString)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(connectionString))
|
|
{
|
|
throw new ArgumentException(
|
|
"Der SQL-Connection-String fehlt.",
|
|
nameof(connectionString));
|
|
}
|
|
|
|
_connectionString = connectionString;
|
|
}
|
|
|
|
public async Task<IReadOnlyList<SonicSystemOption>> GetSystemsAsync(
|
|
string environmentCode,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(environmentCode))
|
|
{
|
|
throw new ArgumentException(
|
|
"Der EnvironmentCode fehlt.",
|
|
nameof(environmentCode));
|
|
}
|
|
|
|
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 =
|
|
@EnvironmentCode
|
|
GROUP BY
|
|
connection.SonicConnectionId,
|
|
connection.ConnectionName,
|
|
environment.EnvironmentCode,
|
|
connection.DomainName,
|
|
connection.ManagementHost,
|
|
connection.ManagementPort,
|
|
connection.ConnectionProtocol
|
|
ORDER BY connection.ConnectionName;
|
|
""";
|
|
|
|
List<SonicSystemOption> systems = [];
|
|
|
|
await using SqlConnection connection =
|
|
new(_connectionString);
|
|
|
|
await connection.OpenAsync(cancellationToken);
|
|
|
|
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);
|
|
|
|
int sonicConnectionIdOrdinal =
|
|
reader.GetOrdinal("SonicConnectionId");
|
|
|
|
int connectionNameOrdinal =
|
|
reader.GetOrdinal("ConnectionName");
|
|
|
|
int environmentCodeOrdinal =
|
|
reader.GetOrdinal("EnvironmentCode");
|
|
|
|
int domainNameOrdinal =
|
|
reader.GetOrdinal("DomainName");
|
|
|
|
int managementHostOrdinal =
|
|
reader.GetOrdinal("ManagementHost");
|
|
|
|
int managementPortOrdinal =
|
|
reader.GetOrdinal("ManagementPort");
|
|
|
|
int connectionProtocolOrdinal =
|
|
reader.GetOrdinal("ConnectionProtocol");
|
|
|
|
int validationContainerNameOrdinal =
|
|
reader.GetOrdinal("ValidationContainerName");
|
|
|
|
while (await reader.ReadAsync(cancellationToken))
|
|
{
|
|
if (reader.IsDBNull(managementPortOrdinal))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
systems.Add(
|
|
new SonicSystemOption
|
|
{
|
|
SonicConnectionId =
|
|
reader.GetInt32(
|
|
sonicConnectionIdOrdinal),
|
|
|
|
ConnectionName =
|
|
reader.GetString(
|
|
connectionNameOrdinal),
|
|
|
|
EnvironmentCode =
|
|
reader.GetString(
|
|
environmentCodeOrdinal),
|
|
|
|
DomainName =
|
|
reader.IsDBNull(domainNameOrdinal)
|
|
? string.Empty
|
|
: reader.GetString(
|
|
domainNameOrdinal),
|
|
|
|
ManagementHost =
|
|
reader.GetString(
|
|
managementHostOrdinal),
|
|
|
|
ManagementPort =
|
|
reader.GetInt32(
|
|
managementPortOrdinal),
|
|
|
|
ConnectionProtocol =
|
|
reader.IsDBNull(connectionProtocolOrdinal)
|
|
? "tcp"
|
|
: reader.GetString(
|
|
connectionProtocolOrdinal),
|
|
|
|
ValidationContainerName =
|
|
reader.IsDBNull(
|
|
validationContainerNameOrdinal)
|
|
? string.Empty
|
|
: reader.GetString(
|
|
validationContainerNameOrdinal)
|
|
});
|
|
}
|
|
|
|
return systems;
|
|
}
|
|
|
|
public async Task<int> AddCredentialAsync(
|
|
int sonicConnectionId,
|
|
string credentialName,
|
|
string userName,
|
|
string secret,
|
|
bool isDefault,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (sonicConnectionId <= 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException(
|
|
nameof(sonicConnectionId));
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(credentialName))
|
|
{
|
|
throw new ArgumentException(
|
|
"Der Profilname fehlt.",
|
|
nameof(credentialName));
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(userName))
|
|
{
|
|
throw new ArgumentException(
|
|
"Der Sonic-Benutzername fehlt.",
|
|
nameof(userName));
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(secret))
|
|
{
|
|
throw new ArgumentException(
|
|
"Das Sonic-Kennwort fehlt.",
|
|
nameof(secret));
|
|
}
|
|
|
|
string normalizedCredentialName =
|
|
credentialName.Trim();
|
|
|
|
string normalizedUserName =
|
|
userName.Trim();
|
|
|
|
if (normalizedCredentialName.Length > 150)
|
|
{
|
|
throw new ArgumentException(
|
|
"Der Profilname darf maximal 150 Zeichen enthalten.",
|
|
nameof(credentialName));
|
|
}
|
|
|
|
if (normalizedUserName.Length > 256)
|
|
{
|
|
throw new ArgumentException(
|
|
"Der Benutzername darf maximal 256 Zeichen enthalten.",
|
|
nameof(userName));
|
|
}
|
|
|
|
if (secret.Length > 512)
|
|
{
|
|
throw new ArgumentException(
|
|
"Das Kennwort darf maximal 512 Zeichen enthalten.",
|
|
nameof(secret));
|
|
}
|
|
|
|
await using SqlConnection connection =
|
|
new(_connectionString);
|
|
|
|
await connection.OpenAsync(cancellationToken);
|
|
|
|
await using SqlTransaction transaction =
|
|
(SqlTransaction)
|
|
await connection.BeginTransactionAsync(
|
|
cancellationToken);
|
|
|
|
try
|
|
{
|
|
if (isDefault)
|
|
{
|
|
const string clearDefaultSql = """
|
|
UPDATE dbo.SonicCredential
|
|
SET
|
|
IsDefault = 0,
|
|
UpdatedAtUtc = SYSUTCDATETIME()
|
|
WHERE SonicConnectionId =
|
|
@SonicConnectionId
|
|
AND IsDefault = 1;
|
|
""";
|
|
|
|
await using SqlCommand clearDefaultCommand =
|
|
new(
|
|
clearDefaultSql,
|
|
connection,
|
|
transaction);
|
|
|
|
clearDefaultCommand.Parameters.Add(
|
|
new SqlParameter(
|
|
"@SonicConnectionId",
|
|
SqlDbType.Int)
|
|
{
|
|
Value = sonicConnectionId
|
|
});
|
|
|
|
await clearDefaultCommand.ExecuteNonQueryAsync(
|
|
cancellationToken);
|
|
}
|
|
|
|
const string insertSql = """
|
|
INSERT INTO dbo.SonicCredential
|
|
(
|
|
SonicConnectionId,
|
|
CredentialName,
|
|
CredentialUserName,
|
|
CredentialSecret,
|
|
IsDefault,
|
|
IsActive,
|
|
CreatedAtUtc,
|
|
UpdatedAtUtc
|
|
)
|
|
OUTPUT INSERTED.SonicCredentialId
|
|
VALUES
|
|
(
|
|
@SonicConnectionId,
|
|
@CredentialName,
|
|
@CredentialUserName,
|
|
@CredentialSecret,
|
|
@IsDefault,
|
|
1,
|
|
SYSUTCDATETIME(),
|
|
NULL
|
|
);
|
|
""";
|
|
|
|
await using SqlCommand insertCommand =
|
|
new(
|
|
insertSql,
|
|
connection,
|
|
transaction);
|
|
|
|
insertCommand.Parameters.Add(
|
|
new SqlParameter(
|
|
"@SonicConnectionId",
|
|
SqlDbType.Int)
|
|
{
|
|
Value = sonicConnectionId
|
|
});
|
|
|
|
insertCommand.Parameters.Add(
|
|
new SqlParameter(
|
|
"@CredentialName",
|
|
SqlDbType.NVarChar,
|
|
150)
|
|
{
|
|
Value = normalizedCredentialName
|
|
});
|
|
|
|
insertCommand.Parameters.Add(
|
|
new SqlParameter(
|
|
"@CredentialUserName",
|
|
SqlDbType.NVarChar,
|
|
256)
|
|
{
|
|
Value = normalizedUserName
|
|
});
|
|
|
|
insertCommand.Parameters.Add(
|
|
new SqlParameter(
|
|
"@CredentialSecret",
|
|
SqlDbType.NVarChar,
|
|
512)
|
|
{
|
|
Value = secret
|
|
});
|
|
|
|
insertCommand.Parameters.Add(
|
|
new SqlParameter(
|
|
"@IsDefault",
|
|
SqlDbType.Bit)
|
|
{
|
|
Value = isDefault
|
|
});
|
|
|
|
object? result =
|
|
await insertCommand.ExecuteScalarAsync(
|
|
cancellationToken);
|
|
|
|
if (result is null || result is DBNull)
|
|
{
|
|
throw new InvalidOperationException(
|
|
"Das Benutzerprofil konnte nicht angelegt werden.");
|
|
}
|
|
|
|
int credentialId =
|
|
Convert.ToInt32(result);
|
|
|
|
await transaction.CommitAsync(
|
|
cancellationToken);
|
|
|
|
return credentialId;
|
|
}
|
|
catch
|
|
{
|
|
try
|
|
{
|
|
await transaction.RollbackAsync(
|
|
CancellationToken.None);
|
|
}
|
|
catch
|
|
{
|
|
// Die ursprüngliche Exception soll erhalten bleiben.
|
|
}
|
|
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public async Task<IReadOnlyList<SonicCredentialProfile>>
|
|
GetCredentialsAsync(
|
|
int sonicConnectionId,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
if (sonicConnectionId <= 0)
|
|
{
|
|
throw new ArgumentOutOfRangeException(
|
|
nameof(sonicConnectionId));
|
|
}
|
|
|
|
const string sql = """
|
|
SELECT
|
|
SonicCredentialId,
|
|
SonicConnectionId,
|
|
CredentialName,
|
|
CredentialUserName,
|
|
CredentialSecret,
|
|
IsDefault,
|
|
IsActive
|
|
FROM dbo.SonicCredential
|
|
WHERE SonicConnectionId = @SonicConnectionId
|
|
AND IsActive = 1
|
|
ORDER BY
|
|
IsDefault DESC,
|
|
CredentialName;
|
|
""";
|
|
|
|
List<SonicCredentialProfile> profiles = [];
|
|
|
|
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
|
|
});
|
|
|
|
await using SqlDataReader reader =
|
|
await command.ExecuteReaderAsync(cancellationToken);
|
|
|
|
int credentialIdOrdinal =
|
|
reader.GetOrdinal("SonicCredentialId");
|
|
|
|
int connectionIdOrdinal =
|
|
reader.GetOrdinal("SonicConnectionId");
|
|
|
|
int credentialNameOrdinal =
|
|
reader.GetOrdinal("CredentialName");
|
|
|
|
int userNameOrdinal =
|
|
reader.GetOrdinal("CredentialUserName");
|
|
|
|
int secretOrdinal =
|
|
reader.GetOrdinal("CredentialSecret");
|
|
|
|
int isDefaultOrdinal =
|
|
reader.GetOrdinal("IsDefault");
|
|
|
|
int isActiveOrdinal =
|
|
reader.GetOrdinal("IsActive");
|
|
|
|
while (await reader.ReadAsync(cancellationToken))
|
|
{
|
|
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))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
profiles.Add(
|
|
new SonicCredentialProfile
|
|
{
|
|
SonicCredentialId =
|
|
reader.GetInt32(
|
|
credentialIdOrdinal),
|
|
|
|
SonicConnectionId =
|
|
reader.GetInt32(
|
|
connectionIdOrdinal),
|
|
|
|
CredentialName =
|
|
reader.GetString(
|
|
credentialNameOrdinal),
|
|
|
|
UserName = userName,
|
|
Secret = secret,
|
|
|
|
IsDefault =
|
|
reader.GetBoolean(
|
|
isDefaultOrdinal),
|
|
|
|
IsActive =
|
|
reader.GetBoolean(
|
|
isActiveOrdinal)
|
|
});
|
|
}
|
|
|
|
return profiles;
|
|
}
|
|
} |