Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connexion claims extra formData parameters that are in the spec #1020

Closed
tsbriggs02 opened this issue Aug 16, 2019 · 10 comments · Fixed by #1124 or #1374
Closed

Connexion claims extra formData parameters that are in the spec #1020

tsbriggs02 opened this issue Aug 16, 2019 · 10 comments · Fixed by #1124 or #1374
Assignees
Labels

Comments

@tsbriggs02
Copy link

Description

I have a simple service that expects a POST to a certain endpoint. There's 1 parameter in the requestBody of the POST ("customerId"), and also a header parameter ("Authorization").

If I turn on strict_validation=True and I send a valid request to the endpoint, I get: Extra formData parameter(s) customerId not in spec.

Expected behaviour

The customerId parameter is in the spec, so Connexion should accept the post and call the endpoint's business logic, rather than returning a 400.

Actual behaviour

Returns:

{
    "detail": "Extra formData parameter(s) customerId not in spec",
    "status": 400,
    "title": null,
    "type": "about:blank"
}

Steps to reproduce

I'm using this spec.yaml:

openapi: "3.0.0"

info:
  title: Hello World
  version: "2"
servers:
  - url: /v1.0

paths:
  /test:
    post:
      operationId: hello.test
      summary: A test endpoint.
      parameters:
        # If this header param is here and `strict_validation` is enabled, Connexion gives a 400 error,
        # even if you DO send `customerId`.
        - name: Authorization
          in: header
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                customerId:
                  type: string
              required:
                - customerId
      responses:
        "200":
          description: OK.
        "401":
          description: Unauthorized.

And this app.py:

import connexion


def create_app():
    cxn = connexion.FlaskApp(__name__.split('.')[0], specification_dir='.')
    cxn.add_api('spec.yaml', strict_validation=True, arguments={'title': 'Hello World Example'})
    return cxn.app

And hello.py is just:

def test(body) -> str:
    return f"customerId is {body['customerId']}"

Then, send a (valid) request to the endpoint. I'm using the httpie utility, although you can exercise the bug with the SwaggerUI too.

http -v -f POST http://localhost:8000/v1.0/test "Authorization: Bearer abcd" "customerId=4"

You will see the 400 response mentioned above.

Additional info:

It seems like having the header in the spec is necessary to make the bug happen. If you take out the parameters: block, it works.

Output of the commands:

  • python --version:
    Python 3.6.6

  • pip show connexion | grep "^Version\:"
    Version: 2.3.0

@tsbriggs02
Copy link
Author

Ping...

@jmdejong
Copy link

To add on this:
I've been digging in the source code a bit and it seems that it is running a ParameterValidator instead of a RequestBodyValidator when there are any parameters.

I think the bug is in this function but I'm not sure how it is supposed to work properly:
https://github.com/zalando/connexion/blob/c8d8973c7e390a5e2071c7b494dd7bd52bd55ff1/connexion/operations/abstract.py#L415-L429

@jtlz2
Copy link

jtlz2 commented Jan 13, 2020

@jmdejong Did you make any headway on this?

@twall
Copy link

twall commented Jan 14, 2020

I see this error in 2.5.1 but not in 2.3.0.

@dtkav
Copy link
Collaborator

dtkav commented Jan 14, 2020

I think this might be fixed by #1110
There was a regression in 2.5.1 that propagated default values from any parameter type to all other parameters type (like query -> form)

I was able to reproduce the bug on master.
I think the problem is here: https://github.com/zalando/connexion/blob/master/connexion/decorators/validation.py#L303
it seems to be looking for a key (formData) that is unique to openapi 2.0.

dtkav added a commit to dtkav/connexion that referenced this issue Jan 14, 2020
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.
@dtkav dtkav added the bug label Jan 14, 2020
@dtkav
Copy link
Collaborator

dtkav commented Jan 15, 2020

Please note that strict mode for connexion was intended to fix a shortcoming of the openapi2.0 spec, but the openapi3.0 spec has a built in notion of strict called additionalProperties.
The OAS3 way to do this is to add additionalProperties: false in the schema.

dtkav added a commit to dtkav/connexion that referenced this issue Jan 21, 2020
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.
@dtkav dtkav self-assigned this Jan 21, 2020
hjacobs pushed a commit that referenced this issue Jan 21, 2020
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.
@tsbriggs02
Copy link
Author

tsbriggs02 commented Feb 4, 2020

Thank you, @jmdejong, @dtkav and @hjacobs ! I'm hoping to try the new version of Connexion out soon, to confirm the fix in my codebase.

@jmdejong
Copy link

jmdejong commented Feb 5, 2020

Just to clarify: I'm not a Connexion dev. I just encountered this bug too and dug into the codebase in order to try to make it easier for the developers to fix this.

@gitttt
Copy link

gitttt commented Feb 14, 2020

There is still an instance of this line

spec_params = [x['name'] for x in self.parameters['formData']] in
the file

https://github.com/zalando/connexion/blob/master/connexion/decorators/validation.py

The problem still occurs. @hjacobs @dtkav

@dtkav
Copy link
Collaborator

dtkav commented Feb 14, 2020

Are you running into the bug on the latest release?
that line should only apply to swagger2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
6 participants