- Einheitlicher WebserverWorker in IBKRTrader.Hosting auf Kestrel-Basis - Token-Authentifizierung (AuthService) mit zeitkonstantem Vergleich und HMAC-Session-Tokens - OrderManager im Core fuer Bestands- und Reservierungsabgleich offener Broker-Orders - SettingsSchema fuer reflexionsbasiertes Auslesen und sichere Aktualisierung ohne Klartext-Passwoerter - SSE-Streaming (LogStreamService) fuer Echtzeit-Logs ueber isolierte Channels - Statische Single-Page-Application in wwwroot (Avalonia Fluent / Polytrader Theme) fuer alle 9 Ansichten - Unit-Tests fuer OrderManager, AuthService, SettingsSchema, LogStreamService und WebserverWorker (498 Tests gruen)
112 lines
3.5 KiB
C#
112 lines
3.5 KiB
C#
using FluentAssertions;
|
|
using IBKRTrader.Core.Settings;
|
|
using IBKRTrader.Hosting.Web;
|
|
|
|
namespace IBKRTrader.Tests.Web;
|
|
|
|
[Trait("cat", "unit")]
|
|
public class AuthServiceTests
|
|
{
|
|
[Fact]
|
|
public void ValidateToken_ReturnsTrueForCorrectToken()
|
|
{
|
|
var settings = new SettingsService();
|
|
settings.Settings.Webserver.AuthToken = "secret-token-123";
|
|
var sut = new AuthService(settings);
|
|
|
|
sut.IsConfigured.Should().BeTrue();
|
|
sut.ValidateToken("secret-token-123").Should().BeTrue();
|
|
sut.ValidateToken("wrong-token").Should().BeFalse();
|
|
sut.ValidateToken("").Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void ValidateToken_ReturnsFalseWhenNotConfigured()
|
|
{
|
|
var settings = new SettingsService();
|
|
settings.Settings.Webserver.AuthToken = "";
|
|
var sut = new AuthService(settings);
|
|
|
|
sut.IsConfigured.Should().BeFalse();
|
|
sut.ValidateToken("any-token").Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void SessionToken_RoundTrip_ValidatesSuccessfully()
|
|
{
|
|
var settings = new SettingsService();
|
|
settings.Settings.Webserver.AuthToken = "my-secret-key";
|
|
var sut = new AuthService(settings);
|
|
|
|
var sessionToken = sut.CreateSessionToken(TimeSpan.FromHours(1));
|
|
|
|
sessionToken.Should().NotBeNullOrWhiteSpace();
|
|
sut.ValidateSessionToken(sessionToken).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void SessionToken_TamperedToken_FailsValidation()
|
|
{
|
|
var settings = new SettingsService();
|
|
settings.Settings.Webserver.AuthToken = "my-secret-key";
|
|
var sut = new AuthService(settings);
|
|
|
|
var sessionToken = sut.CreateSessionToken(TimeSpan.FromHours(1));
|
|
var tampered = sessionToken + "tamper";
|
|
|
|
sut.ValidateSessionToken(tampered).Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void SessionToken_ExpiredToken_FailsValidation()
|
|
{
|
|
var settings = new SettingsService();
|
|
settings.Settings.Webserver.AuthToken = "my-secret-key";
|
|
var sut = new AuthService(settings);
|
|
|
|
// Abgelaufenes Token (minus 1 Sekunde)
|
|
var sessionToken = sut.CreateSessionToken(TimeSpan.FromSeconds(-10));
|
|
|
|
sut.ValidateSessionToken(sessionToken).Should().BeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void IsAuthenticated_RecognizesBearerHeader()
|
|
{
|
|
var settings = new SettingsService();
|
|
settings.Settings.Webserver.AuthToken = "my-secret-key";
|
|
var sut = new AuthService(settings);
|
|
|
|
var ctx = new Microsoft.AspNetCore.Http.DefaultHttpContext();
|
|
ctx.Request.Headers.Authorization = "Bearer my-secret-key";
|
|
|
|
sut.IsAuthenticated(ctx).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void IsAuthenticated_RecognizesQueryToken()
|
|
{
|
|
var settings = new SettingsService();
|
|
settings.Settings.Webserver.AuthToken = "my-secret-key";
|
|
var sut = new AuthService(settings);
|
|
|
|
var ctx = new Microsoft.AspNetCore.Http.DefaultHttpContext();
|
|
ctx.Request.QueryString = new Microsoft.AspNetCore.Http.QueryString("?token=my-secret-key");
|
|
|
|
sut.IsAuthenticated(ctx).Should().BeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void IsAuthenticated_RejectsUnauthenticatedRequest()
|
|
{
|
|
var settings = new SettingsService();
|
|
settings.Settings.Webserver.AuthToken = "my-secret-key";
|
|
var sut = new AuthService(settings);
|
|
|
|
var ctx = new Microsoft.AspNetCore.Http.DefaultHttpContext();
|
|
|
|
sut.IsAuthenticated(ctx).Should().BeFalse();
|
|
}
|
|
}
|
|
|