access-engine/internal/sign/numeric_decode_test.go

55 lines
1.9 KiB
Go
Raw Normal View History

package sign
import (
"bytes"
"crypto/ed25519"
"encoding/json"
"github.com/netkingdom/access-engine/pkg/api"
"testing"
)
func TestProducerNumericEnvelopeDecodeCompatibility(t *testing.T) {
key := ed25519.NewKeyFromSeed(bytes.Repeat([]byte{11}, 32))
keys := map[string]ed25519.PublicKey{"synthetic-numeric": key.Public().(ed25519.PublicKey)}
for _, raw := range []string{`1`, `1.0`, `-0.0`, `1e-07`, `1e+20`, `9007199254740993`, `1.7976931348623157e308`, `5e-324`, `true`, `"<>&\u2028\u2029 café"`, `[1,1.0,-0.0]`, `{"nested":1.0}`} {
t.Run(raw, func(t *testing.T) {
var value any
decoder := json.NewDecoder(bytes.NewBufferString(raw))
decoder.UseNumber()
if err := decoder.Decode(&value); err != nil {
t.Fatal(err)
}
original := api.DecisionEnvelope{Binding: &api.DecisionBinding{Context: map[string]any{"numeric": value}}}
if err := Sign(&original, key, "synthetic-numeric"); err != nil {
t.Fatal(err)
}
wire, _ := json.Marshal(original)
decoded, err := DecodeEnvelope(wire)
if err != nil {
t.Fatal(err)
}
if err := Verify(decoded, keys); err != nil {
t.Fatal(err)
}
before, _ := CanonicalBytes(original)
after, _ := CanonicalBytes(decoded)
if !bytes.Equal(before, after) {
t.Fatal("producer canonical bytes changed")
}
})
}
// Existing float64 producer profile still verifies through the new decoder.
legacy := api.DecisionEnvelope{Binding: &api.DecisionBinding{Context: map[string]any{"number": float64(1), "exponent": float64(1e-7)}}}
Sign(&legacy, key, "synthetic-numeric")
wire, _ := json.Marshal(legacy)
decoded, err := DecodeEnvelope(wire)
if err != nil || Verify(decoded, keys) != nil {
t.Fatal("legacy producer compatibility failed")
}
for _, raw := range []string{`{} {}`, `{"new_unknown_authority":true}`} {
if _, err := DecodeEnvelope([]byte(raw)); err == nil {
t.Fatal("invalid envelope accepted")
}
}
}