Files
sockeye/sockeye.tests/ResignTests.cs

102 lines
3.3 KiB
C#

namespace sockeye.tests;
/*
Extract key fixture data, note that pgroup / format is 1 for v7 product family keys and not 1 for any v8 family keys
mkdir C:\data\sockeye-fixtures
$env:PGCLIENTENCODING = "UTF8"
.\psql -U postgres -d sockeye -At -o C:\data\sockeye-fixtures\resign.json -c "
SELECT json_agg(t ORDER BY t.id) FROM (
SELECT id,
pgroup AS format,
key
FROM alicense
WHERE key IS NOT NULL
) t;"
*/
// public class UnitTest1
// {
// [Fact]
// public void Test1()
// {
// }
// }
using System.Text.Json;
public record ResignRow(long Id, int Format, string Key);
public static class ResignFixture
{
static readonly Lazy<Dictionary<long, ResignRow>> _rows = new(Load);
public static IReadOnlyDictionary<long, ResignRow> Rows => _rows.Value;
static Dictionary<long, ResignRow> Load()
{
var path = "C:\\data\\sockeye-fixtures\\resign.json";//Environment.GetEnvironmentVariable("SOCKEYE_RESIGN_FIXTURE");
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
throw new InvalidOperationException(
"Set SOCKEYE_RESIGN_FIXTURE to the exported alicense JSON file.");
var rows = JsonSerializer.Deserialize<List<ResignRow>>(
File.ReadAllText(path),
new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
return rows.ToDictionary(r => r.Id);
}
}
public class ResignTests
{
public static IEnumerable<object[]> RowIds() =>
ResignFixture.Rows.Keys.Select(id => new object[] { id });
[Theory]
[MemberData(nameof(RowIds))]
public void Stored_licence_resigns_identically(long id)
{
var row = ResignFixture.Rows[id];
var keyText = Between(row.Key, "[KEY", "KEY]");
var expected = StripWs(Between(row.Key, "[SIGNATURE", "SIGNATURE]"));
var actual = row.Format == 1
? Sockeye.Biz.KeyFactory.Sign(keyText) // your extracted internal methods
: Sockeye.Biz.RavenKeyFactory.Sign(keyText);
//test sign returns whole key with signature need to re-extract signature only
actual = StripWs(Between(actual, "[SIGNATURE", "SIGNATURE]"));
Assert.Equal(expected, actual);
}
[Fact]
public void Fixture_covers_both_formats()
{
Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 1);
Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 2);
Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 3);
}
[Fact]
public void Tampered_payload_does_not_match()
{
var row = ResignFixture.Rows.Values.First(r => r.Format == 1);
var keyText = Between(row.Key, "[KEY", "KEY]") + "x";
var expected = StripWs(Between(row.Key, "[SIGNATURE", "SIGNATURE]"));
Assert.NotEqual(expected, StripWs(Between(Sockeye.Biz.KeyFactory.Sign(keyText), "[SIGNATURE", "SIGNATURE]")));
}
static string Between(string s, string start, string end)
{
int a = s.IndexOf(start, StringComparison.Ordinal);
int b = s.IndexOf(end, StringComparison.Ordinal);
if (a < 0 || b < 0 || b < a)
throw new FormatException($"Markers {start}/{end} not found");
return s.Substring(a + start.Length, b - a - start.Length);
}
static string StripWs(string s) => string.Concat(s.Where(c => !char.IsWhiteSpace(c)));
}