Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions E4A.PostGuard.slnx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<Solution>
<Project Path="src/E4A.PostGuard.csproj" />
<Project Path="tests/E4A.PostGuard.Tests/E4A.PostGuard.Tests.csproj" />
</Solution>
2 changes: 2 additions & 0 deletions src/PostGuard.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public class PostGuard

public PostGuard(PostGuardConfig config)
{
ArgumentNullException.ThrowIfNull(config);
config.Validate();
_config = config;
}

Expand Down
30 changes: 30 additions & 0 deletions src/PostGuardConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,34 @@ public class PostGuardConfig
public required string PkgUrl { get; init; }
public required string CryptifyUrl { get; init; }
public Dictionary<string, string>? Headers { get; init; }

/// <summary>
/// Opt-in escape hatch to allow non-https URLs (e.g. http://localhost) for
/// local development and testing. Defaults to false: the SDK refuses to
/// send API keys and signing keys over plaintext connections.
/// </summary>
public bool AllowInsecureUrls { get; init; }

internal void Validate()
{
if (AllowInsecureUrls)
{
return;
}

RequireHttps(PkgUrl, nameof(PkgUrl));
RequireHttps(CryptifyUrl, nameof(CryptifyUrl));
}

private static void RequireHttps(string url, string name)
{
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri) ||
uri.Scheme != Uri.UriSchemeHttps)
{
throw new ArgumentException(
$"{name} must be an absolute https:// URL (got '{url}'). " +
"Set AllowInsecureUrls = true to opt in to plaintext URLs for local testing.",
name);
}
}
}
25 changes: 25 additions & 0 deletions tests/E4A.PostGuard.Tests/E4A.PostGuard.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\E4A.PostGuard.csproj" />
</ItemGroup>

</Project>
94 changes: 94 additions & 0 deletions tests/E4A.PostGuard.Tests/PostGuardConfigTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using E4A.PostGuard;

namespace E4A.PostGuard.Tests;

public class PostGuardConfigTests
{
private const string ValidPkg = "https://pkg.postguard.eu";
private const string ValidCryptify = "https://cryptify.postguard.eu";

[Fact]
public void Ctor_AcceptsHttpsUrls()
{
var config = new PostGuardConfig
{
PkgUrl = ValidPkg,
CryptifyUrl = ValidCryptify,
};

var pg = new PostGuard(config);

Assert.NotNull(pg);
}

[Theory]
[InlineData("http://pkg.postguard.eu")]
[InlineData("http://localhost:8080")]
[InlineData("ftp://pkg.postguard.eu")]
[InlineData("pkg.postguard.eu")]
[InlineData("/relative/path")]
[InlineData("")]
public void Ctor_RejectsNonHttpsPkgUrl(string badUrl)
{
var config = new PostGuardConfig
{
PkgUrl = badUrl,
CryptifyUrl = ValidCryptify,
};

var ex = Assert.Throws<ArgumentException>(() => new PostGuard(config));
Assert.Equal("PkgUrl", ex.ParamName);
}

[Theory]
[InlineData("http://cryptify.postguard.eu")]
[InlineData("ws://cryptify.postguard.eu")]
[InlineData("cryptify.postguard.eu")]
public void Ctor_RejectsNonHttpsCryptifyUrl(string badUrl)
{
var config = new PostGuardConfig
{
PkgUrl = ValidPkg,
CryptifyUrl = badUrl,
};

var ex = Assert.Throws<ArgumentException>(() => new PostGuard(config));
Assert.Equal("CryptifyUrl", ex.ParamName);
}

[Fact]
public void Ctor_AllowInsecureUrls_AcceptsHttpLocalhost()
{
var config = new PostGuardConfig
{
PkgUrl = "http://localhost:8080",
CryptifyUrl = "http://localhost:8081",
AllowInsecureUrls = true,
};

var pg = new PostGuard(config);

Assert.NotNull(pg);
}

[Fact]
public void Ctor_AllowInsecureUrls_StillAcceptsHttpsUrls()
{
var config = new PostGuardConfig
{
PkgUrl = ValidPkg,
CryptifyUrl = ValidCryptify,
AllowInsecureUrls = true,
};

var pg = new PostGuard(config);

Assert.NotNull(pg);
}

[Fact]
public void Ctor_NullConfig_Throws()
{
Assert.Throws<ArgumentNullException>(() => new PostGuard(null!));
}
}