fix(multiplayer): verify recovered arena annotations

This commit is contained in:
Josh Creek
2026-09-01 21:12:06 +01:00
parent e83f84f527
commit 0666d8d308
2 changed files with 16 additions and 1 deletions
+4 -1
View File
@@ -146,6 +146,9 @@ func (c Client) RecoverAllocation(ctx context.Context, request domain.Allocation
if item.Metadata.Annotations["cosmic-clash.io/match-id"] != request.MatchID {
return AllocatedServer{}, false, domain.ErrConflict
}
if request.ArenaPath != "" && item.Metadata.Annotations["cosmic-clash.io/arena-path"] != request.ArenaPath {
return AllocatedServer{}, false, domain.ErrConflict
}
if item.Metadata.Labels["cosmic-clash.io/region"] != request.Region || item.Metadata.Labels["cosmic-clash.io/build"] != request.Build || item.Metadata.Labels["cosmic-clash.io/protocol"] != strconv.Itoa(request.Protocol) || item.Metadata.Labels["cosmic-clash.io/transport"] != request.Transport {
return AllocatedServer{}, false, domain.ErrConflict
}
@@ -217,7 +220,7 @@ func (c Client) Allocate(ctx context.Context, request domain.AllocationRequest,
if err != nil {
return AllocatedServer{}, err
}
if request.AllocationID == "" || request.MatchID == "" || (request.Region != "EU" && request.Region != "NA") || request.Build == "" || request.Protocol <= 0 || (request.Transport != "enet" && request.Transport != "steam_sdr") || now.IsZero() {
if request.AllocationID == "" || request.MatchID == "" || (request.Region != "EU" && request.Region != "NA") || request.Build == "" || request.Protocol <= 0 || (request.Transport != "enet" && request.Transport != "steam_sdr") || (request.Playlist == domain.Ranked && !domain.IsRankedArenaPath(request.ArenaPath)) || (request.ArenaPath != "" && !domain.IsRankedArenaPath(request.ArenaPath)) || now.IsZero() {
return AllocatedServer{}, domain.ErrAllocationInput
}
if len(labels) == 0 {
+12
View File
@@ -184,6 +184,18 @@ func TestRecoverAllocationRejectsMismatchedBinding(t *testing.T) {
}
}
func TestRecoverAllocationRejectsMissingRankedArenaAnnotation(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(`{"items":[{"metadata":{"name":"gs-ranked","labels":{"cosmic-clash.io/region":"EU","cosmic-clash.io/build":"build-1","cosmic-clash.io/protocol":"1","cosmic-clash.io/transport":"enet"},"annotations":{"cosmic-clash.io/allocation-id":"allocation-1","cosmic-clash.io/match-id":"match-1"}},"status":{"state":"Allocated","address":"127.0.0.1","ports":[{"name":"default","port":31001}]}}]}`))
}))
defer server.Close()
recoveryRequest := request()
recoveryRequest.ArenaPath = "res://scenes/arena_01.tscn"
if _, found, err := (Client{BaseURL: server.URL, Namespace: "games", HTTP: server.Client()}).RecoverAllocation(context.Background(), recoveryRequest, time.Unix(1000, 0)); err == nil || found {
t.Fatalf("ranked recovery without arena annotation accepted: found=%t err=%v", found, err)
}
}
func TestRecoverAllocationRejectsDuplicateProviderMatches(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(`{"items":[{"metadata":{"name":"gs-one","labels":{"cosmic-clash.io/region":"EU","cosmic-clash.io/build":"build-1","cosmic-clash.io/protocol":"1","cosmic-clash.io/transport":"enet"},"annotations":{"cosmic-clash.io/allocation-id":"allocation-1","cosmic-clash.io/match-id":"match-1"}},"status":{"state":"Allocated","address":"127.0.0.1","ports":[{"name":"default","port":31001}]}},{"metadata":{"name":"gs-two","labels":{"cosmic-clash.io/region":"EU","cosmic-clash.io/build":"build-1","cosmic-clash.io/protocol":"1","cosmic-clash.io/transport":"enet"},"annotations":{"cosmic-clash.io/allocation-id":"allocation-1","cosmic-clash.io/match-id":"match-1"}},"status":{"state":"Allocated","address":"127.0.0.1","ports":[{"name":"default","port":31002}]}}]}`))