138 lines
5.0 KiB
C#
138 lines
5.0 KiB
C#
using FinalFactory.Rendezvous.Server.Abuse;
|
|
using FinalFactory.Rendezvous.Server.Deployment;
|
|
|
|
namespace FinalFactory.Rendezvous.Tests.Deployment;
|
|
|
|
public sealed class DeploymentOptionsTests
|
|
{
|
|
[Fact]
|
|
public void ProductionConfigurationAcceptsExplicitPublicEndpointsAndTrustBoundary()
|
|
{
|
|
DeploymentOptions options = ValidOptions();
|
|
AbuseProtectionOptions abuse = new()
|
|
{
|
|
TrustedProxyAddresses = ["192.0.2.10"],
|
|
};
|
|
|
|
IReadOnlyList<string> errors = options.ValidateProduction(
|
|
abuse,
|
|
"rendezvous.finalfactory.at");
|
|
|
|
Assert.Empty(errors);
|
|
}
|
|
|
|
[Fact]
|
|
public void ProductionConfigurationRejectsUnsafeAndAmbiguousDefaults()
|
|
{
|
|
DeploymentOptions options = new()
|
|
{
|
|
SingleActiveInstance = false,
|
|
};
|
|
|
|
IReadOnlyList<string> errors = options.ValidateProduction(
|
|
new AbuseProtectionOptions(),
|
|
"*");
|
|
|
|
Assert.Contains(errors, error => error.Contains("SingleActiveInstance", StringComparison.Ordinal));
|
|
Assert.Contains(errors, error => error.Contains("PublicHttpBaseUrl", StringComparison.Ordinal));
|
|
Assert.Contains(errors, error => error.Contains("PublicUdpHost", StringComparison.Ordinal));
|
|
Assert.Contains(errors, error => error.Contains("TrustedProxyAddresses", StringComparison.Ordinal));
|
|
Assert.Contains(errors, error => error.Contains("AllowedHosts", StringComparison.Ordinal));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("http://rendezvous.example.com/")]
|
|
[InlineData("https://user@example.com/")]
|
|
[InlineData("https://rendezvous.example.com/path")]
|
|
[InlineData("https://localhost/")]
|
|
[InlineData("https://10.0.0.1/")]
|
|
[InlineData("https://192.0.2.10/")]
|
|
[InlineData("https://[::ffff:10.0.0.1]/")]
|
|
[InlineData("https://[ff02::1]/")]
|
|
[InlineData("https://rendezvous.invalid/")]
|
|
public void ProductionConfigurationRejectsUnsafeHttpEndpoint(string endpoint)
|
|
{
|
|
DeploymentOptions options = ValidOptions() with { PublicHttpBaseUrl = endpoint };
|
|
|
|
IReadOnlyList<string> errors = options.ValidateProduction(
|
|
new AbuseProtectionOptions { TrustedProxyAddresses = ["192.0.2.10"] },
|
|
"rendezvous.finalfactory.at");
|
|
|
|
Assert.Contains(errors, error => error.Contains("PublicHttpBaseUrl", StringComparison.Ordinal));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("0.1.2.3")]
|
|
[InlineData("100.64.0.1")]
|
|
[InlineData("192.0.2.1")]
|
|
[InlineData("198.18.0.1")]
|
|
[InlineData("198.51.100.1")]
|
|
[InlineData("203.0.113.1")]
|
|
[InlineData("224.0.0.1")]
|
|
[InlineData("255.255.255.255")]
|
|
[InlineData("::ffff:192.168.1.1")]
|
|
[InlineData("2001:db8::1")]
|
|
[InlineData("ff02::1")]
|
|
[InlineData("rendezvous.example.com")]
|
|
[InlineData("rendezvous.home.arpa")]
|
|
[InlineData("rendezvous.alt")]
|
|
[InlineData("service.test")]
|
|
public void ProductionConfigurationRejectsNonPublicUdpEndpoint(string endpoint)
|
|
{
|
|
DeploymentOptions options = ValidOptions() with { PublicUdpHost = endpoint };
|
|
|
|
IReadOnlyList<string> errors = options.ValidateProduction(
|
|
new AbuseProtectionOptions { TrustedProxyAddresses = ["192.0.2.10"] },
|
|
"rendezvous.finalfactory.at");
|
|
|
|
Assert.Contains(errors, error => error.Contains("PublicUdpHost", StringComparison.Ordinal));
|
|
}
|
|
|
|
[Fact]
|
|
public void IsolatedSmokeTestRequiresExplicitPrivateEndpointOverride()
|
|
{
|
|
DeploymentOptions options = ValidOptions() with
|
|
{
|
|
PublicHttpBaseUrl = "https://localhost/",
|
|
PublicUdpHost = "127.0.0.1",
|
|
AllowPrivatePublicEndpoints = true,
|
|
};
|
|
|
|
IReadOnlyList<string> errors = options.ValidateProduction(
|
|
new AbuseProtectionOptions { TrustedProxyAddresses = ["127.0.0.1"] },
|
|
"localhost");
|
|
|
|
Assert.Empty(errors);
|
|
}
|
|
|
|
[Fact]
|
|
public void ProductionConfigurationRejectsInvalidPortsDeadlinesAndMismatchedHostFilter()
|
|
{
|
|
DeploymentOptions options = ValidOptions() with
|
|
{
|
|
PublicUdpPort = 0,
|
|
DrainDeadlineSeconds = 31,
|
|
MinimumDrainSeconds = 6,
|
|
};
|
|
|
|
IReadOnlyList<string> errors = options.ValidateProduction(
|
|
new AbuseProtectionOptions { TrustedProxyAddresses = ["192.0.2.10"] },
|
|
"different.finalfactory.at");
|
|
|
|
Assert.Contains(errors, error => error.Contains("PublicUdpPort", StringComparison.Ordinal));
|
|
Assert.Contains(errors, error => error.Contains("DrainDeadlineSeconds", StringComparison.Ordinal));
|
|
Assert.Contains(errors, error => error.Contains("MinimumDrainSeconds", StringComparison.Ordinal));
|
|
Assert.Contains(errors, error => error.Contains("exact host", StringComparison.Ordinal));
|
|
}
|
|
|
|
private static DeploymentOptions ValidOptions() => new()
|
|
{
|
|
PublicHttpBaseUrl = "https://rendezvous.finalfactory.at/",
|
|
PublicUdpHost = "rendezvous-udp.finalfactory.at",
|
|
PublicUdpPort = 9050,
|
|
DrainDeadlineSeconds = 10,
|
|
MinimumDrainSeconds = 1,
|
|
SingleActiveInstance = true,
|
|
};
|
|
}
|