mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-11 08:23:45 +00:00
feat: add projected workload JWT adapter
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
package workload
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/cosmic-clash/cosmic-clash/server/domain"
|
||||
)
|
||||
|
||||
func binding() domain.WorkloadBinding {
|
||||
return domain.WorkloadBinding{Issuer: "https://issuer", Audience: "cosmic-result", Namespace: "games", ServiceAcct: "match-server", PodUID: "pod-1", GameServerUID: "gs-1", AllocationID: "allocation-1", MatchID: "match-1", ServerID: "server-1"}
|
||||
}
|
||||
|
||||
func tokenFor(t *testing.T, alg string, claims map[string]any) string {
|
||||
t.Helper()
|
||||
header, _ := json.Marshal(map[string]string{"alg": alg, "typ": "JWT"})
|
||||
payload, _ := json.Marshal(claims)
|
||||
encode := func(value []byte) string { return base64.RawURLEncoding.EncodeToString(value) }
|
||||
return encode(header) + "." + encode(payload) + "." + encode([]byte("signature"))
|
||||
}
|
||||
|
||||
func validClaims() map[string]any {
|
||||
return map[string]any{"iss": "https://issuer", "aud": "cosmic-result", "iat": float64(999), "exp": float64(1001), "namespace": "games", "service_account": "match-server", "pod_uid": "pod-1", "gameserver_uid": "gs-1", "allocation_id": "allocation-1", "match_id": "match-1", "server_id": "server-1"}
|
||||
}
|
||||
|
||||
func TestParseAndValidateVerifiesJWTBeforeReturningBinding(t *testing.T) {
|
||||
token := tokenFor(t, "RS256", validClaims())
|
||||
wantSigning := strings.Join(strings.Split(token, ".")[:2], ".")
|
||||
got, err := ParseAndValidate(token, binding(), func(signingInput, signature []byte) bool {
|
||||
return string(signingInput) == wantSigning && string(signature) == "signature"
|
||||
}, time.Unix(1000, 0))
|
||||
if err != nil || got != binding() {
|
||||
t.Fatalf("binding=%+v err=%v", got, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAndValidateRejectsUnsignedMalformedAndMutatedTokens(t *testing.T) {
|
||||
cases := []string{tokenFor(t, "none", validClaims()), tokenFor(t, "RS256", validClaims())[:10], tokenFor(t, "RS256", validClaims())}
|
||||
for i, token := range cases {
|
||||
_, err := ParseAndValidate(token, binding(), func([]byte, []byte) bool { return i != 2 }, time.Unix(1000, 0))
|
||||
if err == nil {
|
||||
t.Fatalf("case %d accepted", i)
|
||||
}
|
||||
}
|
||||
claims := validClaims()
|
||||
claims["server_id"] = "other"
|
||||
if _, err := ParseAndValidate(tokenFor(t, "RS256", claims), binding(), func([]byte, []byte) bool { return true }, time.Unix(1000, 0)); err == nil {
|
||||
t.Fatal("mutated binding accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAndValidateRejectsBoundaryExpiryAndMultiAudience(t *testing.T) {
|
||||
claims := validClaims()
|
||||
claims["exp"] = float64(1000)
|
||||
if _, err := ParseAndValidate(tokenFor(t, "RS256", claims), binding(), func([]byte, []byte) bool { return true }, time.Unix(1000, 0)); err == nil {
|
||||
t.Fatal("expiry boundary accepted")
|
||||
}
|
||||
claims = validClaims()
|
||||
claims["aud"] = []string{"other", "cosmic-result"}
|
||||
if _, err := ParseAndValidate(tokenFor(t, "RS256", claims), binding(), func([]byte, []byte) bool { return true }, time.Unix(1000, 0)); err == nil {
|
||||
t.Fatal("ambiguous audience accepted")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user