[backend/configuration] Allow configuring of parameter logging for database exceptions

This commit is contained in:
Laura Hausmann 2024-06-21 16:24:03 +02:00
parent f2e4d11ce4
commit 3e0a5b5759
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
4 changed files with 47 additions and 27 deletions

View file

@ -88,13 +88,14 @@ public sealed class Config
public sealed class DatabaseSection
{
[Required] public string Host { get; init; } = "localhost";
[Range(1, 65535)] public int Port { get; init; } = 5432;
[Required] public string Database { get; init; } = null!;
[Required] public string Username { get; init; } = null!;
public string? Password { get; init; }
[Range(1, 1000)] public int MaxConnections { get; init; } = 100;
public bool Multiplexing { get; init; } = false;
[Required] public string Host { get; init; } = "localhost";
[Range(1, 65535)] public int Port { get; init; } = 5432;
[Required] public string Database { get; init; } = null!;
[Required] public string Username { get; init; } = null!;
public string? Password { get; init; }
[Range(1, 1000)] public int MaxConnections { get; init; } = 100;
public bool Multiplexing { get; init; } = false;
public bool ParameterLogging { get; init; } = false;
}
public sealed class StorageSection

View file

@ -91,25 +91,28 @@ public class DatabaseContext(DbContextOptions<DatabaseContext> options)
public virtual DbSet<Filter> Filters { get; init; } = null!;
public virtual DbSet<DataProtectionKey> DataProtectionKeys { get; init; } = null!;
public static NpgsqlDataSource GetDataSource(Config.DatabaseSection? config)
public static NpgsqlDataSource GetDataSource(Config.DatabaseSection config)
{
var dataSourceBuilder = new NpgsqlDataSourceBuilder();
var dataSourceBuilder = new NpgsqlDataSourceBuilder
{
ConnectionStringBuilder =
{
Host = config.Host,
Port = config.Port,
Username = config.Username,
Password = config.Password,
Database = config.Database,
MaxPoolSize = config.MaxConnections,
Multiplexing = config.Multiplexing
}
};
if (config == null)
throw new Exception("Failed to initialize database: Failed to load configuration");
dataSourceBuilder.ConnectionStringBuilder.Host = config.Host;
dataSourceBuilder.ConnectionStringBuilder.Port = config.Port;
dataSourceBuilder.ConnectionStringBuilder.Username = config.Username;
dataSourceBuilder.ConnectionStringBuilder.Password = config.Password;
dataSourceBuilder.ConnectionStringBuilder.Database = config.Database;
dataSourceBuilder.ConnectionStringBuilder.MaxPoolSize = config.MaxConnections;
dataSourceBuilder.ConnectionStringBuilder.Multiplexing = config.Multiplexing;
return ConfigureDataSource(dataSourceBuilder);
return ConfigureDataSource(dataSourceBuilder, config);
}
public static NpgsqlDataSource ConfigureDataSource(NpgsqlDataSourceBuilder dataSourceBuilder)
private static NpgsqlDataSource ConfigureDataSource(
NpgsqlDataSourceBuilder dataSourceBuilder, Config.DatabaseSection config
)
{
dataSourceBuilder.MapEnum<Antenna.AntennaSource>();
dataSourceBuilder.MapEnum<Note.NoteVisibility>();
@ -125,14 +128,22 @@ public class DatabaseContext(DbContextOptions<DatabaseContext> options)
dataSourceBuilder.EnableDynamicJson();
if (config.ParameterLogging)
dataSourceBuilder.EnableParameterLogging();
return dataSourceBuilder.Build();
}
public static void Configure(DbContextOptionsBuilder optionsBuilder, NpgsqlDataSource dataSource)
public static void Configure(
DbContextOptionsBuilder optionsBuilder, NpgsqlDataSource dataSource, Config.DatabaseSection config
)
{
optionsBuilder.UseNpgsql(dataSource);
optionsBuilder.UseProjectables(options => { options.CompatibilityMode(CompatibilityMode.Full); });
optionsBuilder.UseExceptionProcessor();
if (config.ParameterLogging)
optionsBuilder.EnableSensitiveDataLogging();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
@ -1292,10 +1303,12 @@ public class DesignTimeDatabaseContextFactory : IDesignTimeDbContextFactory<Data
.AddCustomConfiguration()
.Build();
var config = configuration.GetSection("Database").Get<Config.DatabaseSection>();
var config = configuration.GetSection("Database").Get<Config.DatabaseSection>() ??
throw new Exception("Failed to initialize database: Failed to load configuration");
var dataSource = DatabaseContext.GetDataSource(config);
var builder = new DbContextOptionsBuilder<DatabaseContext>();
DatabaseContext.Configure(builder, dataSource);
DatabaseContext.Configure(builder, dataSource, config);
return new DatabaseContext(builder.Options);
}
}

View file

@ -159,9 +159,11 @@ public static class ServiceExtensions
public static void AddDatabaseContext(this IServiceCollection services, IConfiguration configuration)
{
var config = configuration.GetSection("Database").Get<Config.DatabaseSection>();
var config = configuration.GetSection("Database").Get<Config.DatabaseSection>() ??
throw new Exception("Failed to initialize database: Failed to load configuration");
var dataSource = DatabaseContext.GetDataSource(config);
services.AddDbContext<DatabaseContext>(options => { DatabaseContext.Configure(options, dataSource); });
services.AddDbContext<DatabaseContext>(options => { DatabaseContext.Configure(options, dataSource, config); });
services.AddKeyedDatabaseContext<DatabaseContext>("cache");
services.AddDataProtection()
.PersistKeysToDbContextAsync<DatabaseContext>()

View file

@ -102,6 +102,10 @@ MaxConnections = 100
;; Whether to enable connection multiplexing, which allows for more efficient use of the connection pool.
Multiplexing = false
;; Whether to log parameter information on errors.
;; Caution: this may contain sensitive information, it's recommended to keep this disabled except for debugging purposes
ParameterLogging = false
[Storage]
;; Where to store media attachments
;; Options: [Local, ObjectStorage]