up
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
using StellaOps.Policy;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Policy.Tests;
|
||||
|
||||
public class SplCanonicalizerTests
|
||||
{
|
||||
[Fact]
|
||||
public void Canonicalize_SortsStatementsActionsAndConditions()
|
||||
{
|
||||
const string input = """
|
||||
{
|
||||
"kind": "Policy",
|
||||
"apiVersion": "spl.stellaops/v1",
|
||||
"spec": {
|
||||
"statements": [
|
||||
{
|
||||
"effect": "deny",
|
||||
"id": "B-2",
|
||||
"match": {
|
||||
"resource": "/accounts/*",
|
||||
"actions": ["delete", "read"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "desc",
|
||||
"effect": "allow",
|
||||
"id": "A-1",
|
||||
"match": {
|
||||
"actions": ["write", "read"],
|
||||
"resource": "/accounts/*",
|
||||
"conditions": [
|
||||
{"operator": "gte", "value": 2, "field": "tier"},
|
||||
{"field": "env", "value": "prod", "operator": "eq"}
|
||||
]
|
||||
},
|
||||
"audit": {"severity": "warn", "message": "audit msg"}
|
||||
}
|
||||
],
|
||||
"defaultEffect": "deny"
|
||||
},
|
||||
"metadata": {
|
||||
"labels": {"env": "prod"},
|
||||
"annotations": {"a": "1"},
|
||||
"name": "demo"
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
var canonical = SplCanonicalizer.CanonicalizeToString(input);
|
||||
|
||||
const string expected = "{\"apiVersion\":\"spl.stellaops/v1\",\"kind\":\"Policy\",\"metadata\":{\"annotations\":{\"a\":\"1\"},\"labels\":{\"env\":\"prod\"},\"name\":\"demo\"},\"spec\":{\"defaultEffect\":\"deny\",\"statements\":[{\"audit\":{\"message\":\"audit msg\",\"severity\":\"warn\"},\"description\":\"desc\",\"effect\":\"allow\",\"id\":\"A-1\",\"match\":{\"actions\":[\"read\",\"write\"],\"conditions\":[{\"field\":\"env\",\"operator\":\"eq\",\"value\":\"prod\"},{\"field\":\"tier\",\"operator\":\"gte\",\"value\":2}],\"resource\":\"/accounts/*\"}},{\"effect\":\"deny\",\"id\":\"B-2\",\"match\":{\"actions\":[\"delete\",\"read\"],\"resource\":\"/accounts/*\"}}]}}}";
|
||||
|
||||
Assert.Equal(expected, canonical);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ComputeDigest_IgnoresOrderingNoise()
|
||||
{
|
||||
const string versionA = """
|
||||
{"apiVersion":"spl.stellaops/v1","kind":"Policy","metadata":{"name":"demo"},"spec":{"defaultEffect":"deny","statements":[{"id":"B","effect":"deny","match":{"resource":"/r","actions":["write","read"]}},{"id":"A","effect":"allow","match":{"resource":"/r","actions":["read"],"conditions":[{"field":"env","operator":"eq","value":"prod"}]}}]}}
|
||||
""";
|
||||
|
||||
const string versionB = """
|
||||
{"spec":{"statements":[{"match":{"actions":["read"],"resource":"/r","conditions":[{"value":"prod","operator":"eq","field":"env"}]},"effect":"allow","id":"A"},{"match":{"actions":["read","write"],"resource":"/r"},"effect":"deny","id":"B"}],"defaultEffect":"deny"},"kind":"Policy","metadata":{"name":"demo"},"apiVersion":"spl.stellaops/v1"}
|
||||
""";
|
||||
|
||||
var hashA = SplCanonicalizer.ComputeDigest(versionA);
|
||||
var hashB = SplCanonicalizer.ComputeDigest(versionB);
|
||||
|
||||
Assert.Equal(hashA, hashB);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ComputeDigest_DetectsContentChange()
|
||||
{
|
||||
const string baseDoc = """
|
||||
{"apiVersion":"spl.stellaops/v1","kind":"Policy","metadata":{"name":"demo"},"spec":{"statements":[{"id":"A","effect":"allow","match":{"resource":"/r","actions":["read"]}}]}}
|
||||
""";
|
||||
|
||||
const string changedDoc = """
|
||||
{"apiVersion":"spl.stellaops/v1","kind":"Policy","metadata":{"name":"demo"},"spec":{"statements":[{"id":"A","effect":"allow","match":{"resource":"/r","actions":["read","write"]}}]}}
|
||||
""";
|
||||
|
||||
var original = SplCanonicalizer.ComputeDigest(baseDoc);
|
||||
var changed = SplCanonicalizer.ComputeDigest(changedDoc);
|
||||
|
||||
Assert.NotEqual(original, changed);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user