up
Some checks failed
Build Test Deploy / authority-container (push) Has been cancelled
Build Test Deploy / docs (push) Has been cancelled
Build Test Deploy / deploy (push) Has been cancelled
Build Test Deploy / build-test (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled

This commit is contained in:
root
2025-10-15 19:20:13 +03:00
parent 8d153522b0
commit 0d8233dfb4
125 changed files with 9383 additions and 3306 deletions

View File

@@ -0,0 +1,137 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using StellaOps.Cli.Configuration;
using StellaOps.Cli.Services;
using Xunit;
namespace StellaOps.Cli.Tests.Services;
public sealed class AuthorityDiagnosticsReporterTests : IDisposable
{
private readonly string _originalDirectory = Directory.GetCurrentDirectory();
private readonly string _tempDirectory = Path.Combine(Path.GetTempPath(), $"stellaops-cli-tests-{Guid.NewGuid():N}");
public AuthorityDiagnosticsReporterTests()
{
Directory.CreateDirectory(_tempDirectory);
Directory.SetCurrentDirectory(_tempDirectory);
}
[Fact]
public void Emit_LogsWarning_WhenPasswordPolicyWeakened()
{
WriteAuthorityConfiguration(minimumLength: 8);
var (_, configuration) = CliBootstrapper.Build(Array.Empty<string>());
var logger = new ListLogger();
AuthorityDiagnosticsReporter.Emit(configuration, logger);
var warning = Assert.Single(logger.Entries, entry => entry.Level == LogLevel.Warning);
Assert.Contains("minimum length 8 < 12", warning.Message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("standard.yaml", warning.Message, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void Emit_EmitsNoWarnings_WhenPasswordPolicyMeetsBaseline()
{
WriteAuthorityConfiguration(minimumLength: 12);
var (_, configuration) = CliBootstrapper.Build(Array.Empty<string>());
var logger = new ListLogger();
AuthorityDiagnosticsReporter.Emit(configuration, logger);
Assert.DoesNotContain(logger.Entries, entry => entry.Level >= LogLevel.Warning);
}
public void Dispose()
{
Directory.SetCurrentDirectory(_originalDirectory);
try
{
if (Directory.Exists(_tempDirectory))
{
Directory.Delete(_tempDirectory, recursive: true);
}
}
catch
{
// Ignored.
}
}
private static void WriteAuthorityConfiguration(int minimumLength)
{
var payload = new
{
Authority = new
{
Plugins = new
{
ConfigurationDirectory = "plugins",
Descriptors = new
{
standard = new
{
AssemblyName = "StellaOps.Authority.Plugin.Standard",
Enabled = true,
ConfigFile = "standard.yaml"
}
}
}
}
};
var json = JsonSerializer.Serialize(payload, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText("appsettings.json", json);
var pluginDirectory = Path.Combine(Directory.GetCurrentDirectory(), "plugins");
Directory.CreateDirectory(pluginDirectory);
var pluginConfig = $"""
bootstrapUser:
username: "admin"
password: "changeme"
passwordPolicy:
minimumLength: {minimumLength}
requireUppercase: true
requireLowercase: true
requireDigit: true
requireSymbol: true
""";
File.WriteAllText(Path.Combine(pluginDirectory, "standard.yaml"), pluginConfig);
}
private sealed class ListLogger : ILogger
{
public readonly record struct LogEntry(LogLevel Level, string Message);
public List<LogEntry> Entries { get; } = new();
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => NullScope.Instance;
public bool IsEnabled(LogLevel logLevel) => true;
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
var message = formatter(state, exception);
Entries.Add(new LogEntry(logLevel, message));
}
}
private sealed class NullScope : IDisposable
{
public static NullScope Instance { get; } = new();
public void Dispose()
{
}
}
}