Files
123123/ZA.CoreService.ESBCertificateManager/Services/CertificateDeployer.cs
T
2026-07-24 08:10:13 +02:00

99 lines
3.3 KiB
C#

using System.Security.Cryptography;
using ZA.CoreService.ESBCertificateManager.Models;
namespace ZA.CoreService.ESBCertificateManager.Services;
public sealed class CertificateDeployer
{
public Task<(bool Success, string Status, string? Detail, string? BackupPath)> DeployAsync(
string sourceCertificatePath,
DeploymentTarget target,
CancellationToken cancellationToken = default)
{
return Task.Run(() => Deploy(sourceCertificatePath, target, cancellationToken), cancellationToken);
}
private static (bool Success, string Status, string? Detail, string? BackupPath) Deploy(
string sourceCertificatePath,
DeploymentTarget target,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
if (!File.Exists(sourceCertificatePath))
{
return (false, "Quelle fehlt", $"Quelldatei nicht gefunden: {sourceCertificatePath}", null);
}
string targetDirectory = PathResolver.ResolvePath(target.TargetDirectory);
Directory.CreateDirectory(targetDirectory);
string destinationPath = Path.Combine(targetDirectory, target.CertificateFileName);
string? backupPath = null;
try
{
if (File.Exists(destinationPath))
{
backupPath = $"{destinationPath}.bak-{DateTime.Now:yyyyMMddHHmmss}";
File.Copy(destinationPath, backupPath, overwrite: false);
}
cancellationToken.ThrowIfCancellationRequested();
File.Copy(sourceCertificatePath, destinationPath, overwrite: true);
string sourceHash = ComputeSha256(sourceCertificatePath);
string destHash = ComputeSha256(destinationPath);
if (!string.Equals(sourceHash, destHash, StringComparison.OrdinalIgnoreCase))
{
RestoreFromBackupOrDelete(destinationPath, backupPath);
return (false, "Hash-Fehler", "SHA-256 von Quelle und Ziel stimmen nicht überein. Rollback ausgeführt.", backupPath);
}
return (true, "Kopiert", $"Ziel: {destinationPath}", backupPath);
}
catch (OperationCanceledException)
{
throw;
}
catch (Exception ex)
{
try
{
if (backupPath is not null && File.Exists(backupPath) && File.Exists(destinationPath))
{
File.Copy(backupPath, destinationPath, overwrite: true);
}
}
catch
{
// Rollback best-effort
}
return (false, "Kopierfehler", ex.Message, backupPath);
}
}
private static void RestoreFromBackupOrDelete(string destinationPath, string? backupPath)
{
if (backupPath is not null && File.Exists(backupPath))
{
File.Copy(backupPath, destinationPath, overwrite: true);
return;
}
if (File.Exists(destinationPath))
{
File.Delete(destinationPath);
}
}
public static string ComputeSha256(string filePath)
{
using FileStream stream = File.OpenRead(filePath);
byte[] hash = SHA256.HashData(stream);
return Convert.ToHexString(hash);
}
}