From dec723740ed4af860f60ad4e6dcc63efeddfb427 Mon Sep 17 00:00:00 2001 From: Julien Sagnard Date: Thu, 9 May 2019 18:28:45 +0200 Subject: [PATCH] Improve with PR comments --- connexion/apis/flask_api.py | 43 +++++++++++-------- examples/openapi3/reverseproxy/app.py | 6 +++ examples/openapi3/reverseproxy_aiohttp/app.py | 6 +++ 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/connexion/apis/flask_api.py b/connexion/apis/flask_api.py index 1c671d0b7..21a638475 100644 --- a/connexion/apis/flask_api.py +++ b/connexion/apis/flask_api.py @@ -26,13 +26,6 @@ def _set_blueprint(self): self.blueprint = flask.Blueprint(endpoint, __name__, url_prefix=self.base_path, template_folder=str(self.options.openapi_console_ui_from_dir)) - def _spec_for_prefix(self): - """ Modify base_path in the spec based on incoming url - This fixes problems with reverse proxies changing the path. - """ - base_path = flask.url_for(flask.request.endpoint).rsplit("/", 1)[0] - return self.specification.with_base_path(base_path).raw - def add_openapi_json(self): """ Adds spec json to {base_path}/swagger.json @@ -42,12 +35,9 @@ def add_openapi_json(self): self.options.openapi_spec_path) endpoint_name = "{name}_openapi_json".format(name=self.blueprint.name) - def get_json_spec(): - return flask.jsonify(self._spec_for_prefix()) - self.blueprint.add_url_rule(self.options.openapi_spec_path, endpoint_name, - get_json_spec) + self._handlers.get_json_spec) def add_openapi_yaml(self): """ @@ -65,11 +55,7 @@ def add_openapi_yaml(self): self.blueprint.add_url_rule( openapi_spec_path_yaml, endpoint_name, - lambda: FlaskApi._build_flask_response( - status_code=200, - content_type="text/yaml", - data=yamldumper(self._spec_for_prefix()) - ) + self._handlers.get_yaml_spec ) def add_swagger_ui(self): @@ -131,7 +117,7 @@ def _add_operation_internal(self, method, path, operation): def _handlers(self): # type: () -> InternalHandlers if not hasattr(self, '_internal_handlers'): - self._internal_handlers = InternalHandlers(self.base_path, self.options) + self._internal_handlers = InternalHandlers(self.base_path, self.options, self.specification) return self._internal_handlers @classmethod @@ -310,9 +296,10 @@ class InternalHandlers(object): Flask handlers for internally registered endpoints. """ - def __init__(self, base_path, options): + def __init__(self, base_path, options, specification): self.base_path = base_path self.options = options + self.specification = specification def console_ui_home(self): """ @@ -321,7 +308,7 @@ def console_ui_home(self): :return: """ openapi_json_route_name = "{blueprint}.{prefix}_openapi_json" - escaped = self.base_path.replace(".", "_") + escaped = flask_utils.flaskify_endpoint(self.base_path) openapi_json_route_name = openapi_json_route_name.format( blueprint=escaped, prefix=escaped @@ -343,3 +330,21 @@ def console_ui_static_files(self, filename): # convert PosixPath to str static_dir = str(self.options.openapi_console_ui_from_dir) return flask.send_from_directory(static_dir, filename) + + def get_json_spec(self): + return flask.jsonify(self._spec_for_prefix()) + + def get_yaml_spec(self): + return FlaskApi._build_flask_response( + status_code=200, + content_type="text/yaml", + data=yamldumper(self._spec_for_prefix()) + ) + + def _spec_for_prefix(self): + """ + Modify base_path in the spec based on incoming url + This fixes problems with reverse proxies changing the path. + """ + base_path = flask.url_for(flask.request.endpoint).rsplit("/", 1)[0] + return self.specification.with_base_path(base_path).raw diff --git a/examples/openapi3/reverseproxy/app.py b/examples/openapi3/reverseproxy/app.py index 7a1652c43..be4a8e04a 100755 --- a/examples/openapi3/reverseproxy/app.py +++ b/examples/openapi3/reverseproxy/app.py @@ -7,6 +7,7 @@ directly from users on the web! ''' +import logging import connexion @@ -41,6 +42,11 @@ def __init__(self, app, script_name=None, scheme=None, server=None): self.server = server def __call__(self, environ, start_response): + logging.warn( + "this demo is not secure by default!! " + "You'll want to make sure these headers are coming from your proxy, " + "and not directly from users on the web!" + ) script_name = environ.get('HTTP_X_FORWARDED_PATH', '') or self.script_name if script_name: environ['SCRIPT_NAME'] = "/" + script_name.lstrip("/") diff --git a/examples/openapi3/reverseproxy_aiohttp/app.py b/examples/openapi3/reverseproxy_aiohttp/app.py index df6654cd1..f35477c6c 100755 --- a/examples/openapi3/reverseproxy_aiohttp/app.py +++ b/examples/openapi3/reverseproxy_aiohttp/app.py @@ -4,6 +4,7 @@ ''' import json +import logging import connexion @@ -28,6 +29,11 @@ def get_forwarded_path(self, headers): @web.middleware async def middleware(self, request, handler): + logging.warn( + "this demo is not secure by default!! " + "You'll want to make sure these headers are coming from your proxy, " + "and not directly from users on the web!" + ) try: overrides = {} headers = request.headers