refactor(securestore): store entire connection strings in SecureStore

Eliminates placeholder substitution (${KEY}) in favor of storing complete
connection strings as single encrypted values. SecureStore now auto-creates
entries for all connection strings defined in appsettings. ConfigManager
editor reads/writes values directly to SecureStore.
This commit is contained in:
Joseph Doherty
2026-01-23 14:44:04 -05:00
parent ba54a87be5
commit bfc1c8064a
16 changed files with 462 additions and 279 deletions
@@ -1,7 +1,7 @@
using JdeScoping.Core.Interfaces;
using JdeScoping.DataAccess.Exceptions;
using JdeScoping.DataAccess.Interfaces;
using Microsoft.Data.SqlClient;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Oracle.ManagedDataAccess.Client;
@@ -9,35 +9,29 @@ namespace JdeScoping.DataAccess;
/// <summary>
/// Factory for creating database connections to all data sources.
/// Retrieves connection strings from SecureStore.
/// </summary>
public class DbConnectionFactory : IDbConnectionFactory
{
private readonly IConfiguration _configuration;
private readonly ISecureStoreService _secureStore;
private readonly ILogger<DbConnectionFactory> _logger;
/// <summary>
/// Initializes a new instance of the <see cref="DbConnectionFactory"/> class.
/// </summary>
/// <param name="configuration">Application configuration.</param>
/// <param name="secureStore">SecureStore service for retrieving connection strings.</param>
/// <param name="logger">Logger instance.</param>
public DbConnectionFactory(IConfiguration configuration, ILogger<DbConnectionFactory> logger)
public DbConnectionFactory(ISecureStoreService secureStore, ILogger<DbConnectionFactory> logger)
{
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));
_secureStore = secureStore ?? throw new ArgumentNullException(nameof(secureStore));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
/// <inheritdoc/>
public async Task<SqlConnection> CreateLotFinderConnectionAsync(CancellationToken ct = default)
{
const string dataSource = "LotFinderDB";
var connectionString = _configuration.GetConnectionString(dataSource);
if (string.IsNullOrEmpty(connectionString))
{
throw new ConnectionException(
$"{dataSource}: Connection string not found in configuration.",
dataSource);
}
const string dataSource = "LotFinder";
var connectionString = GetConnectionString(dataSource);
try
{
@@ -93,17 +87,24 @@ public class DbConnectionFactory : IDbConnectionFactory
return await CreateOracleConnectionAsync("GIW", ct).ConfigureAwait(false);
}
private async Task<OracleConnection> CreateOracleConnectionAsync(string dataSource, CancellationToken ct)
private string GetConnectionString(string dataSource)
{
var connectionString = _configuration.GetConnectionString(dataSource);
var connectionString = _secureStore.Get(dataSource);
if (string.IsNullOrEmpty(connectionString))
{
throw new ConnectionException(
$"{dataSource}: Connection string not found in configuration.",
$"{dataSource}: Connection string not found in SecureStore. Use ConfigManager to configure the connection string.",
dataSource);
}
return connectionString;
}
private async Task<OracleConnection> CreateOracleConnectionAsync(string dataSource, CancellationToken ct)
{
var connectionString = GetConnectionString(dataSource);
try
{
_logger.LogDebug("Creating connection to {DataSource}", dataSource);