chore: establish local platform baseline
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package rtc
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestVolcengineTokenIssuerProducesSignedScopedDeterministicToken(t *testing.T) {
|
||||
const appID = "661e7ae5543cf00000000000"
|
||||
appKey := "unit-test-" + strings.Repeat("x", 23)
|
||||
issuer, err := NewVolcengineTokenIssuer(appID, appKey, 5*time.Minute)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expiresAt := time.Unix(1_800_000_000, 0).UTC()
|
||||
first, err := issuer.Issue("room-1", "device-1", expiresAt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
second, err := issuer.Issue("room-1", "device-1", expiresAt)
|
||||
if err != nil || second != first {
|
||||
t.Fatalf("idempotent issue mismatch: err=%v equal=%v", err, second == first)
|
||||
}
|
||||
if len(first) <= 27 || first[:27] != "001"+appID {
|
||||
t.Fatalf("unexpected token prefix: %q", first)
|
||||
}
|
||||
|
||||
content, err := base64.StdEncoding.DecodeString(first[27:])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
message, rest := readTokenBytes(t, content)
|
||||
signature, rest := readTokenBytes(t, rest)
|
||||
if len(rest) != 0 {
|
||||
t.Fatalf("unexpected trailing token bytes: %d", len(rest))
|
||||
}
|
||||
mac := hmac.New(sha256.New, []byte(appKey))
|
||||
_, _ = mac.Write(message)
|
||||
if !hmac.Equal(signature, mac.Sum(nil)) {
|
||||
t.Fatal("token signature is invalid")
|
||||
}
|
||||
|
||||
offset := 4 // deterministic nonce
|
||||
issuedAt := binary.LittleEndian.Uint32(message[offset : offset+4])
|
||||
offset += 4
|
||||
expires := binary.LittleEndian.Uint32(message[offset : offset+4])
|
||||
offset += 4
|
||||
room, remaining := readTokenBytes(t, message[offset:])
|
||||
user, remaining := readTokenBytes(t, remaining)
|
||||
if string(room) != "room-1" || string(user) != "device-1" || issuedAt != uint32(expiresAt.Add(-5*time.Minute).Unix()) || expires != uint32(expiresAt.Unix()) {
|
||||
t.Fatalf("unexpected token scope room=%s user=%s issued=%d expires=%d", room, user, issuedAt, expires)
|
||||
}
|
||||
if len(remaining) != 2+5*6 || binary.LittleEndian.Uint16(remaining[:2]) != 5 {
|
||||
t.Fatalf("unexpected privileges payload: %x", remaining)
|
||||
}
|
||||
for index, want := range []uint16{0, 1, 2, 3, 4} {
|
||||
position := 2 + index*6
|
||||
if got := binary.LittleEndian.Uint16(remaining[position : position+2]); got != want {
|
||||
t.Fatalf("privilege[%d]=%d want=%d", index, got, want)
|
||||
}
|
||||
if got := binary.LittleEndian.Uint32(remaining[position+2 : position+6]); got != uint32(expiresAt.Unix()) {
|
||||
t.Fatalf("privilege[%d] expiry=%d", index, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVolcengineTokenIssuerValidatesApplicationIdentity(t *testing.T) {
|
||||
if _, err := NewVolcengineTokenIssuer("short", "0123456789abcdef", time.Minute); err == nil {
|
||||
t.Fatal("expected invalid app ID to be rejected")
|
||||
}
|
||||
}
|
||||
|
||||
func readTokenBytes(t *testing.T, input []byte) ([]byte, []byte) {
|
||||
t.Helper()
|
||||
if len(input) < 2 {
|
||||
t.Fatal("truncated token field length")
|
||||
}
|
||||
length := int(binary.LittleEndian.Uint16(input[:2]))
|
||||
if len(input) < 2+length {
|
||||
t.Fatal("truncated token field")
|
||||
}
|
||||
return input[2 : 2+length], input[2+length:]
|
||||
}
|
||||
Reference in New Issue
Block a user