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

Move parameter validation to middleware #1610

Merged
merged 3 commits into from
Dec 23, 2022

Conversation

RobbeSneyders
Copy link
Member

Fixes #1525

This PR follows up on #1588 and #1591 and moves the last part of validation, the parameter validation, to the middleware,

@RobbeSneyders RobbeSneyders added this to the Connexion 3.0 milestone Nov 14, 2022
@coveralls
Copy link

Pull Request Test Coverage Report for Build 3465708868

  • 342 of 353 (96.88%) changed or added relevant lines in 9 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.07%) to 94.405%

Changes Missing Coverage Covered Lines Changed/Added Lines %
connexion/validators/parameter.py 87 89 97.75%
connexion/validators/json.py 94 97 96.91%
connexion/validators/form_data.py 90 96 93.75%
Totals Coverage Status
Change from base Build 3396121566: 0.07%
Covered Lines: 2936
Relevant Lines: 3110

💛 - Coveralls

@@ -119,6 +120,15 @@ def resolve_params(self, params, _in):
else:
resolved_param[k] = values[-1]

if not (is_nullable(param_defn) and is_null(resolved_param[k])):
try:
# TODO: coerce types in a single place
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now coerce the types in three locations

  • Here, in the URI parser
  • In the parameter validation
  • In the form validation

I feel like we should be able to only do this in the URI parsing, but then we need some more work to still propagate the validation errors properly and make sure the URI parsing is used in all cases.

@@ -206,3 +206,22 @@ def __init__(
)

super().__init__(title=title, detail=detail, **kwargs)


class TypeValidationError(Exception):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only moved

@@ -25,6 +25,10 @@ def from_operation(cls, operation: AbstractOperation, next_app: ASGIApp):
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
"""Attach operation to scope and pass it to the next app"""
original_scope = _scope.get()
# Pass resolved path params along
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Starlette Request relies on this.

@@ -296,3 +298,53 @@ def extract_content_type(
mime_type = content_type
break
return mime_type, encoding


def coerce_type(param, value, parameter_type, parameter_name=None):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only moved

@@ -0,0 +1,150 @@
import logging
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only moved

@@ -0,0 +1,155 @@
import json
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only moved

@@ -0,0 +1,148 @@
import collections
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly moved with some small changes.

@@ -172,7 +172,7 @@ def test_path_parameter_someint__bad(simple_app):
# non-integer values will not match Flask route
app_client = simple_app.app.test_client()
resp = app_client.get("/v1.0/test-int-path/foo") # type: flask.Response
assert resp.status_code == 404
assert resp.status_code == 400, resp.text
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe 400 is more correct than 404 when a wrong type of path parameter is passed.

@@ -706,7 +706,7 @@ def test_oauth_scopes_in_or(security_handler_factory):


def test_form_transformation(api):
mock_self = mock.Mock(strict_validation=True)
mock_self = mock.Mock()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strict_validation for form data is checked by the FormDataValidator, we don't need to include it in the transformation here.

@RobbeSneyders
Copy link
Member Author

Fixes #770

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

Successfully merging this pull request may close these issues.

Extract validation into middleware
2 participants