From ab430afaf51e2ad901b1a5afe0cf9fbeb42c304c Mon Sep 17 00:00:00 2001 From: Daniel Grossmann-Kavanagh Date: Tue, 21 Jan 2020 00:49:46 -0800 Subject: [PATCH] Fixes #1020, OAS3 false positive for extra form param (#1124) When using an OAS3 spec with formdata, the validation logic looks for the key 'formData' in the spec parameters list. This keys is specific to OAS2, and will never be present, causing any form data to throw an ExtraParameterProblem. --- connexion/decorators/validation.py | 6 +++++- tests/api/test_parameters.py | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/connexion/decorators/validation.py b/connexion/decorators/validation.py index db65dc9..b7c7a62 100644 --- a/connexion/decorators/validation.py +++ b/connexion/decorators/validation.py @@ -302,7 +302,11 @@ class ParameterValidator(object): def validate_formdata_parameter_list(self, request): request_params = request.form.keys() - spec_params = [x['name'] for x in self.parameters.get('formData', [])] + try: + spec_params = [x['name'] for x in self.parameters['formData']] + except KeyError: + # OAS 3 + return set() return validate_parameter_list(request_params, spec_params) def validate_query_parameter(self, param, request): diff --git a/tests/api/test_parameters.py b/tests/api/test_parameters.py index cd2014f..5c9900b 100644 --- a/tests/api/test_parameters.py +++ b/tests/api/test_parameters.py @@ -117,6 +117,16 @@ def test_strict_extra_query_param(strict_app): assert response['detail'] == "Extra query parameter(s) extra_parameter not in spec" +def test_strict_formdata_param(strict_app): + app_client = strict_app.app.test_client() + headers = {'Content-type': 'application/x-www-form-urlencoded'} + url = '/v1.0/test_array_csv_form_param' + resp = app_client.post(url, headers=headers, data={"items":"mango"}) + response = json.loads(resp.data.decode('utf-8', 'replace')) + assert response == ['mango'] + assert resp.status_code == 200 + + def test_path_parameter_someint(simple_app): app_client = simple_app.app.test_client() resp = app_client.get('/v1.0/test-int-path/123') # type: flask.Response