mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
Make CT required in ISigningKeyStore, flow through implementations and tests
This commit is contained in:
parent
20879f18a9
commit
0789fff7ee
6 changed files with 76 additions and 65 deletions
|
|
@ -52,14 +52,15 @@ public class SigningKeyStore : ISigningKeyStore
|
|||
/// <summary>
|
||||
/// Loads all keys from store.
|
||||
/// </summary>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<SerializedKey>> LoadKeysAsync()
|
||||
public async Task<IEnumerable<SerializedKey>> LoadKeysAsync(CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("SigningKeyStore.LoadKeys");
|
||||
|
||||
var entities = await Context.Keys.Where(x => x.Use == Use)
|
||||
.AsNoTracking()
|
||||
.ToArrayAsync(CancellationTokenProvider.CancellationToken);
|
||||
.ToArrayAsync(ct);
|
||||
return entities.Select(key => new SerializedKey
|
||||
{
|
||||
Id = key.Id,
|
||||
|
|
@ -76,8 +77,9 @@ public class SigningKeyStore : ISigningKeyStore
|
|||
/// Persists new key in store.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public async Task StoreKeyAsync(SerializedKey key)
|
||||
public async Task StoreKeyAsync(SerializedKey key, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("SigningKeyStore.StoreKey");
|
||||
|
||||
|
|
@ -93,26 +95,27 @@ public class SigningKeyStore : ISigningKeyStore
|
|||
IsX509Certificate = key.IsX509Certificate
|
||||
};
|
||||
Context.Keys.Add(entity);
|
||||
await Context.SaveChangesAsync(CancellationTokenProvider.CancellationToken);
|
||||
await Context.SaveChangesAsync(ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes key from storage.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public async Task DeleteKeyAsync(string id)
|
||||
public async Task DeleteKeyAsync(string id, CT ct)
|
||||
{
|
||||
using var activity = Tracing.StoreActivitySource.StartActivity("SigningKeyStore.DeleteKey");
|
||||
|
||||
var item = await Context.Keys.Where(x => x.Use == Use && x.Id == id)
|
||||
.FirstOrDefaultAsync(CancellationTokenProvider.CancellationToken);
|
||||
.FirstOrDefaultAsync(ct);
|
||||
if (item != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Context.Keys.Remove(item);
|
||||
await Context.SaveChangesAsync(CancellationTokenProvider.CancellationToken);
|
||||
await Context.SaveChangesAsync(ct);
|
||||
}
|
||||
catch (DbUpdateConcurrencyException ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,8 +44,9 @@ public class FileSystemKeyStore : ISigningKeyStore
|
|||
/// <summary>
|
||||
/// Returns all the keys in storage.
|
||||
/// </summary>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<IEnumerable<SerializedKey>> LoadKeysAsync()
|
||||
public async Task<IEnumerable<SerializedKey>> LoadKeysAsync(CT ct)
|
||||
{
|
||||
var list = new List<SerializedKey>();
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ public class FileSystemKeyStore : ISigningKeyStore
|
|||
{
|
||||
using (var reader = new StreamReader(file.OpenRead()))
|
||||
{
|
||||
var json = await reader.ReadToEndAsync();
|
||||
var json = await reader.ReadToEndAsync(ct);
|
||||
var item = KeySerializer.Deserialize<SerializedKey>(json);
|
||||
list.Add(item);
|
||||
}
|
||||
|
|
@ -80,8 +81,9 @@ public class FileSystemKeyStore : ISigningKeyStore
|
|||
/// Persists new key in storage.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public async Task StoreKeyAsync(SerializedKey key)
|
||||
public async Task StoreKeyAsync(SerializedKey key, CT ct)
|
||||
{
|
||||
if (!_directory.Exists)
|
||||
{
|
||||
|
|
@ -91,15 +93,16 @@ public class FileSystemKeyStore : ISigningKeyStore
|
|||
var json = KeySerializer.Serialize(key);
|
||||
|
||||
var path = Path.Combine(_directory.FullName, KeyFilePrefix + key.Id + KeyFileExtension);
|
||||
await File.WriteAllTextAsync(path, json, Encoding.UTF8);
|
||||
await File.WriteAllTextAsync(path, json, Encoding.UTF8, ct);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes key from storage.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
public Task DeleteKeyAsync(string id)
|
||||
public Task DeleteKeyAsync(string id, CT ct)
|
||||
{
|
||||
var path = Path.Combine(_directory.FullName, KeyFilePrefix + id + KeyFileExtension);
|
||||
try
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ public class KeyManager : IKeyManager
|
|||
|
||||
_logger.LogTrace("Getting the current key.");
|
||||
|
||||
var (_, currentKeys) = await GetAllKeysInternalAsync();
|
||||
var (_, currentKeys) = await GetAllKeysInternalAsync(default);
|
||||
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
|
|
@ -89,20 +89,20 @@ public class KeyManager : IKeyManager
|
|||
|
||||
_logger.LogTrace("Getting all the keys.");
|
||||
|
||||
var (keys, _) = await GetAllKeysInternalAsync();
|
||||
var (keys, _) = await GetAllKeysInternalAsync(default);
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal async Task<(IEnumerable<KeyContainer> allKeys, IEnumerable<KeyContainer> signingKeys)> GetAllKeysInternalAsync()
|
||||
internal async Task<(IEnumerable<KeyContainer> allKeys, IEnumerable<KeyContainer> signingKeys)> GetAllKeysInternalAsync(CT ct = default)
|
||||
{
|
||||
var cached = true;
|
||||
var keys = await GetAllKeysFromCacheAsync();
|
||||
if (!keys.Any())
|
||||
{
|
||||
cached = false;
|
||||
keys = await GetAllKeysFromStoreAsync();
|
||||
keys = await GetAllKeysFromStoreAsync(ct: ct);
|
||||
}
|
||||
|
||||
// ensure we have all of our active signing keys
|
||||
|
|
@ -154,7 +154,7 @@ public class KeyManager : IKeyManager
|
|||
if (!signingKeysSuccess || rotationRequired)
|
||||
{
|
||||
// still need to do the work, but check if another server did the work already
|
||||
keys = await GetAllKeysFromStoreAsync();
|
||||
keys = await GetAllKeysFromStoreAsync(ct: ct);
|
||||
|
||||
if (!signingKeysSuccess)
|
||||
{
|
||||
|
|
@ -177,7 +177,7 @@ public class KeyManager : IKeyManager
|
|||
}
|
||||
|
||||
// now we know we need to create new keys
|
||||
(keys, signingKeys) = await CreateNewKeysAndAddToCacheAsync();
|
||||
(keys, signingKeys) = await CreateNewKeysAndAddToCacheAsync(ct);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -265,7 +265,7 @@ public class KeyManager : IKeyManager
|
|||
return false;
|
||||
}
|
||||
|
||||
internal async Task<KeyContainer> CreateAndStoreNewKeyAsync(SigningAlgorithmOptions alg)
|
||||
internal async Task<KeyContainer> CreateAndStoreNewKeyAsync(SigningAlgorithmOptions alg, CT ct = default)
|
||||
{
|
||||
_logger.LogTrace("Creating new key.");
|
||||
|
||||
|
|
@ -300,7 +300,7 @@ public class KeyManager : IKeyManager
|
|||
}
|
||||
|
||||
var key = _protector.Protect(container);
|
||||
await _store.StoreKeyAsync(key);
|
||||
await _store.StoreKeyAsync(key, ct);
|
||||
|
||||
_logger.LogDebug("Created and stored new key with kid {kid}.", container.Id);
|
||||
|
||||
|
|
@ -340,7 +340,7 @@ public class KeyManager : IKeyManager
|
|||
return result;
|
||||
}
|
||||
|
||||
internal async Task<IEnumerable<SerializedKey>> FilterAndDeleteRetiredKeysAsync(IEnumerable<SerializedKey> keys)
|
||||
internal async Task<IEnumerable<SerializedKey>> FilterAndDeleteRetiredKeysAsync(IEnumerable<SerializedKey> keys, CT ct = default)
|
||||
{
|
||||
var retired = keys
|
||||
.Where(x =>
|
||||
|
|
@ -365,7 +365,7 @@ public class KeyManager : IKeyManager
|
|||
{
|
||||
_logger.LogDebug("Deleting retired keys from store: {kids}", ids.Aggregate((x, y) => $"{x},{y}"));
|
||||
}
|
||||
await DeleteKeysAsync(ids);
|
||||
await DeleteKeysAsync(ids, ct);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ public class KeyManager : IKeyManager
|
|||
return result;
|
||||
}
|
||||
|
||||
internal async Task DeleteKeysAsync(IEnumerable<string> keys)
|
||||
internal async Task DeleteKeysAsync(IEnumerable<string> keys, CT ct = default)
|
||||
{
|
||||
if (keys == null || !keys.Any())
|
||||
{
|
||||
|
|
@ -382,7 +382,7 @@ public class KeyManager : IKeyManager
|
|||
|
||||
foreach (var key in keys)
|
||||
{
|
||||
await _store.DeleteKeyAsync(key);
|
||||
await _store.DeleteKeyAsync(key, ct);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -428,15 +428,15 @@ public class KeyManager : IKeyManager
|
|||
}
|
||||
}
|
||||
|
||||
internal async Task<IEnumerable<KeyContainer>> GetAllKeysFromStoreAsync(bool cache = true)
|
||||
internal async Task<IEnumerable<KeyContainer>> GetAllKeysFromStoreAsync(bool cache = true, CT ct = default)
|
||||
{
|
||||
_logger.LogTrace("Loading keys from store.");
|
||||
|
||||
var protectedKeys = await _store.LoadKeysAsync();
|
||||
var protectedKeys = await _store.LoadKeysAsync(ct);
|
||||
if (protectedKeys != null && protectedKeys.Any())
|
||||
{
|
||||
// retired keys are those that are beyond inclusion, thus we act as if they don't exist.
|
||||
protectedKeys = await FilterAndDeleteRetiredKeysAsync(protectedKeys);
|
||||
protectedKeys = await FilterAndDeleteRetiredKeysAsync(protectedKeys, ct);
|
||||
|
||||
var keys = protectedKeys.Select(x =>
|
||||
{
|
||||
|
|
@ -505,14 +505,14 @@ public class KeyManager : IKeyManager
|
|||
|
||||
|
||||
|
||||
internal async Task<(IEnumerable<KeyContainer> allKeys, IEnumerable<KeyContainer> activeKeys)> CreateNewKeysAndAddToCacheAsync()
|
||||
internal async Task<(IEnumerable<KeyContainer> allKeys, IEnumerable<KeyContainer> activeKeys)> CreateNewKeysAndAddToCacheAsync(CT ct = default)
|
||||
{
|
||||
var keys = new List<KeyContainer>();
|
||||
keys.AddRange(await _cache.GetKeysAsync() ?? Enumerable.Empty<KeyContainer>());
|
||||
|
||||
foreach (var alg in _options.KeyManagement.SigningAlgorithms)
|
||||
{
|
||||
var newKey = await CreateAndStoreNewKeyAsync(alg);
|
||||
var newKey = await CreateAndStoreNewKeyAsync(alg, ct);
|
||||
keys.Add(newKey);
|
||||
}
|
||||
|
||||
|
|
@ -527,7 +527,7 @@ public class KeyManager : IKeyManager
|
|||
if (_options.KeyManagement.InitializationSynchronizationDelay > TimeSpan.Zero)
|
||||
{
|
||||
_logger.LogTrace("All keys are new; delaying before reloading keys from store by InitializationSynchronizationDelay for {InitializationSynchronizationDelay}.", _options.KeyManagement.InitializationSynchronizationDelay);
|
||||
await Task.Delay(_options.KeyManagement.InitializationSynchronizationDelay);
|
||||
await Task.Delay(_options.KeyManagement.InitializationSynchronizationDelay, ct);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -535,7 +535,7 @@ public class KeyManager : IKeyManager
|
|||
}
|
||||
|
||||
// reload in case other new keys were recently created
|
||||
keys = new List<KeyContainer>(await GetAllKeysFromStoreAsync(false));
|
||||
keys = new List<KeyContainer>(await GetAllKeysFromStoreAsync(false, ct));
|
||||
}
|
||||
|
||||
// explicitly cache here since we didn't when we loaded above
|
||||
|
|
|
|||
|
|
@ -16,20 +16,23 @@ public interface ISigningKeyStore
|
|||
/// <summary>
|
||||
/// Returns all the keys in storage.
|
||||
/// </summary>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SerializedKey>> LoadKeysAsync();
|
||||
Task<IEnumerable<SerializedKey>> LoadKeysAsync(CT ct);
|
||||
|
||||
/// <summary>
|
||||
/// Persists new key in storage.
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
Task StoreKeyAsync(SerializedKey key);
|
||||
Task StoreKeyAsync(SerializedKey key, CT ct);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes key from storage.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="ct"></param>
|
||||
/// <returns></returns>
|
||||
Task DeleteKeyAsync(string id);
|
||||
Task DeleteKeyAsync(string id, CT ct);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ public class KeyManagerTests
|
|||
{
|
||||
private KeyManager _subject;
|
||||
|
||||
private readonly CT _ct = TestContext.Current.CancellationToken;
|
||||
|
||||
private SigningAlgorithmOptions _rsaOptions = new SigningAlgorithmOptions("RS256");
|
||||
|
||||
private IdentityServerOptions _options = new IdentityServerOptions();
|
||||
|
|
@ -131,7 +133,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var id = CreateAndStoreKey(_options.KeyManagement.PropagationTime.Add(TimeSpan.FromHours(1)));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
key.Id.ShouldBe(id);
|
||||
|
|
@ -142,7 +144,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var id = CreateAndStoreKey(TimeSpan.FromSeconds(5));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -156,7 +158,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var id = CreateAndStoreKey(-TimeSpan.FromSeconds(5));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -168,7 +170,7 @@ public class KeyManagerTests
|
|||
[Fact]
|
||||
public async Task GetAllKeysInternalAsync_when_no_keys_should_create_key()
|
||||
{
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -182,7 +184,7 @@ public class KeyManagerTests
|
|||
{
|
||||
_mockKeyStore.Keys = null;
|
||||
|
||||
var (keys, key) = await _subject.GetAllKeysInternalAsync();
|
||||
var (keys, key) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
keys.ShouldNotBeEmpty();
|
||||
}
|
||||
|
|
@ -192,7 +194,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var id = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -207,7 +209,7 @@ public class KeyManagerTests
|
|||
var id1 = CreateCacheAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
|
||||
var id2 = CreateAndStoreKey();
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -223,7 +225,7 @@ public class KeyManagerTests
|
|||
var key3 = CreateAndStoreKey(-TimeSpan.FromSeconds(5));
|
||||
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -238,7 +240,7 @@ public class KeyManagerTests
|
|||
var key1 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Subtract(TimeSpan.FromSeconds(10)));
|
||||
var key2 = CreateAndStoreKey(-TimeSpan.FromSeconds(5));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -256,7 +258,7 @@ public class KeyManagerTests
|
|||
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
|
||||
var key5 = CreateAndStoreKey(_options.KeyManagement.KeyRetirementAge.Add(TimeSpan.FromSeconds(5)));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
allKeys.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
|
||||
}
|
||||
|
|
@ -272,7 +274,7 @@ public class KeyManagerTests
|
|||
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(5)));
|
||||
var key5 = CreateAndStoreKey(_options.KeyManagement.KeyRetirementAge.Add(TimeSpan.FromSeconds(5)));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
allKeys.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
|
||||
}
|
||||
|
|
@ -282,7 +284,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var key = CreateAndStoreKey();
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
allKeys.Count().ShouldBe(1);
|
||||
allKeys.Single().Id.ShouldBe(key);
|
||||
|
|
@ -300,7 +302,7 @@ public class KeyManagerTests
|
|||
key
|
||||
};
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
allKeys.Count().ShouldBe(1);
|
||||
allKeys.Single().Id.ShouldBe(key.Id);
|
||||
|
|
@ -312,7 +314,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var key1 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Subtract(TimeSpan.FromSeconds(1)));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -327,7 +329,7 @@ public class KeyManagerTests
|
|||
var key1 = CreateCacheAndStoreKey(_options.KeyManagement.RotationInterval.Subtract(TimeSpan.FromSeconds(1)));
|
||||
var key2 = CreateAndStoreKey();
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
_mockKeyStore.Keys.Count.ShouldBe(2);
|
||||
}
|
||||
|
|
@ -337,7 +339,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var key1 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Subtract(_options.KeyManagement.PropagationTime.Add(TimeSpan.FromSeconds(1))));
|
||||
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync();
|
||||
var (allKeys, signgingKeys) = await _subject.GetAllKeysInternalAsync(_ct);
|
||||
|
||||
var key = signgingKeys.Single();
|
||||
|
||||
|
|
@ -477,7 +479,7 @@ public class KeyManagerTests
|
|||
var key5 = CreateSerializedKey(_options.KeyManagement.PropagationTime);
|
||||
var key6 = CreateSerializedKey(_options.KeyManagement.PropagationTime.Subtract(TimeSpan.FromSeconds(1)));
|
||||
|
||||
var result = await _subject.FilterAndDeleteRetiredKeysAsync([key1, key2, key3, key4, key5, key6]);
|
||||
var result = await _subject.FilterAndDeleteRetiredKeysAsync([key1, key2, key3, key4, key5, key6], _ct);
|
||||
|
||||
result.Select(x => x.Id).ShouldBe([key3.Id, key4.Id, key5.Id, key6.Id]);
|
||||
}
|
||||
|
|
@ -585,7 +587,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var key = CreateAndStoreKey();
|
||||
|
||||
var keys = await _subject.GetAllKeysFromStoreAsync();
|
||||
var keys = await _subject.GetAllKeysFromStoreAsync(ct: _ct);
|
||||
|
||||
keys.ShouldNotBeNull();
|
||||
keys.Single().Id.ShouldBe(key);
|
||||
|
|
@ -601,7 +603,7 @@ public class KeyManagerTests
|
|||
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(1)));
|
||||
var key5 = CreateAndStoreKey(_options.KeyManagement.KeyRetirementAge.Add(TimeSpan.FromSeconds(5)));
|
||||
|
||||
var keys = await _subject.GetAllKeysFromStoreAsync();
|
||||
var keys = await _subject.GetAllKeysFromStoreAsync(ct: _ct);
|
||||
|
||||
keys.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
|
||||
}
|
||||
|
|
@ -615,12 +617,12 @@ public class KeyManagerTests
|
|||
var key4 = CreateAndStoreKey(_options.KeyManagement.RotationInterval.Add(TimeSpan.FromSeconds(1)));
|
||||
var key5 = CreateAndStoreKeyThatCannotBeUnprotected(_options.KeyManagement.KeyRetirementAge.Add(TimeSpan.FromSeconds(5)));
|
||||
|
||||
var keys = await _subject.GetAllKeysFromStoreAsync();
|
||||
var keys = await _subject.GetAllKeysFromStoreAsync(ct: _ct);
|
||||
|
||||
keys.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
|
||||
|
||||
_mockKeyStore.DeleteWasCalled.ShouldBeTrue();
|
||||
var keysInStore = await _mockKeyStore.LoadKeysAsync();
|
||||
var keysInStore = await _mockKeyStore.LoadKeysAsync(_ct);
|
||||
keysInStore.Select(x => x.Id).ShouldBe([key1, key2, key3, key4]);
|
||||
}
|
||||
|
||||
|
|
@ -630,7 +632,7 @@ public class KeyManagerTests
|
|||
var key1 = CreateAndStoreKey(TimeSpan.FromSeconds(10));
|
||||
_mockKeyStore.Keys.Add(null);
|
||||
|
||||
var keys = await _subject.GetAllKeysFromStoreAsync();
|
||||
var keys = await _subject.GetAllKeysFromStoreAsync(ct: _ct);
|
||||
|
||||
keys.Select(x => x.Id).ShouldBe([key1]);
|
||||
}
|
||||
|
|
@ -640,7 +642,7 @@ public class KeyManagerTests
|
|||
[Fact]
|
||||
public async Task CreateNewKeyAndAddToCacheAsync_when_no_keys_should_store_and_return_new_key()
|
||||
{
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
|
||||
var key = signingKeys.Single();
|
||||
_mockKeyStore.Keys.Single().Id.ShouldBe(key.Id);
|
||||
}
|
||||
|
|
@ -650,7 +652,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var key1 = CreateCacheAndStoreKey(_options.KeyManagement.PropagationTime.Add(TimeSpan.FromSeconds(1)));
|
||||
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
|
||||
var key = signingKeys.Single();
|
||||
|
||||
allKeys.Count().ShouldBe(2);
|
||||
|
|
@ -664,7 +666,7 @@ public class KeyManagerTests
|
|||
{
|
||||
var key1 = CreateCacheAndStoreKey();
|
||||
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
|
||||
|
||||
allKeys.Select(x => x.Id).ShouldBe(_mockKeyStore.Keys.Select(x => x.Id));
|
||||
}
|
||||
|
|
@ -678,7 +680,7 @@ public class KeyManagerTests
|
|||
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
|
||||
sw.Stop();
|
||||
|
||||
sw.Elapsed.ShouldBeGreaterThanOrEqualTo(_options.KeyManagement.InitializationSynchronizationDelay);
|
||||
|
|
@ -695,7 +697,7 @@ public class KeyManagerTests
|
|||
|
||||
var sw = new Stopwatch();
|
||||
sw.Start();
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync();
|
||||
var (allKeys, signingKeys) = await _subject.CreateNewKeysAndAddToCacheAsync(_ct);
|
||||
sw.Stop();
|
||||
|
||||
sw.Elapsed.ShouldBeLessThan(_options.KeyManagement.InitializationSynchronizationDelay);
|
||||
|
|
@ -925,7 +927,7 @@ public class KeyManagerTests
|
|||
[Fact]
|
||||
public async Task CreateAndStoreNewKeyAsync_should_create_and_store_and_return_key()
|
||||
{
|
||||
var result = await _subject.CreateAndStoreNewKeyAsync(_rsaOptions);
|
||||
var result = await _subject.CreateAndStoreNewKeyAsync(_rsaOptions, _ct);
|
||||
|
||||
_mockKeyProtector.ProtectWasCalled.ShouldBeTrue();
|
||||
_mockKeyStore.Keys.Count.ShouldBe(1);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ internal class MockSigningKeyStore : ISigningKeyStore
|
|||
public bool LoadKeysAsyncWasCalled { get; set; }
|
||||
public bool DeleteWasCalled { get; set; }
|
||||
|
||||
public Task DeleteKeyAsync(string id)
|
||||
public Task DeleteKeyAsync(string id, CT ct)
|
||||
{
|
||||
DeleteWasCalled = true;
|
||||
if (Keys != null)
|
||||
|
|
@ -23,13 +23,13 @@ internal class MockSigningKeyStore : ISigningKeyStore
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<SerializedKey>> LoadKeysAsync()
|
||||
public Task<IEnumerable<SerializedKey>> LoadKeysAsync(CT ct)
|
||||
{
|
||||
LoadKeysAsyncWasCalled = true;
|
||||
return Task.FromResult<IEnumerable<SerializedKey>>(Keys);
|
||||
}
|
||||
|
||||
public Task StoreKeyAsync(SerializedKey key)
|
||||
public Task StoreKeyAsync(SerializedKey key, CT ct)
|
||||
{
|
||||
if (Keys == null)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue