Switch Owned value types to ComplexProperty which is better fit.
This requires fluent configuration. Also made some conversion registration context wide.
This commit is contained in:
parent
07393f57fc
commit
1a8c63808a
11 changed files with 93 additions and 54 deletions
12
IdentityShroud.Core/EFCore/Converters/DekIdConverter.cs
Normal file
12
IdentityShroud.Core/EFCore/Converters/DekIdConverter.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using IdentityShroud.Core.Security;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace IdentityShroud.Core;
|
||||
|
||||
public class DekIdConverter : ValueConverter<DekId, Guid>
|
||||
{
|
||||
public DekIdConverter()
|
||||
: base(id => id.Id, guid => new DekId(guid))
|
||||
{
|
||||
}
|
||||
}
|
||||
12
IdentityShroud.Core/EFCore/Converters/KekIdConverter.cs
Normal file
12
IdentityShroud.Core/EFCore/Converters/KekIdConverter.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using IdentityShroud.Core.Security;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
namespace IdentityShroud.Core;
|
||||
|
||||
public class KekIdConverter : ValueConverter<KekId, Guid>
|
||||
{
|
||||
public KekIdConverter()
|
||||
: base(id => id.Id, guid => new KekId(guid))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using System.Linq.Expressions;
|
||||
using IdentityShroud.Core.Model;
|
||||
using IdentityShroud.Core.Security;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
|
|
@ -23,39 +23,6 @@ public class Db(
|
|||
public virtual DbSet<RealmKey> Keys { get; set; }
|
||||
public virtual DbSet<RealmDek> Deks { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
var dekIdConverter = new ValueConverter<DekId, Guid>(
|
||||
id => id.Id,
|
||||
guid => new DekId(guid));
|
||||
|
||||
var kekIdConverter = new ValueConverter<KekId, Guid>(
|
||||
id => id.Id,
|
||||
guid => new KekId(guid));
|
||||
|
||||
modelBuilder.Entity<RealmDek>()
|
||||
.Property(d => d.Id)
|
||||
.HasConversion(dekIdConverter);
|
||||
|
||||
modelBuilder.Entity<RealmDek>()
|
||||
.OwnsOne(d => d.KeyData, keyData =>
|
||||
{
|
||||
keyData.Property(k => k.KekId).HasConversion(kekIdConverter);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<RealmKey>()
|
||||
.OwnsOne(k => k.Key, key =>
|
||||
{
|
||||
key.Property(k => k.KekId).HasConversion(kekIdConverter);
|
||||
});
|
||||
|
||||
modelBuilder.Entity<ClientSecret>()
|
||||
.OwnsOne(c => c.Secret, secret =>
|
||||
{
|
||||
secret.Property(s => s.DekId).HasConversion(dekIdConverter);
|
||||
});
|
||||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
optionsBuilder.UseNpgsql("<connection string>");
|
||||
|
|
@ -71,6 +38,18 @@ public class Db(
|
|||
{
|
||||
optionsBuilder.UseLoggerFactory(loggerFactory);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.ApplyConfigurationsFromAssembly(typeof(Db).Assembly);
|
||||
}
|
||||
|
||||
protected override void ConfigureConventions(ModelConfigurationBuilder b)
|
||||
{
|
||||
base.ConfigureConventions(b);
|
||||
|
||||
b.Properties<DekId>().HaveConversion<DekIdConverter>();
|
||||
b.Properties<KekId>().HaveConversion<KekIdConverter>();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=efcore_005Cconverters/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
||||
|
|
@ -2,6 +2,8 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using IdentityShroud.Core.Contracts;
|
||||
using IdentityShroud.Core.Security;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace IdentityShroud.Core.Model;
|
||||
|
||||
|
|
@ -13,5 +15,15 @@ public class ClientSecret
|
|||
public Guid ClientId { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime? RevokedAt { get; set; }
|
||||
public required EncryptedValue Secret { get; set; }
|
||||
public EncryptedValue? Secret { get; set; }
|
||||
}
|
||||
|
||||
public class ClientSecretConfiguration : IEntityTypeConfiguration<ClientSecret>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<ClientSecret> b)
|
||||
{
|
||||
b.ToTable("client_secret");
|
||||
b.HasKey(e => e.Id);
|
||||
b.ComplexProperty(e => e.Secret);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using IdentityShroud.Core.Security;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace IdentityShroud.Core.Model;
|
||||
|
||||
[Table("realm")]
|
||||
public class Realm
|
||||
{
|
||||
|
||||
public Guid Id { get; set; }
|
||||
/// <summary>
|
||||
/// Note this is part of the url we should encourage users to keep it short but we do not want to limit them too much
|
||||
|
|
@ -28,13 +29,3 @@ public class Realm
|
|||
/// </summary>
|
||||
public string DefaultSignatureAlgorithm { get; set; } = JsonWebAlgorithm.RS256;
|
||||
}
|
||||
|
||||
[Table("realm_dek")]
|
||||
public record RealmDek
|
||||
{
|
||||
public required DekId Id { get; init; }
|
||||
public required bool Active { get; set; }
|
||||
public required string Algorithm { get; init; }
|
||||
public required EncryptedDek KeyData { get; init; }
|
||||
public required Guid RealmId { get; init; }
|
||||
}
|
||||
|
|
|
|||
24
IdentityShroud.Core/Model/RealmDek.cs
Normal file
24
IdentityShroud.Core/Model/RealmDek.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using IdentityShroud.Core.Security;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace IdentityShroud.Core.Model;
|
||||
|
||||
public record RealmDek
|
||||
{
|
||||
public required DekId Id { get; init; }
|
||||
public required bool Active { get; set; }
|
||||
public required string Algorithm { get; init; }
|
||||
public required EncryptedDek KeyData { get; init; }
|
||||
public required Guid RealmId { get; init; }
|
||||
}
|
||||
|
||||
public class RealmDekConfiguration : IEntityTypeConfiguration<RealmDek>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<RealmDek> b)
|
||||
{
|
||||
b.ToTable("realm_dek");
|
||||
b.HasKey(e => e.Id);
|
||||
b.ComplexProperty(e => e.KeyData, e => e.IsRequired());
|
||||
}
|
||||
}
|
||||
|
|
@ -2,17 +2,14 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
using IdentityShroud.Core.Contracts;
|
||||
using IdentityShroud.Core.Security;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace IdentityShroud.Core.Model;
|
||||
|
||||
|
||||
[Table("realm_key")]
|
||||
public record RealmKey
|
||||
{
|
||||
public required Guid Id { get; init; }
|
||||
public required string KeyType { get; init; }
|
||||
|
||||
|
||||
public required EncryptedDek Key { get; init; }
|
||||
public required DateTime CreatedAt { get; init; }
|
||||
public DateTime? RevokedAt { get; set; }
|
||||
|
|
@ -22,6 +19,15 @@ public record RealmKey
|
|||
/// are more comfortable replacing keys by using priority then directly deactivating the old key.
|
||||
/// </summary>
|
||||
public int Priority { get; set; } = 10;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class RealmKeyConfiguration : IEntityTypeConfiguration<RealmKey>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<RealmKey> b)
|
||||
{
|
||||
b.ToTable("realm_key");
|
||||
b.HasKey(e => e.Id);
|
||||
|
||||
b.ComplexProperty(e => e.Key, e => e.IsRequired());
|
||||
}
|
||||
}
|
||||
|
|
@ -2,5 +2,4 @@ using Microsoft.EntityFrameworkCore;
|
|||
|
||||
namespace IdentityShroud.Core.Security;
|
||||
|
||||
[Owned]
|
||||
public record EncryptedDek(KekId KekId, byte[] Value);
|
||||
|
|
@ -2,7 +2,6 @@ using Microsoft.EntityFrameworkCore;
|
|||
|
||||
namespace IdentityShroud.Core.Security;
|
||||
|
||||
[Owned]
|
||||
public record EncryptedValue(DekId DekId, byte[] Value);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@
|
|||
|
||||
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/DotNetCliExePath/@EntryValue">/home/eelke/.dotnet/dotnet</s:String>
|
||||
<s:String x:Key="/Default/Environment/Hierarchy/Build/BuildTool/CustomBuildToolPath/@EntryValue">/home/eelke/.dotnet/sdk/10.0.102/MSBuild.dll</s:String>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=c1fa4888_002D88fd_002D4859_002D8288_002D37c12fb8ef13/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<Solution />
|
||||
</SessionState></s:String>
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=ead9ca22_002Dfc70_002D4ddf_002Db4c7_002D534498815537/@EntryIndexedValue"><SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
|
||||
<Solution />
|
||||
</SessionState></s:String>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue