Reworked code around signing keys have key details much more isolated from the other parts of the program.

This commit is contained in:
eelke 2026-02-21 20:15:46 +01:00
parent eb872a4f44
commit 0c6f227049
40 changed files with 474 additions and 281 deletions

View file

@ -30,4 +30,8 @@
<ProjectReference Include="..\IdentityShroud.TestUtils\IdentityShroud.TestUtils.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Model\" />
</ItemGroup>
</Project>

View file

@ -1,51 +0,0 @@
using IdentityShroud.Core.Contracts;
using IdentityShroud.Core.Model;
namespace IdentityShroud.Core.Tests.Model;
public class RealmKeyTests
{
[Fact]
public void SetNewKey()
{
byte[] privateKey = [5, 6, 7, 8];
byte[] encryptedPrivateKey = [1, 2, 3, 4];
var encryptionService = Substitute.For<IEncryptionService>();
encryptionService
.Encrypt(Arg.Any<byte[]>())
.Returns(x => encryptedPrivateKey);
RealmKey realmKey = new();
realmKey.SetPrivateKey(encryptionService, privateKey);
// should be able to return original without calling decrypt
Assert.Equal(privateKey, realmKey.GetPrivateKey(encryptionService));
Assert.Equal(encryptedPrivateKey, realmKey.PrivateKeyEncrypted);
encryptionService.Received(1).Encrypt(privateKey);
encryptionService.DidNotReceive().Decrypt(Arg.Any<byte[]>());
}
[Fact]
public void GetDecryptedKey()
{
byte[] privateKey = [5, 6, 7, 8];
byte[] encryptedPrivateKey = [1, 2, 3, 4];
var encryptionService = Substitute.For<IEncryptionService>();
encryptionService
.Decrypt(encryptedPrivateKey)
.Returns(x => privateKey);
RealmKey realmKey = new();
realmKey.PrivateKeyEncrypted = encryptedPrivateKey;
// should be able to return original without calling decrypt
Assert.Equal(privateKey, realmKey.GetPrivateKey(encryptionService));
Assert.Equal(encryptedPrivateKey, realmKey.PrivateKeyEncrypted);
encryptionService.Received(1).Decrypt(encryptedPrivateKey);
}
}

View file

@ -1,4 +1,6 @@
using IdentityShroud.Core.Contracts;
using IdentityShroud.Core.Model;
using IdentityShroud.Core.Security.Keys;
using IdentityShroud.Core.Services;
using IdentityShroud.Core.Tests.Fixtures;
using IdentityShroud.TestUtils.Substitutes;
@ -9,7 +11,7 @@ namespace IdentityShroud.Core.Tests.Services;
public class RealmServiceTests : IClassFixture<DbFixture>
{
private readonly DbFixture _dbFixture;
private readonly IEncryptionService _encryptionService = EncryptionServiceSubstitute.CreatePassthrough();
private readonly IKeyService _keyService = Substitute.For<IKeyService>();
public RealmServiceTests(DbFixture dbFixture)
{
@ -34,25 +36,37 @@ public class RealmServiceTests : IClassFixture<DbFixture>
if (idString is not null)
realmId = new(idString);
using Db db = _dbFixture.CreateDbContext();
RealmService sut = new(db, _encryptionService);
// Act
var response = await sut.Create(
new(realmId, "slug", "New realm"),
TestContext.Current.CancellationToken);
// Verify
RealmCreateResponse val = ResultAssert.Success(response);
if (realmId.HasValue)
Assert.Equal(realmId, val.Id);
else
Assert.NotEqual(Guid.Empty, val.Id);
Assert.Equal("slug", val.Slug);
Assert.Equal("New realm", val.Name);
// TODO verify data has been stored!
RealmCreateResponse? val;
await using (var db = _dbFixture.CreateDbContext())
{
_keyService.CreateKey(Arg.Any<KeyPolicy>())
.Returns(new RealmKey(Guid.NewGuid(), "TST", [21], DateTime.UtcNow));
// Act
RealmService sut = new(db, _keyService);
var response = await sut.Create(
new(realmId, "slug", "New realm"),
TestContext.Current.CancellationToken);
// Verify
val = ResultAssert.Success(response);
if (realmId.HasValue)
Assert.Equal(realmId, val.Id);
else
Assert.NotEqual(Guid.Empty, val.Id);
Assert.Equal("slug", val.Slug);
Assert.Equal("New realm", val.Name);
_keyService.Received().CreateKey(Arg.Any<KeyPolicy>());
}
await using (var db = _dbFixture.CreateDbContext())
{
var dbRecord = await db.Realms
.Include(e => e.Keys)
.SingleAsync(e => e.Id == val.Id, TestContext.Current.CancellationToken);
Assert.Equal("TST", dbRecord.Keys[0].KeyType);
}
}
[Theory]
@ -60,7 +74,7 @@ public class RealmServiceTests : IClassFixture<DbFixture>
[InlineData("foo", "Foo")]
public async Task FindBySlug(string slug, string? name)
{
using (var setupContext = _dbFixture.CreateDbContext())
await using (var setupContext = _dbFixture.CreateDbContext())
{
setupContext.Realms.Add(new()
{
@ -76,8 +90,8 @@ public class RealmServiceTests : IClassFixture<DbFixture>
await setupContext.SaveChangesAsync(TestContext.Current.CancellationToken);
}
using Db actContext = _dbFixture.CreateDbContext();
RealmService sut = new(actContext, _encryptionService);
await using var actContext = _dbFixture.CreateDbContext();
RealmService sut = new(actContext, _keyService);
// Act
var result = await sut.FindBySlug(slug, TestContext.Current.CancellationToken);