generated from VLADIMIR/template
fix
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/subtle"
|
||||
"encoding/json"
|
||||
@@ -39,9 +40,8 @@ func TeamRegistrationHandler(token string, register func(context.Context, int, s
|
||||
return
|
||||
}
|
||||
decoder := json.NewDecoder(http.MaxBytesReader(w, r.Body, 16<<10))
|
||||
decoder.DisallowUnknownFields()
|
||||
var registration game_service.Registration
|
||||
if err := decoder.Decode(®istration); err != nil {
|
||||
var payload json.RawMessage
|
||||
if err := decoder.Decode(&payload); err != nil {
|
||||
fail(http.StatusBadRequest, fmt.Sprintf("Некорректный JSON регистрации: %v", err))
|
||||
return
|
||||
}
|
||||
@@ -54,6 +54,11 @@ func TeamRegistrationHandler(token string, register func(context.Context, int, s
|
||||
}
|
||||
return
|
||||
}
|
||||
registration, rpcID, isRPC, err := decodeRegistrationPayload(payload)
|
||||
if err != nil {
|
||||
fail(http.StatusBadRequest, fmt.Sprintf("Некорректный JSON регистрации: %v", err))
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(r.Context(), 4*time.Second)
|
||||
defer cancel()
|
||||
id, err := register(ctx, int(gameID), deliveryID, registration)
|
||||
@@ -65,7 +70,44 @@ func TeamRegistrationHandler(token string, register func(context.Context, int, s
|
||||
case err != nil:
|
||||
fail(http.StatusInternalServerError, "Не удалось зарегистрировать команду")
|
||||
default:
|
||||
_ = json.NewEncoder(w).Encode(map[string]int{"id": id})
|
||||
if isRPC {
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{"jsonrpc": "2.0", "result": map[string]int{"id": id}, "id": rpcID})
|
||||
} else {
|
||||
_ = json.NewEncoder(w).Encode(map[string]int{"id": id})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func decodeRegistrationPayload(payload json.RawMessage) (game_service.Registration, json.RawMessage, bool, error) {
|
||||
var fields map[string]json.RawMessage
|
||||
if err := json.Unmarshal(payload, &fields); err != nil {
|
||||
return game_service.Registration{}, nil, false, err
|
||||
}
|
||||
if rawRPC, ok := fields["jsonrpc"]; ok {
|
||||
var version string
|
||||
if err := json.Unmarshal(rawRPC, &version); err != nil || version != "2.0" {
|
||||
return game_service.Registration{}, nil, true, errors.New(`поле "jsonrpc" должно быть равно "2.0"`)
|
||||
}
|
||||
params, ok := fields["params"]
|
||||
if !ok {
|
||||
return game_service.Registration{}, nil, true, errors.New(`в JSON-RPC запросе отсутствует поле "params"`)
|
||||
}
|
||||
var registration game_service.Registration
|
||||
if err := decodeStrict(params, ®istration); err != nil {
|
||||
return game_service.Registration{}, nil, true, fmt.Errorf("поле params: %w", err)
|
||||
}
|
||||
return registration, fields["id"], true, nil
|
||||
}
|
||||
var registration game_service.Registration
|
||||
if err := decodeStrict(payload, ®istration); err != nil {
|
||||
return game_service.Registration{}, nil, false, err
|
||||
}
|
||||
return registration, nil, false, nil
|
||||
}
|
||||
|
||||
func decodeStrict(data []byte, target any) error {
|
||||
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||
decoder.DisallowUnknownFields()
|
||||
return decoder.Decode(target)
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ func TestTeamRegistrationHandler(t *testing.T) {
|
||||
{"malformed", "secret", "Bearer secret", "42", "delivery", `{`, nil, 400, false},
|
||||
{"extra object", "secret", "Bearer secret", "42", "delivery", valid + ` {}`, nil, 400, false},
|
||||
{"unknown field", "secret", "Bearer secret", "42", "delivery", `{"extra":1}`, nil, 400, false},
|
||||
{"jsonrpc", "secret", "Bearer secret", "42", "delivery", `{"jsonrpc":"2.0","method":"register","params":{"name":"Команда","email":"captain@example.org","participantsCount":5},"id":1}`, nil, 200, true},
|
||||
{"too large", "secret", "Bearer secret", "42", "delivery", `{"name":"` + strings.Repeat("a", 17000) + `"}`, nil, 400, false},
|
||||
{"invalid fields", "secret", "Bearer secret", "42", "delivery", valid, game_service.ErrInvalidRegistration, 400, true},
|
||||
{"closed", "secret", "Bearer secret", "42", "delivery", valid, teams_repo.ErrRegistrationClosed, 409, true},
|
||||
@@ -55,7 +56,7 @@ func TestTeamRegistrationHandler(t *testing.T) {
|
||||
if res.Code != tc.want || called != tc.called {
|
||||
t.Fatalf("status=%d called=%v body=%s", res.Code, called, res.Body.String())
|
||||
}
|
||||
if tc.want == 200 && res.Body.String() != "{\"id\":7}\n" {
|
||||
if tc.name == "success" && res.Body.String() != "{\"id\":7}\n" {
|
||||
t.Fatal(res.Body.String())
|
||||
}
|
||||
if strings.Contains(res.Body.String(), "private database detail") {
|
||||
@@ -70,6 +71,9 @@ func TestTeamRegistrationHandler(t *testing.T) {
|
||||
if tc.name == "extra object" && !strings.Contains(res.Body.String(), "лишние данные") {
|
||||
t.Fatalf("extra data reason missing: %s", res.Body.String())
|
||||
}
|
||||
if tc.name == "jsonrpc" && !strings.Contains(res.Body.String(), `"jsonrpc":"2.0"`) {
|
||||
t.Fatalf("JSON-RPC response missing: %s", res.Body.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user