internal/server/hosttoken/hosttoken_generation_test.go
Ref: Size: 1.7 KiB History
package hosttoken
import (
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestMintVerifyRoundTrip pins the credential contract:
// host_id.gen.issued_unix.hmac, HMAC over the three dotted fields.
func TestMintVerifyRoundTrip(t *testing.T) {
secret := []byte("s3cret")
issued := time.Unix(1_750_000_000, 0)
cred := Mint(secret, "abc123", 3, issued)
claims, ok := Verify(secret, cred)
require.True(t, ok)
assert.Equal(t, "abc123", claims.HostID)
assert.Equal(t, int64(3), claims.Generation)
assert.True(t, claims.IssuedAt.Equal(issued))
}
// TestVerifyRejectsTampering: flipping any field invalidates the HMAC, and a
// wrong secret never verifies.
func TestVerifyRejectsTampering(t *testing.T) {
secret := []byte("s3cret")
cred := Mint(secret, "abc123", 1, time.Unix(1_750_000_000, 0))
parts := strings.Split(cred, ".")
require.Len(t, parts, 4)
for i, repl := range []string{"otherhost", "9", "1750000001"} {
mut := make([]string, 4)
copy(mut, parts)
mut[i] = repl
_, ok := Verify(secret, strings.Join(mut, "."))
assert.False(t, ok, "tampered field %d must fail", i)
}
_, ok := Verify([]byte("wrong"), cred)
assert.False(t, ok)
}
// TestVerifyRejectsMalformed: anything that is not exactly the four signed
// fields is rejected.
func TestVerifyRejectsMalformed(t *testing.T) {
secret := []byte("s3cret")
for _, cred := range []string{
"", "abc123", "a.b.c", // too few parts
"abc123.deadbeef", // two parts
"a.b.c.d.e", // too many parts
"abc123.x.170.deadbeef", // non-numeric generation
"abc123.1.x.deadbeef", // non-numeric issued_unix
} {
_, ok := Verify(secret, cred)
assert.False(t, ok, "must reject %q", cred)
}
}