Skip to content

Commit 1f7ef34

Browse files
committed
FUND-2062 Moved to separate project DataProtectionKeyDbContext. Moved MNIgration under the same schema
1 parent bb8b7a6 commit 1f7ef34

18 files changed

Lines changed: 837 additions & 37 deletions

getting-started/docker-compose/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ services:
385385
ASPNETCORE_URLS: "http://*:${ASPNETCORE_INTERNAL_PORT}"
386386
ConnectionStrings__UserConnectionString: "Host=${POSTGRES_HOST};Port=${POSTGRES_PORT};Database=${POSTGRES_ZRC_DB};Username=${POSTGRES_USER};Password=${POSTGRES_USER_PASSWORD}"
387387
ConnectionStrings__AdminConnectionString: "Host=${POSTGRES_HOST};Port=${POSTGRES_PORT};Database=${POSTGRES_ZRC_DB};Username=${POSTGRES_ADMIN};Password=${POSTGRES_ADMIN_PASSWORD}"
388+
ConnectionStrings__DataProtectionConnectionString: "Host=${POSTGRES_HOST};Port=${POSTGRES_PORT};Database=${POSTGRES_ZRC_DB};Username=${POSTGRES_ADMIN};Password=${POSTGRES_ADMIN_PASSWORD}"
388389
networks:
389390
- oneground
390391

localdev/README.md

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -231,23 +231,20 @@ DataProtection__Certificate=<base64-encoded-pfx>
231231
DataProtection__CertificatePassword=<pfx-password>
232232
```
233233
234-
To generate a self-signed certificate:
234+
Use the provided generator script to create a certificate. Run the following commands **from the `localdev` directory**. The script outputs the values ready to paste into `default.env`:
235+
236+
**Linux/macOS:**
235237
236238
```bash
237-
# Generate cert + key
238-
openssl req -x509 -newkey rsa:4096 \
239-
-keyout dp-key.pem -out dp-cert.pem \
240-
-sha256 -days 3650 -nodes \
241-
-subj "/CN=OneGround-DataProtection"
242-
243-
# Convert to PFX
244-
openssl pkcs12 -export \
245-
-in dp-cert.pem -inkey dp-key.pem \
246-
-out dataprotection.pfx \
247-
-passout pass:YourStrongPassword
248-
249-
# Base64 encode
250-
base64 -w 0 dataprotection.pfx
239+
chmod +x ../tools/oneground-certificates-generator/generate-dataprotection-certificate.sh
240+
../tools/oneground-certificates-generator/generate-dataprotection-certificate.sh
241+
```
242+
243+
**Windows (PowerShell):**
244+
245+
```powershell
246+
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
247+
..\tools\oneground-certificates-generator\generate-dataprotection-certificate.ps1
251248
```
252249
253250
> **Warning**: If the certificate is lost, all encrypted data in the database becomes permanently unreadable. Always back up the PFX file.

localdev/docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ services:
407407
ASPNETCORE_URLS: "http://*:${ASPNETCORE_INTERNAL_PORT}"
408408
ConnectionStrings__UserConnectionString: "Host=${POSTGRES_HOST};Port=${POSTGRES_PORT};Database=${POSTGRES_ZRC_DB};Username=${POSTGRES_USER};Password=${POSTGRES_USER_PASSWORD}"
409409
ConnectionStrings__AdminConnectionString: "Host=${POSTGRES_HOST};Port=${POSTGRES_PORT};Database=${POSTGRES_ZRC_DB};Username=${POSTGRES_ADMIN};Password=${POSTGRES_ADMIN_PASSWORD}"
410+
ConnectionStrings__DataProtectionConnectionString: "Host=${POSTGRES_HOST};Port=${POSTGRES_PORT};Database=${POSTGRES_ZRC_DB};Username=${POSTGRES_ADMIN};Password=${POSTGRES_ADMIN_PASSWORD}"
410411
networks:
411412
- oneground
412413

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Microsoft.AspNetCore.Builder;
4+
using Microsoft.EntityFrameworkCore;
5+
using Microsoft.Extensions.Configuration;
6+
using Microsoft.Extensions.DependencyInjection;
7+
8+
namespace OneGround.ZGW.Common.DataProtection.DataModel;
9+
10+
public static class DataProtectionDbContextExtensions
11+
{
12+
public static IServiceCollection AddDataProtectionDbContext(this IServiceCollection services, IConfiguration configuration)
13+
{
14+
var connectionString = configuration.GetConnectionString("DataProtectionConnectionString");
15+
if (string.IsNullOrWhiteSpace(connectionString))
16+
throw new InvalidOperationException(
17+
"No valid 'DataProtectionConnectionString' specified in ConnectionStrings."
18+
);
19+
20+
services.AddDbContext<DataProtectionKeyDbContext>(dbContextOptionsBuilder =>
21+
{
22+
dbContextOptionsBuilder.UseNpgsql(connectionString, o => o.MigrationsHistoryTable("__EFMigrationsHistory", "data_protection"));
23+
});
24+
25+
return services;
26+
}
27+
28+
/// <summary>
29+
/// Migrates the DataProtection database schema eagerly during startup.
30+
/// Must be called before app.Run() to ensure the schema exists before ASP.NET DataProtection reads keys.
31+
/// </summary>
32+
public static async Task MigrateDataProtectionDatabaseAsync(this WebApplication app)
33+
{
34+
using var scope = app.Services.CreateScope();
35+
await scope.ServiceProvider.GetRequiredService<DataProtectionKeyDbContext>().Database.MigrateAsync();
36+
}
37+
}

src/OneGround.ZGW.Zaken.DataModel/DataProtectionKeyDbContext.cs renamed to src/OneGround.ZGW.Common.DataProtection.DataModel/DataProtectionKeyDbContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore;
22
using Microsoft.EntityFrameworkCore;
33

4-
namespace OneGround.ZGW.Zaken.DataModel;
4+
namespace OneGround.ZGW.Common.DataProtection.DataModel;
55

66
public class DataProtectionKeyDbContext : DbContext, IDataProtectionKeyContext
77
{

src/OneGround.ZGW.Zaken.DataModel/DataProtectionKeyDbContextFactory.cs renamed to src/OneGround.ZGW.Common.DataProtection.DataModel/DataProtectionKeyDbContextFactory.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1+
using Microsoft.EntityFrameworkCore;
12
using Microsoft.Extensions.Configuration;
23
using OneGround.ZGW.DataAccess;
34

4-
namespace OneGround.ZGW.Zaken.DataModel;
5+
namespace OneGround.ZGW.Common.DataProtection.DataModel;
56

67
public class DataProtectionKeyDbContextFactory : BaseDbContextFactory<DataProtectionKeyDbContext>
78
{
89
public DataProtectionKeyDbContextFactory(IConfiguration configuration)
9-
: base(configuration) { }
10+
: base(configuration, "DataProtectionConnectionString") { }
1011

1112
public DataProtectionKeyDbContextFactory()
12-
: base() { }
13+
: base("DataProtectionConnectionString") { }
1314

1415
public override DataProtectionKeyDbContext CreateDbContext(string[] args)
1516
{
16-
var optionsBuilder = CreateDbContextOptionsBuilder();
17+
var optionsBuilder = new DbContextOptionsBuilder<DataProtectionKeyDbContext>();
18+
optionsBuilder.UseNpgsql(ConnectionString, o => o.MigrationsHistoryTable("__EFMigrationsHistory", "data_protection"));
1719
return new DataProtectionKeyDbContext(optionsBuilder.Options);
1820
}
1921
}

src/OneGround.ZGW.Zaken.DataModel/Migrations/DataProtectionKeyDb/20260401134941_create_data_protection_keys.Designer.cs renamed to src/OneGround.ZGW.Common.DataProtection.DataModel/Migrations/20260401134941_create_data_protection_keys.Designer.cs

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/OneGround.ZGW.Zaken.DataModel/Migrations/DataProtectionKeyDb/20260401134941_create_data_protection_keys.cs renamed to src/OneGround.ZGW.Common.DataProtection.DataModel/Migrations/20260401134941_create_data_protection_keys.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
using Microsoft.EntityFrameworkCore.Migrations;
1+
using Microsoft.EntityFrameworkCore.Migrations;
22
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
33

44
#nullable disable
55

6-
namespace OneGround.ZGW.Zaken.DataModel.Migrations.DataProtectionKeyDb
6+
namespace OneGround.ZGW.Common.DataProtection.DataModel.Migrations
77
{
88
/// <inheritdoc />
99
public partial class create_data_protection_keys : Migration

src/OneGround.ZGW.Zaken.DataModel/Migrations/DataProtectionKeyDb/DataProtectionKeyDbContextModelSnapshot.cs renamed to src/OneGround.ZGW.Common.DataProtection.DataModel/Migrations/DataProtectionKeyDbContextModelSnapshot.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
// <auto-generated />
1+
// <auto-generated />
22
using Microsoft.EntityFrameworkCore;
33
using Microsoft.EntityFrameworkCore.Infrastructure;
44
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
55
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
6-
using OneGround.ZGW.Zaken.DataModel;
6+
using OneGround.ZGW.Common.DataProtection.DataModel;
77

88
#nullable disable
99

10-
namespace OneGround.ZGW.Zaken.DataModel.Migrations.DataProtectionKeyDb
10+
namespace OneGround.ZGW.Common.DataProtection.DataModel.Migrations
1111
{
1212
[DbContext(typeof(DataProtectionKeyDbContext))]
1313
partial class DataProtectionKeyDbContextModelSnapshot : ModelSnapshot
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<AssemblyName>OneGround.ZGW.Common.DataProtection.DataModel</AssemblyName>
5+
<RootNamespace>OneGround.ZGW.Common.DataProtection.DataModel</RootNamespace>
6+
</PropertyGroup>
7+
<ItemGroup>
8+
<ProjectReference Include="..\OneGround.ZGW.DataAccess\ZGW.DataAccess.csproj" />
9+
</ItemGroup>
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.AspNetCore.DataProtection.EntityFrameworkCore" />
12+
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
13+
</ItemGroup>
14+
</Project>

0 commit comments

Comments
 (0)