using ClawdDotNet.Core.Instances;
using Shouldly;
namespace ClawdDotNet.Core.Tests.Instances;
///
/// Der Nachweis, dass ein lizenzierter Instanzmanager die Instanz gestartet hat (#535).
///
/// Das Loch, das hier zugeht. Mit E-M3 prüft eine geführte Instanz die Lizenz
/// nicht mehr selbst — der Manager hat es zentral getan. Woran sie „geführt" erkannte, war
/// der Schalter --managed, und ein Schalter ist keine Erkennung.
///
/// Es geht nicht darum, jemanden abzuwehren, der Werkzeuge mitbringt: Der Schlüssel
/// steht in der Programmdatei. Es geht darum, dass der gewöhnliche Weg an der Lizenz
/// vorbei verschlossen ist.
///
public sealed class ManagerHandshakeTests
{
private const string Instanz = "/daten/Instances/Alpha";
private const string Andere = "/daten/Instances/Beta";
[Fact]
public void Eine_frische_Unterschrift_traegt()
{
var token = ManagerHandshake.Sign(Instanz);
ManagerHandshake.Verify(Instanz, token).ShouldBeTrue();
}
///
/// Der Fall, der überhaupt der Anlass war: --managed ohne Unterschrift.
///
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
[InlineData("--managed")]
[InlineData("v1")]
[InlineData("v1.999.")]
[InlineData("v2.99999999999.abcdef")]
[InlineData("v1.keinezahl.abcdef")]
public void Ohne_brauchbare_Unterschrift_gilt_die_Instanz_als_ungefuehrt(string? token)
{
ManagerHandshake.Verify(Instanz, token).ShouldBeFalse();
}
///
/// Eine erfundene Unterschrift trägt nicht — auch wenn der Aufbau stimmt.
///
[Fact]
public void Eine_erfundene_Unterschrift_traegt_nicht()
{
var ablauf = DateTimeOffset.UtcNow.AddMinutes(5).ToUnixTimeSeconds();
ManagerHandshake.Verify(Instanz, $"v1.{ablauf}.{new string('a', 64)}")
.ShouldBeFalse();
}
///
/// Geprüft wird gegen das Verzeichnis, in dem die Instanz tatsächlich läuft.
///
/// Sonst unterschriebe man das Argument statt der Sache: Eine Unterschrift für
/// Alpha ließe Beta starten, indem man beim Prüfen Alpha vorzeigt.
///
[Fact]
public void Eine_Unterschrift_gilt_nur_fuer_ihre_eigene_Instanz()
{
var token = ManagerHandshake.Sign(Instanz);
ManagerHandshake.Verify(Andere, token).ShouldBeFalse();
}
///
/// Abgelaufen ist abgelaufen — sonst hübe jemand eine Unterschrift auf und startete
/// damit nächste Woche eine Instanz ohne Lizenz.
///
[Fact]
public void Eine_abgelaufene_Unterschrift_traegt_nicht()
{
var vorhin = DateTimeOffset.UtcNow.AddHours(-1);
var token = ManagerHandshake.Sign(Instanz, vorhin);
ManagerHandshake.Verify(Instanz, token, vorhin).ShouldBeTrue("Damals galt sie.");
ManagerHandshake.Verify(Instanz, token).ShouldBeFalse("Jetzt nicht mehr.");
}
///
/// Am Ablaufzeitpunkt herumzudrehen hilft nicht: Er geht in die Unterschrift ein.
///
[Fact]
public void Ein_verlaengerter_Ablauf_macht_die_Unterschrift_ungueltig()
{
var token = ManagerHandshake.Sign(Instanz);
var teile = token.Split('.');
var spaeter = DateTimeOffset.UtcNow.AddYears(1).ToUnixTimeSeconds();
ManagerHandshake.Verify(Instanz, $"v1.{spaeter}.{teile[2]}").ShouldBeFalse();
}
///
/// Derselbe Pfad in anderer Schreibweise muss dieselbe Unterschrift ergeben — sonst
/// scheitert der Handschlag daran, dass einer einen Schrägstrich mehr geschrieben hat.
///
[Fact]
public void Schreibweisen_desselben_Pfades_ergeben_dieselbe_Unterschrift()
{
var basis = Path.Combine(Path.GetTempPath(), "clawd-handschlag");
var token = ManagerHandshake.Sign(basis);
ManagerHandshake.Verify(basis + Path.DirectorySeparatorChar, token).ShouldBeTrue();
ManagerHandshake.Verify(Path.Combine(basis, "."), token).ShouldBeTrue();
}
}