fix: validate matchmaking event vocabulary

This commit is contained in:
Josh Creek
2026-08-31 23:10:31 +01:00
parent a4bc8cdac8
commit 161d2cdceb
3 changed files with 56 additions and 3 deletions
+38 -2
View File
@@ -70,8 +70,8 @@ func (h *eventHub) unsubscribe(subscriber *eventSubscriber) {
}
func (h *eventHub) publish(event ControlPlaneEvent) error {
if event.PlayerID == "" || event.Event == "" || event.ResourceID == "" || event.OccurredAt.IsZero() {
return errors.New("invalid control-plane event")
if err := validateControlPlaneEvent(event); err != nil {
return err
}
payload, err := json.Marshal(event)
if err != nil {
@@ -96,6 +96,42 @@ func (h *eventHub) publish(event ControlPlaneEvent) error {
return nil
}
func validateControlPlaneEvent(event ControlPlaneEvent) error {
if event.PlayerID == "" || event.ResourceID == "" || event.OccurredAt.IsZero() {
return errors.New("invalid control-plane event envelope")
}
switch event.Event {
case "state_changed":
if !eventState(event.State, "QUEUED", "PROPOSED", "ACCEPTED", "ALLOCATING", "PROCESS_READY", "ASSIGNMENT_READY", "ASSIGNED", "CONNECTING", "LIVE", "RESULT_PENDING", "COMPLETED", "CANCELLED", "EXPIRED", "FAILED") {
return errors.New("invalid state-changed event")
}
case "proposal_changed":
if !eventState(event.State, "OPEN", "ACCEPTED", "DECLINED", "EXPIRED", "CANCELLED") {
return errors.New("invalid proposal-changed event")
}
case "assignment_changed":
if event.MatchID == "" || event.ServerID == "" {
return errors.New("invalid assignment-changed event")
}
case "error":
if !eventState(event.Code, "REVISION_GAP", "NOT_AUTHORISED", "INVALID_STATE", "RATE_LIMITED") {
return errors.New("invalid error event")
}
default:
return errors.New("unknown control-plane event")
}
return nil
}
func eventState(value string, allowed ...string) bool {
for _, candidate := range allowed {
if value == candidate {
return true
}
}
return false
}
func (s *Service) controlPlaneEvent(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
writeError(w, http.StatusMethodNotAllowed, "method_not_allowed")