initital commit
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
package token_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"gitea.tecamino.local/paadi/licenseServer/client/hwid"
|
||||
"gitea.tecamino.local/paadi/licenseServer/client/token"
|
||||
)
|
||||
|
||||
var secret = []byte("super-secret-key-32-bytes-minimum!")
|
||||
|
||||
func newPair(t *testing.T) (*token.Generator, *token.Reader) {
|
||||
t.Helper()
|
||||
g, err := token.NewGenerator(secret)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := token.NewReader(secret)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return g, r
|
||||
}
|
||||
|
||||
// --- Expiry license tests ---
|
||||
|
||||
func TestExpiryLicense_Valid(t *testing.T) {
|
||||
g, r := newPair(t)
|
||||
tok, err := g.IssueExpiry("myapp", time.Now().Add(24*time.Hour), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fp, err := hwid.Collect()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID := fp.Hash()
|
||||
|
||||
result := r.Validate(tok, machineID)
|
||||
if !result.Valid {
|
||||
t.Fatalf("expected valid, got: %v", result.Error)
|
||||
}
|
||||
if result.ExpiresAt == nil {
|
||||
t.Fatal("expected ExpiresAt to be set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpiryLicense_Expired(t *testing.T) {
|
||||
g, r := newPair(t)
|
||||
tok, err := g.IssueExpiry("myapp", time.Now().Add(-1*time.Hour), nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fp, err := hwid.Collect()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID := fp.Hash()
|
||||
|
||||
result := r.Validate(tok, machineID)
|
||||
if result.Valid {
|
||||
t.Fatal("expected invalid for expired license")
|
||||
}
|
||||
}
|
||||
|
||||
// --- Usage license tests ---
|
||||
|
||||
func TestUsageLicense_Valid(t *testing.T) {
|
||||
g, r := newPair(t)
|
||||
tok, err := g.IssueUsage("myapp", 5, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fp, err := hwid.Collect()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID := fp.Hash()
|
||||
|
||||
result := r.Validate(tok, machineID)
|
||||
if !result.Valid {
|
||||
t.Fatalf("expected valid: %v", result.Error)
|
||||
}
|
||||
if *result.Remaining != 5 {
|
||||
t.Fatalf("expected 5 remaining, got %d", *result.Remaining)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsageLicense_Consume(t *testing.T) {
|
||||
g, r := newPair(t)
|
||||
tok, err := g.IssueUsage("myapp", 3, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fp, err := hwid.Collect()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID := fp.Hash()
|
||||
|
||||
for i := int64(2); i >= 0; i-- {
|
||||
res, err := r.Consume(tok, machineID)
|
||||
if err != nil {
|
||||
t.Fatalf("consume failed: %v", err)
|
||||
}
|
||||
if *res.Remaining != i {
|
||||
t.Fatalf("expected %d remaining, got %d", i, *res.Remaining)
|
||||
}
|
||||
}
|
||||
|
||||
// 4th consume should fail
|
||||
_, err = r.Consume(tok, machineID)
|
||||
if err == nil {
|
||||
t.Fatal("expected error after exhausting usage")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsageLicense_Exhausted(t *testing.T) {
|
||||
g, r := newPair(t)
|
||||
tok, err := g.IssueUsage("myapp", 2, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fp, err := hwid.Collect()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID := fp.Hash()
|
||||
|
||||
r.Consume(tok, machineID)
|
||||
r.Consume(tok, machineID)
|
||||
|
||||
result := r.Validate(tok, machineID)
|
||||
if result.Valid {
|
||||
t.Fatal("expected invalid after exhausting uses")
|
||||
}
|
||||
}
|
||||
|
||||
// --- Tamper / signature tests ---
|
||||
|
||||
func TestTamperedToken(t *testing.T) {
|
||||
g, r := newPair(t)
|
||||
tok, _ := g.IssueExpiry("myapp", time.Now().Add(24*time.Hour), nil)
|
||||
|
||||
tampered := token.Token(string(tok) + "x")
|
||||
|
||||
fp, err := hwid.Collect()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID := fp.Hash()
|
||||
|
||||
result := r.Validate(tampered, machineID)
|
||||
if result.Valid {
|
||||
t.Fatal("tampered token should be invalid")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWrongSecret(t *testing.T) {
|
||||
g, _ := newPair(t)
|
||||
tok, _ := g.IssueExpiry("myapp", time.Now().Add(24*time.Hour), nil)
|
||||
|
||||
// Reader with different secret
|
||||
r2, _ := token.NewReader([]byte("different-secret-key-32-bytes-xx!"))
|
||||
|
||||
fp, err := hwid.Collect()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID := fp.Hash()
|
||||
|
||||
result := r2.Validate(tok, machineID)
|
||||
if result.Valid {
|
||||
t.Fatal("token signed with different secret should be invalid")
|
||||
}
|
||||
}
|
||||
|
||||
// --- Usage persistence ---
|
||||
|
||||
func TestUsageLedger_Persistence(t *testing.T) {
|
||||
g, r := newPair(t)
|
||||
tok, _ := g.IssueUsage("myapp", 10, nil)
|
||||
|
||||
fp, err := hwid.Collect()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
machineID := fp.Hash()
|
||||
|
||||
res, _ := r.Consume(tok, machineID)
|
||||
res, _ = r.Consume(tok, machineID)
|
||||
_ = res
|
||||
|
||||
snap := r.UsageSnapshot()
|
||||
|
||||
// Simulate restart: new reader, load snapshot
|
||||
r2, _ := token.NewReader(secret)
|
||||
for id, count := range snap {
|
||||
r2.LoadUsage(id, count)
|
||||
}
|
||||
|
||||
result := r2.Validate(tok, machineID)
|
||||
if !result.Valid {
|
||||
t.Fatalf("expected valid after reload: %v", result.Error)
|
||||
}
|
||||
if *result.Remaining != 8 {
|
||||
t.Fatalf("expected 8 remaining after reloading 2 uses, got %d", *result.Remaining)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user