Compare commits

..

8 Commits

Author SHA1 Message Date
khwezi a763e5e40e Merge pull request 'Added certificate protected data protection keys' (#124) from dataprotection into master
Reviewed-on: #124
2026-06-14 11:27:32 +02:00
Khwezi Mngoma 9b15e296df Added certificate protected data protection keys
continuous-integration/drone/pr Build is passing
2026-06-14 11:26:20 +02:00
khwezi 1ef5e52ed9 Merge pull request 'Refactored AddDataProtectionDatabase' (#123) from dataprotection into master
Reviewed-on: #123
2026-06-14 10:12:08 +02:00
Khwezi Mngoma f4a615277f Refactored AddDataProtectionDatabase
continuous-integration/drone/pr Build is passing
2026-06-14 10:11:25 +02:00
khwezi c06cf13add Merge pull request 'Added data protection database based support' (#122) from dataprotection into master
Reviewed-on: #122
2026-06-14 09:58:17 +02:00
Khwezi Mngoma 4e9e428ab5 Added data protection database based support
continuous-integration/drone/pr Build is passing
2026-06-14 09:57:24 +02:00
khwezi 92c60e6616 Merge pull request 'Refactored AddLiteCharmsWebSecurity to be OS aware when it handles data protection keys' (#121) from dataprotection into master
Reviewed-on: #121
2026-06-13 23:41:30 +02:00
Khwezi Mngoma 9099610185 Refactored AddLiteCharmsWebSecurity to be OS aware when it handles data protection keys
continuous-integration/drone/pr Build is passing
2026-06-13 23:41:02 +02:00
8 changed files with 192 additions and 6 deletions
+8 -4
View File
@@ -2,6 +2,10 @@
using LiteCharms.Features.Api; using LiteCharms.Features.Api;
using LiteCharms.Features.Api.Configuration; using LiteCharms.Features.Api.Configuration;
using LiteCharms.Features.Api.Sdk; using LiteCharms.Features.Api.Sdk;
using LiteCharms.Features.Postgres;
using Microsoft.AspNetCore.Hosting;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;
namespace LiteCharms.Features.Extensions; namespace LiteCharms.Features.Extensions;
@@ -53,11 +57,11 @@ public static class Api
public static IServiceCollection AddLiteCharmsWebSecurity(this IServiceCollection services, IConfiguration configuration) public static IServiceCollection AddLiteCharmsWebSecurity(this IServiceCollection services, IConfiguration configuration)
{ {
var keysFolder = Path.Combine("/app/shared-keys"); var certificate = X509CertificateLoader.LoadPkcs12(Convert.FromBase64String(configuration["DataProtection:Certificate"]!), configuration["DataProtection:Password"]);
services.AddDataProtection() services.AddDataProtection().PersistKeysToDbContext<DataProtectionDbContext>()
.PersistKeysToFileSystem(new DirectoryInfo(keysFolder)) .ProtectKeysWithCertificate(certificate)
.SetApplicationName("MidrandBooks"); .SetApplicationName("LiteCharmsApp");
var configSection = configuration.GetSection(nameof(LiteCharmsSettings)); var configSection = configuration.GetSection(nameof(LiteCharmsSettings));
+14 -1
View File
@@ -1,6 +1,19 @@
namespace LiteCharms.Features.Extensions; using LiteCharms.Features.Postgres;
namespace LiteCharms.Features.Extensions;
public static class Postgres public static class Postgres
{ {
public const string SchedulerDbConfigName = "PostgresScheduler"; public const string SchedulerDbConfigName = "PostgresScheduler";
public const string DataProtectionDbConfigName = "PostgresDataProtection";
public static IServiceCollection AddDataProtectionDatabase(this IServiceCollection services, IConfiguration configuration)
{
var connectionString = configuration.GetConnectionString(DataProtectionDbConfigName);
services.AddPooledDbContextFactory<DataProtectionDbContext>(options =>
options.UseNpgsql(connectionString));
return services;
}
} }
@@ -153,9 +153,11 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.2" /> <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.2" />
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" Version="10.0.9" />
<!-- Global Usings --> <!-- Global Usings -->
<Using Include="Npgsql" /> <Using Include="Npgsql" />
<Using Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" />
<Using Include="Microsoft.EntityFrameworkCore" /> <Using Include="Microsoft.EntityFrameworkCore" />
<Using Include="Microsoft.EntityFrameworkCore.Design" /> <Using Include="Microsoft.EntityFrameworkCore.Design" />
<Using Include="Microsoft.EntityFrameworkCore.Metadata.Builders" /> <Using Include="Microsoft.EntityFrameworkCore.Metadata.Builders" />
@@ -0,0 +1,13 @@
namespace LiteCharms.Features.Postgres;
public class DataProtectionDbContext(DbContextOptions<DataProtectionDbContext> options) : DbContext(options), IDataProtectionKeyContext
{
public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<DataProtectionKey>(entity => entity.ToTable(nameof(DataProtectionKeys), schema: "security"));
}
}
@@ -0,0 +1,20 @@
using static LiteCharms.Features.Extensions.Postgres;
namespace LiteCharms.Features.Postgres;
public class DataProtectionDbContextFactory : IDesignTimeDbContextFactory<DataProtectionDbContext>
{
public DataProtectionDbContext CreateDbContext(string[] args)
{
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddUserSecrets(typeof(DataProtectionDbContext).Assembly)
.AddEnvironmentVariables()
.Build();
var optionsBuilder = new DbContextOptionsBuilder<DataProtectionDbContext>();
optionsBuilder.UseNpgsql(configuration.GetConnectionString(DataProtectionDbConfigName));
return new DataProtectionDbContext(optionsBuilder.Options);
}
}
@@ -0,0 +1,48 @@
// <auto-generated />
using LiteCharms.Features.Postgres;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace LiteCharms.Features.Postgres.Migrations
{
[DbContext(typeof(DataProtectionDbContext))]
[Migration("20260614075149_Init")]
partial class Init
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("FriendlyName")
.HasColumnType("text");
b.Property<string>("Xml")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("DataProtectionKeys", "security");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,41 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace LiteCharms.Features.Postgres.Migrations
{
/// <inheritdoc />
public partial class Init : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.EnsureSchema(
name: "security");
migrationBuilder.CreateTable(
name: "DataProtectionKeys",
schema: "security",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
FriendlyName = table.Column<string>(type: "text", nullable: true),
Xml = table.Column<string>(type: "text", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_DataProtectionKeys", x => x.Id);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "DataProtectionKeys",
schema: "security");
}
}
}
@@ -0,0 +1,45 @@
// <auto-generated />
using LiteCharms.Features.Postgres;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace LiteCharms.Features.Postgres.Migrations
{
[DbContext(typeof(DataProtectionDbContext))]
partial class DataProtectionDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "10.0.9")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("FriendlyName")
.HasColumnType("text");
b.Property<string>("Xml")
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("DataProtectionKeys", "security");
});
#pragma warning restore 612, 618
}
}
}