85 lines
2.8 KiB
Go
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)
|
|
}
|
|
}
|