- Add ReactivatePipeline to handle subscription reactivation, including scaling Docker services, health verification, status updates, audit logging, and broadcasting status changes. - Introduce RotateCredentialsPipeline for OAuth2 credential rotation, managing the deletion of old apps, creation of new ones, credential storage, access verification, and audit logging. - Create StepRunner to manage job step execution, including lifecycle management and progress broadcasting via SignalR. - Implement SuspendPipeline for subscription suspension, scaling down services, updating statuses, logging audits, and broadcasting changes. - Add UpdateScreenLimitPipeline to update Xibo CMS screen limits and record snapshots. - Introduce XiboFeatureManifests for hardcoded feature ACLs per role. - Add docker-compose.dev.yml for local development with PostgreSQL setup.
61 lines
2.1 KiB
C#
61 lines
2.1 KiB
C#
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}");
|
|
}
|
|
}
|
|
}
|