Files
2026-07-20 21:41:51 +02:00

85 lines
2.8 KiB
Go

package licensekit
import (
"crypto/ed25519"
"crypto/rand"
"testing"
"time"
)
func testKeys(t *testing.T) (ed25519.PublicKey, ed25519.PrivateKey) {
t.Helper()
pub, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
t.Fatal(err)
}
return pub, priv
}
func TestLicenseRoundTripAndContext(t *testing.T) {
pub, priv := testKeys(t)
now := time.Now().UTC()
claims := Claims{Version: 1, LicenseID: "lic_test", Issuer: "vendor", Customer: "customer", Product: "product-a", Edition: "pro", Features: []string{"b", "a"}, Domains: []string{"*.example.org"}, IssuedAt: now.Unix(), ExpiresAt: now.Add(time.Hour).Unix(), Verification: VerificationPolicy{Mode: ModeOffline}}
token, err := SignLicense(priv, "issuer-1", claims)
if err != nil {
t.Fatal(err)
}
store := NewTrustStore()
store.LicenseKeys["issuer-1"] = EncodeKey(pub)
verified, err := VerifyLicense(store, token, now)
if err != nil {
t.Fatal(err)
}
if verified.Claims.Features[0] != "a" {
t.Fatalf("features not sorted: %#v", verified.Claims.Features)
}
if err := ValidateLicenseContext(verified.Claims, "product-a", "https://app.example.org", ""); err != nil {
t.Fatal(err)
}
if err := ValidateLicenseContext(verified.Claims, "product-b", "https://app.example.org", ""); err == nil {
t.Fatal("expected product mismatch")
}
}
func TestGlobalWildcardAllowsAllHosts(t *testing.T) {
if err := ValidateDomain([]string{"*"}, "http://localhost:8080"); err != nil {
t.Fatal(err)
}
if err := ValidateDomain([]string{"*"}, "https://anything.invalid"); err != nil {
t.Fatal(err)
}
}
func TestUnknownKeyIsRejected(t *testing.T) {
_, priv := testKeys(t)
now := time.Now().UTC()
claims := Claims{Version: 1, LicenseID: "lic_test", Issuer: "vendor", Customer: "customer", Product: "product", Edition: "pro", IssuedAt: now.Unix(), ExpiresAt: now.Add(time.Hour).Unix(), Verification: VerificationPolicy{Mode: ModeOffline}}
token, err := SignLicense(priv, "self-chosen", claims)
if err != nil {
t.Fatal(err)
}
if _, err := VerifyLicense(NewTrustStore(), token, now); err == nil {
t.Fatal("untrusted user key must not be accepted")
}
}
func TestLeaseRoundTrip(t *testing.T) {
pub, priv := testKeys(t)
now := time.Now().UTC()
claims := LeaseClaims{Version: 1, LeaseID: "lease_1", LicenseID: "lic_1", Product: "product", Customer: "customer", Edition: "pro", Features: []string{"x"}, Host: "example.org", IssuedAt: now.Unix(), ExpiresAt: now.Add(time.Hour).Unix()}
token, err := SignLease(priv, "lease-1", claims)
if err != nil {
t.Fatal(err)
}
store := NewTrustStore()
store.LeaseKeys["lease-1"] = EncodeKey(pub)
verified, err := VerifyLease(store, token, now, 0)
if err != nil {
t.Fatal(err)
}
license := Claims{LicenseID: "lic_1", Product: "product"}
if err := ValidateLeaseContext(verified.Claims, license, "product", "https://example.org", ""); err != nil {
t.Fatal(err)
}
}