feat: Document completed tasks for KMS, Cryptography, and Plugin Libraries

- Added detailed task completion records for KMS interface implementation and CLI support for file-based keys.
- Documented security enhancements including Argon2id password hashing, audit event contracts, and rate limiting configurations.
- Included scoped service support and integration updates for the Plugin platform, ensuring proper DI handling and testing coverage.
This commit is contained in:
master
2025-10-31 14:37:45 +02:00
parent 240e8ff25d
commit 15b4a1de6a
312 changed files with 6399 additions and 3319 deletions

View File

@@ -1,25 +1,30 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Auth.Abstractions;
using StellaOps.Scheduler.Models;
using StellaOps.Scheduler.WebService.GraphJobs;
using StellaOps.Scheduler.WebService.GraphJobs.Events;
using StellaOps.Scheduler.WebService.Options;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Auth.Abstractions;
using StellaOps.Scheduler.Models;
using StellaOps.Scheduler.WebService.GraphJobs;
using StellaOps.Scheduler.WebService.GraphJobs.Events;
using StellaOps.Scheduler.WebService.Options;
using StackExchange.Redis;
namespace StellaOps.Scheduler.WebService.Tests;
public sealed class GraphJobEventPublisherTests
{
[Fact]
public async Task PublishAsync_WritesEventJson_WhenEnabled()
{
var options = Microsoft.Extensions.Options.Options.Create(new SchedulerEventsOptions
{
GraphJobs = { Enabled = true }
});
var loggerProvider = new ListLoggerProvider();
using var loggerFactory = LoggerFactory.Create(builder => builder.AddProvider(loggerProvider));
var publisher = new GraphJobEventPublisher(new OptionsMonitorStub<SchedulerEventsOptions>(options), loggerFactory.CreateLogger<GraphJobEventPublisher>());
public async Task PublishAsync_LogsEvent_WhenDriverUnsupported()
{
var options = Microsoft.Extensions.Options.Options.Create(new SchedulerEventsOptions
{
GraphJobs =
{
Enabled = true,
Driver = "memory"
}
});
var loggerProvider = new ListLoggerProvider();
using var loggerFactory = LoggerFactory.Create(builder => builder.AddProvider(loggerProvider));
var publisher = new GraphJobEventPublisher(new OptionsMonitorStub<SchedulerEventsOptions>(options), new ThrowingRedisConnectionFactory(), loggerFactory.CreateLogger<GraphJobEventPublisher>());
var buildJob = new GraphBuildJob(
id: "gbj_test",
@@ -58,12 +63,12 @@ public sealed class GraphJobEventPublisherTests
}
[Fact]
public async Task PublishAsync_Suppressed_WhenDisabled()
{
var options = Microsoft.Extensions.Options.Options.Create(new SchedulerEventsOptions());
var loggerProvider = new ListLoggerProvider();
using var loggerFactory = LoggerFactory.Create(builder => builder.AddProvider(loggerProvider));
var publisher = new GraphJobEventPublisher(new OptionsMonitorStub<SchedulerEventsOptions>(options), loggerFactory.CreateLogger<GraphJobEventPublisher>());
public async Task PublishAsync_Suppressed_WhenDisabled()
{
var options = Microsoft.Extensions.Options.Options.Create(new SchedulerEventsOptions());
var loggerProvider = new ListLoggerProvider();
using var loggerFactory = LoggerFactory.Create(builder => builder.AddProvider(loggerProvider));
var publisher = new GraphJobEventPublisher(new OptionsMonitorStub<SchedulerEventsOptions>(options), new ThrowingRedisConnectionFactory(), loggerFactory.CreateLogger<GraphJobEventPublisher>());
var overlayJob = new GraphOverlayJob(
id: "goj_test",
@@ -95,12 +100,12 @@ public sealed class GraphJobEventPublisherTests
await publisher.PublishAsync(notification, CancellationToken.None);
Assert.DoesNotContain(loggerProvider.Messages, message => message.Contains(GraphJobEventKinds.GraphJobCompleted, StringComparison.Ordinal));
Assert.DoesNotContain(loggerProvider.Messages, message => message.Contains(GraphJobEventKinds.GraphJobCompleted, StringComparison.Ordinal));
}
private sealed class OptionsMonitorStub<T> : IOptionsMonitor<T> where T : class
{
private readonly IOptions<T> _options;
private sealed class OptionsMonitorStub<T> : IOptionsMonitor<T> where T : class
{
private readonly IOptions<T> _options;
public OptionsMonitorStub(IOptions<T> options)
{
@@ -112,7 +117,13 @@ private sealed class OptionsMonitorStub<T> : IOptionsMonitor<T> where T : class
public T Get(string? name) => _options.Value;
public IDisposable? OnChange(Action<T, string?> listener) => null;
}
}
private sealed class ThrowingRedisConnectionFactory : IRedisConnectionFactory
{
public Task<IConnectionMultiplexer> ConnectAsync(ConfigurationOptions options, CancellationToken cancellationToken)
=> throw new InvalidOperationException("Redis connection should not be established in this test.");
}
private sealed class ListLoggerProvider : ILoggerProvider
{