Skip to content

Commit

Permalink
Actually fix getkin#624, thanks to @orensolo
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre Fenoll <pierrefenoll@gmail.com>
  • Loading branch information
fenollp committed Oct 13, 2022
1 parent e887ba8 commit 255e8d8
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 23 deletions.
25 changes: 15 additions & 10 deletions openapi3filter/issue624_test.go
Expand Up @@ -48,17 +48,22 @@ paths:

router, err := gorillamux.NewRouter(doc)
require.NoError(t, err)
httpReq, err := http.NewRequest(http.MethodGet, `/items?test=test1`, nil)
require.NoError(t, err)

route, pathParams, err := router.FindRoute(httpReq)
require.NoError(t, err)
for _, testcase := range []string{`test1`, `test[1`} {
t.Run(testcase, func(t *testing.T) {
httpReq, err := http.NewRequest(http.MethodGet, `/items?test=`+testcase, nil)
require.NoError(t, err)

requestValidationInput := &RequestValidationInput{
Request: httpReq,
PathParams: pathParams,
Route: route,
route, pathParams, err := router.FindRoute(httpReq)
require.NoError(t, err)

requestValidationInput := &RequestValidationInput{
Request: httpReq,
PathParams: pathParams,
Route: route,
}
err = ValidateRequest(ctx, requestValidationInput)
require.NoError(t, err)
})
}
err = ValidateRequest(ctx, requestValidationInput)
require.NoError(t, err)
}
4 changes: 2 additions & 2 deletions openapi3filter/req_resp_decoder.go
Expand Up @@ -227,7 +227,7 @@ type valueDecoder interface {
// decodeStyledParameter returns a value of an operation's parameter from HTTP request for
// parameters defined using the style format, and whether the parameter is supplied in the input.
// The function returns ParseError when HTTP request contains an invalid value of a parameter.
func decodeStyledParameter(param *openapi3.Parameter, input *RequestValidationInput) (interface{}, bool, error) {
func decodeStyledParameter(param *openapi3.Parameter, input *RequestValidationInput, schema *openapi3.SchemaRef) (interface{}, bool, error) {
sm, err := param.SerializationMethod()
if err != nil {
return nil, false, err
Expand All @@ -253,7 +253,7 @@ func decodeStyledParameter(param *openapi3.Parameter, input *RequestValidationIn
return nil, false, fmt.Errorf("unsupported parameter's 'in': %s", param.In)
}

return decodeValue(dec, param.Name, sm, param.Schema, param.Required)
return decodeValue(dec, param.Name, sm, schema, param.Required)
}

func decodeValue(dec valueDecoder, param string, sm *openapi3.SerializationMethod, schema *openapi3.SchemaRef, required bool) (interface{}, bool, error) {
Expand Down
23 changes: 16 additions & 7 deletions openapi3filter/validate_request.go
Expand Up @@ -129,20 +129,29 @@ func ValidateParameter(ctx context.Context, input *RequestValidationInput, param
var value interface{}
var err error
var found bool
var schema *openapi3.Schema
var schemaRef *openapi3.SchemaRef

// Validation will ensure that we either have content or schema.
if parameter.Content != nil {
if value, schema, found, err = decodeContentParameter(parameter, input); err != nil {
return &RequestError{Input: input, Parameter: parameter, Err: err}
}
if parameter.Content == nil {
schemaRef = parameter.Schema
} else if len(parameter.Content) != 1 {
// We only know how to decode a parameter if it has one content, application/json
err = fmt.Errorf("multiple content types for parameter %q", parameter.Name)
return &RequestError{Input: input, Parameter: parameter, Err: err}
} else {
if value, found, err = decodeStyledParameter(parameter, input); err != nil {
mt := parameter.Content.Get("application/json")
if mt == nil {
err = fmt.Errorf("parameter %q has no content schema", parameter.Name)
return &RequestError{Input: input, Parameter: parameter, Err: err}
}
schema = parameter.Schema.Value
schemaRef = mt.Schema
}

if value, found, err = decodeStyledParameter(parameter, input, schemaRef); err != nil {
return &RequestError{Input: input, Parameter: parameter, Err: err}
}

schema := schemaRef.Value
// Set default value if needed
if value == nil && schema != nil && schema.Default != nil {
value = schema.Default
Expand Down
8 changes: 4 additions & 4 deletions openapi3filter/validation_test.go
Expand Up @@ -328,15 +328,15 @@ func TestFilter(t *testing.T) {
// enough.
req = ExampleRequest{
Method: "POST",
URL: "http://example.com/api/prefix/v/suffix?contentArg={\"name\":\"bob\", \"id\":\"a\"}",
URL: `http://example.com/api/prefix/v/suffix?contentArg={"name":"bob", "id":"a"}`,
}
err = expect(req, resp)
require.NoError(t, err)

// Now it should fail due the ID being too long
req = ExampleRequest{
Method: "POST",
URL: "http://example.com/api/prefix/v/suffix?contentArg={\"name\":\"bob\", \"id\":\"EXCEEDS_MAX_LENGTH\"}",
URL: `http://example.com/api/prefix/v/suffix?contentArg={"name":"bob", "id":"EXCEEDS_MAX_LENGTH"}`,
}
err = expect(req, resp)
require.IsType(t, &RequestError{}, err)
Expand All @@ -351,15 +351,15 @@ func TestFilter(t *testing.T) {

req = ExampleRequest{
Method: "POST",
URL: "http://example.com/api/prefix/v/suffix?contentArg2={\"name\":\"bob\", \"id\":\"a\"}",
URL: `http://example.com/api/prefix/v/suffix?contentArg2={"name":"bob", "id":"a"}`,
}
err = expectWithDecoder(req, resp, customDecoder)
require.NoError(t, err)

// Now it should fail due the ID being too long
req = ExampleRequest{
Method: "POST",
URL: "http://example.com/api/prefix/v/suffix?contentArg2={\"name\":\"bob\", \"id\":\"EXCEEDS_MAX_LENGTH\"}",
URL: `http://example.com/api/prefix/v/suffix?contentArg2={"name":"bob", "id":"EXCEEDS_MAX_LENGTH"}`,
}
err = expectWithDecoder(req, resp, customDecoder)
require.IsType(t, &RequestError{}, err)
Expand Down

0 comments on commit 255e8d8

Please sign in to comment.