using Microsoft.Extensions.Configuration;
namespace QRRapidoApp.Configuration
{
///
/// Configuration provider that reads Docker Secrets from /run/secrets/
/// Secrets are mounted as files in Swarm mode.
///
public class DockerSecretsConfigurationProvider : ConfigurationProvider
{
private readonly string _secretsPath;
private readonly Dictionary _secretKeyMappings;
public DockerSecretsConfigurationProvider(string secretsPath, Dictionary secretKeyMappings)
{
_secretsPath = secretsPath;
_secretKeyMappings = secretKeyMappings;
}
public override void Load()
{
Data = new Dictionary(StringComparer.OrdinalIgnoreCase);
if (!Directory.Exists(_secretsPath))
{
return;
}
var secretsLoaded = 0;
foreach (var mapping in _secretKeyMappings)
{
var secretFileName = mapping.Key;
var configKey = mapping.Value;
var secretFilePath = Path.Combine(_secretsPath, secretFileName);
if (File.Exists(secretFilePath))
{
try
{
var secretValue = (string?)File.ReadAllText(secretFilePath).Trim();
if (!string.IsNullOrEmpty(secretValue))
{
Data[configKey] = secretValue;
secretsLoaded++;
}
}
catch (Exception)
{
// Silently ignore read errors - will fall back to other config sources
}
}
}
// Set indicator that secrets were loaded from Docker
if (secretsLoaded > 0)
{
Data["App:SecretsLoaded"] = "true";
}
}
}
public class DockerSecretsConfigurationSource : IConfigurationSource
{
public string SecretsPath { get; set; } = "/run/secrets";
public Dictionary SecretKeyMappings { get; set; } = new();
public IConfigurationProvider Build(IConfigurationBuilder builder)
{
return new DockerSecretsConfigurationProvider(SecretsPath, SecretKeyMappings);
}
}
public static class DockerSecretsConfigurationExtensions
{
///
/// Adds Docker Secrets as a configuration source.
/// Maps secret file names to configuration keys.
///
public static IConfigurationBuilder AddDockerSecrets(
this IConfigurationBuilder builder,
Action? configure = null)
{
var source = new DockerSecretsConfigurationSource
{
// Default mappings for QRRapido secrets
SecretKeyMappings = new Dictionary
{
// Stripe
["stripe_secret_key"] = "Stripe:SecretKey",
["stripe_webhook_secret"] = "Stripe:WebhookSecret",
// MongoDB
["mongodb_connection_string"] = "ConnectionStrings:MongoDB",
// OAuth - Google
["google_client_id"] = "Authentication:Google:ClientId",
["google_client_secret"] = "Authentication:Google:ClientSecret",
// OAuth - Microsoft
["microsoft_client_id"] = "Authentication:Microsoft:ClientId",
["microsoft_client_secret"] = "Authentication:Microsoft:ClientSecret",
}
};
configure?.Invoke(source);
builder.Add(source);
return builder;
}
}
}