Files
OTSSignsOrchestrator/OTSSignsOrchestrator.Server/Health/Checks/AuthentikSamlProviderHealthCheck.cs

61 lines
2.1 KiB
C#
Raw Normal View History

using OTSSignsOrchestrator.Server.Clients;
using OTSSignsOrchestrator.Server.Data.Entities;
namespace OTSSignsOrchestrator.Server.Health.Checks;
/// <summary>
/// Verifies the per-instance SAML provider in Authentik is active by checking
/// the provider exists using the stored <see cref="Instance.AuthentikProviderId"/>.
/// </summary>
public sealed class AuthentikSamlProviderHealthCheck : IHealthCheck
{
private readonly IAuthentikClient _authentikClient;
private readonly ILogger<AuthentikSamlProviderHealthCheck> _logger;
public string CheckName => "AuthentikSamlProvider";
public bool AutoRemediate => false;
public AuthentikSamlProviderHealthCheck(
IAuthentikClient authentikClient,
ILogger<AuthentikSamlProviderHealthCheck> logger)
{
_authentikClient = authentikClient;
_logger = logger;
}
public async Task<HealthCheckResult> RunAsync(Instance instance, CancellationToken ct)
{
if (string.IsNullOrEmpty(instance.AuthentikProviderId))
{
return new HealthCheckResult(HealthStatus.Degraded,
"No Authentik provider ID stored — SAML not provisioned");
}
if (!int.TryParse(instance.AuthentikProviderId, out var providerId))
{
return new HealthCheckResult(HealthStatus.Critical,
$"Invalid Authentik provider ID: {instance.AuthentikProviderId}");
}
try
{
var response = await _authentikClient.GetSamlProviderAsync(providerId);
if (response.IsSuccessStatusCode && response.Content is not null)
{
return new HealthCheckResult(HealthStatus.Healthy,
$"SAML provider {providerId} is active in Authentik");
}
return new HealthCheckResult(HealthStatus.Critical,
$"SAML provider {providerId} not found or inaccessible",
response.Error?.Content);
}
catch (Exception ex)
{
return new HealthCheckResult(HealthStatus.Critical,
$"Failed to check SAML provider: {ex.Message}");
}
}
}