feat: add authenticated matchmaking control client

This commit is contained in:
Josh Creek
2026-08-31 22:36:05 +01:00
parent 39ebfce1bb
commit 5106ac64da
5 changed files with 158 additions and 2 deletions
@@ -0,0 +1,26 @@
extends "res://tests/test_case.gd"
const ControlPlaneClient = preload("res://scripts/control_plane_client.gd")
func test_base_url_validation_rejects_ambiguous_or_insecure_values() -> void:
assert_true(ControlPlaneClient.is_valid_base_url("http://127.0.0.1:8080"), "local HTTP endpoint is valid")
assert_true(ControlPlaneClient.is_valid_base_url("https://match.example"), "HTTPS endpoint is valid")
assert_true(not ControlPlaneClient.is_valid_base_url("match.example"), "scheme is required")
assert_true(not ControlPlaneClient.is_valid_base_url("http://match.example/"), "trailing slash is normalized before validation")
assert_true(not ControlPlaneClient.is_valid_base_url("http://match example"), "whitespace is rejected")
assert_true(not ControlPlaneClient.is_valid_base_url("https://user:pass@match.example"), "userinfo is rejected")
assert_true(not ControlPlaneClient.is_valid_base_url("https://match.example?token=secret"), "query strings are rejected")
var client := ControlPlaneClient.new()
assert_true(client.configure("https://match.example", "session-id:opaque-token"), "safe access token configures")
assert_true(not client.configure("https://match.example", "token\nforged-header"), "header injection is rejected")
func test_ticket_normalization_preserves_payload_and_derives_expiry() -> void:
var payload := {"ticket_id": "ticket-1", "state": "QUEUED", "expires_at": "2026-08-31T12:00:00Z"}
var normalized := ControlPlaneClient.normalize_ticket(payload)
assert_eq(normalized["ticket_id"], "ticket-1", "normalization preserves ticket identity")
assert_true(normalized.has("expires_at_unix"), "RFC3339 expiry is available to the projection")
assert_true(int(normalized["expires_at_unix"]) > 0, "expiry is converted to a positive epoch")
assert_true(not payload.has("expires_at_unix"), "normalization does not mutate the HTTP payload")
+1 -1
View File
@@ -71,7 +71,7 @@ func test_physics_engine_is_jolt() -> void:
func test_required_autoloads_are_registered() -> void:
# NetworkManager in particular is reached by name from many scripts; losing
# it from [autoload] fails only at the point of use, deep in a smoke test.
for autoload_name in ["GameSettings", "VideoSettings", "NetworkManager", "MatchNet", "MatchSim"]:
for autoload_name in ["GameSettings", "ControlPlaneClient", "VideoSettings", "NetworkManager", "MatchNet", "MatchSim"]:
assert_true(
ProjectSettings.has_setting("autoload/" + autoload_name),
"autoload/%s registered" % autoload_name