Files
IBKRTrader/tests/IBKRTrader.Tests/Web/AuthServiceTests.cs
T
Richard f923721784
Build & Test / build (ubuntu-latest) (push) Canceled after 0s
Build & Test / build (windows-latest) (push) Canceled after 0s
feat: Web-UI als zweiter Ausgabeweg neben Avalonia-Shell (#490)
- 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)
2026-09-06 19:55:40 +02:00

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();
}
}