diff --git a/cdci_data_analysis/flask_app/app.py b/cdci_data_analysis/flask_app/app.py index dab793c6..3188949f 100644 --- a/cdci_data_analysis/flask_app/app.py +++ b/cdci_data_analysis/flask_app/app.py @@ -100,7 +100,7 @@ def run_api_instr_list(): logger.warning('\nThe endpoint \'/api/instr-list\' is deprecated and you will be automatically redirected to the ' '\'/instr-list\' endpoint. Please use this one in the future.\n') - if app.config['conf'].products_url is not None and validators.url(app.config['conf'].products_url): + if app.config['conf'].products_url is not None and validators.url(app.config['conf'].products_url, simple_host=True): # TODO remove the dispatch-data part, better to have it extracted from the configuration file redirection_url = os.path.join(app.config['conf'].products_url, 'dispatch-data/instr-list') if request.args: @@ -160,7 +160,7 @@ def download_products(): @app.route("/download_file", methods=['POST', 'GET', 'HEAD']) def download_file(): - if app.config['conf'].products_url is not None and validators.url(app.config['conf'].products_url): + if app.config['conf'].products_url is not None and validators.url(app.config['conf'].products_url, simple_host=True): # TODO remove the dispatch-data part, better to have it extracted from the configuration file redirection_url = os.path.join(app.config['conf'].products_url, 'dispatch-data/download_products') if request.args: diff --git a/cdci_data_analysis/pytest_fixtures.py b/cdci_data_analysis/pytest_fixtures.py index a6d19069..85649a53 100644 --- a/cdci_data_analysis/pytest_fixtures.py +++ b/cdci_data_analysis/pytest_fixtures.py @@ -566,6 +566,19 @@ def dispatcher_test_conf_with_external_products_url_fn(dispatcher_test_conf_fn): yield fn +@pytest.fixture +def dispatcher_test_conf_with_default_route_products_url_fn(dispatcher_test_conf_fn): + fn = dispatcher_test_conf_fn + with open(fn, "r+") as f: + data = f.read() + data = re.sub('(\s+products_url:).*\n', '\n products_url: http://0.0.0.0:1234/mmoda/\n', data) + f.seek(0) + f.write(data) + f.truncate() + + yield fn + + @pytest.fixture def dispatcher_test_conf_no_resubmit_timeout_fn(dispatcher_test_conf_fn): fn = dispatcher_test_conf_fn @@ -677,6 +690,13 @@ def dispatcher_test_conf_with_external_products_url(dispatcher_test_conf_with_ex yield loaded_yaml['dispatcher'] +@pytest.fixture +def dispatcher_test_conf_with_default_route_products_url(dispatcher_test_conf_with_default_route_products_url_fn): + with open(dispatcher_test_conf_with_default_route_products_url_fn) as yaml_f: + loaded_yaml = yaml.load(yaml_f, Loader=yaml.SafeLoader) + yield loaded_yaml['dispatcher'] + + def dispatcher_test_conf_with_no_resubmit_timeout(dispatcher_test_conf_with_no_resubmit_timeout_fn): with open(dispatcher_test_conf_with_no_resubmit_timeout_fn) as yaml_f: loaded_yaml = yaml.load(yaml_f, Loader=yaml.SafeLoader) @@ -1126,6 +1146,19 @@ def dispatcher_live_fixture_with_external_products_url(pytestconfig, dispatcher_ os.kill(pid, signal.SIGINT) +@pytest.fixture +def dispatcher_live_fixture_with_default_route_products_url(pytestconfig, dispatcher_test_conf_with_default_route_products_url_fn, dispatcher_debug): + dispatcher_state = start_dispatcher(pytestconfig.rootdir, dispatcher_test_conf_with_default_route_products_url_fn) + + service = dispatcher_state['url'] + pid = dispatcher_state['pid'] + + yield service + + kill_child_processes(pid, signal.SIGINT) + os.kill(pid, signal.SIGINT) + + @pytest.fixture def dispatcher_live_fixture_with_renku_options(pytestconfig, dispatcher_test_conf_with_renku_options_fn, dispatcher_debug): dispatcher_state = start_dispatcher(pytestconfig.rootdir, dispatcher_test_conf_with_renku_options_fn) diff --git a/requirements.txt b/requirements.txt index 275321ab..d5dd525e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,5 +36,5 @@ MarkupSafe==2.0.1 # TODO: needed by some plugins: migrate simple_logger matplotlib -validators==0.27.0 +validators==0.28.0 pillow>=10.0.1 # not directly required, pinned by Snyk to avoid a vulnerability \ No newline at end of file diff --git a/setup.py b/setup.py index 6c287ab5..f48ac152 100644 --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ "nbformat", "giturlparse", "sentry-sdk", - "validators==0.27.0", + "validators==0.28.0", "jsonschema" ] diff --git a/tests/conftest.py b/tests/conftest.py index fd6cd174..1f6659bd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -23,8 +23,11 @@ dispatcher_test_conf_with_gallery_fn, dispatcher_test_conf_with_gallery_no_resolver_fn, dispatcher_live_fixture_with_external_products_url, + dispatcher_live_fixture_with_default_route_products_url, dispatcher_test_conf_with_external_products_url_fn, + dispatcher_test_conf_with_default_route_products_url_fn, dispatcher_test_conf_with_external_products_url, + dispatcher_test_conf_with_default_route_products_url, dispatcher_test_conf_no_resubmit_timeout_fn, dispatcher_test_conf_with_matrix_options, dispatcher_test_conf_with_matrix_options_fn, diff --git a/tests/test_server_basic.py b/tests/test_server_basic.py index 69f3b100..f9305f96 100644 --- a/tests/test_server_basic.py +++ b/tests/test_server_basic.py @@ -660,6 +660,31 @@ def test_download_file_redirection_external_products_url(dispatcher_live_fixture assert redirection_url == redirection_header_location_url +@pytest.mark.fast +@pytest.mark.parametrize("include_args", [True, False]) +def test_download_file_redirection_default_route_products_url(dispatcher_live_fixture_with_default_route_products_url, + dispatcher_test_conf_with_default_route_products_url, + include_args): + server = dispatcher_live_fixture_with_default_route_products_url + + logger.info("constructed server: %s", server) + + url_request = os.path.join(server, "download_file") + + if include_args: + url_request += '?a=4566&token=aaaaaaaaaa' + + c = requests.get(url_request, allow_redirects=False) + + assert c.status_code == 302 + redirection_header_location_url = c.headers["Location"] + redirection_url = os.path.join(dispatcher_test_conf_with_default_route_products_url['products_url'], 'dispatch-data/download_products') + if include_args: + redirection_url += '?a=4566&token=aaaaaaaaaa' + redirection_url += '&from_request_files_dir=True&download_file=True&download_products=False' + assert redirection_url == redirection_header_location_url + + @pytest.mark.fast @pytest.mark.parametrize("include_args", [True, False]) def test_download_file_redirection_no_custom_products_url(dispatcher_live_fixture_no_products_url, @@ -854,6 +879,30 @@ def test_instrument_list_redirection_external_products_url(dispatcher_live_fixtu assert redirection_url == redirection_header_location_url +@pytest.mark.fast +@pytest.mark.parametrize("include_args", [True, False]) +def test_instrument_list_redirection_default_route_products_url(dispatcher_live_fixture_with_default_route_products_url, + dispatcher_test_conf_with_default_route_products_url, + include_args): + server = dispatcher_live_fixture_with_default_route_products_url + + logger.info("constructed server: %s", server) + + url_request = os.path.join(server, "api/instr-list") + + if include_args: + url_request += '?a=4566&token=aaaaaaaaaa' + + c = requests.get(url_request, allow_redirects=False) + + assert c.status_code == 302 + redirection_header_location_url = c.headers["Location"] + redirection_url = os.path.join(dispatcher_test_conf_with_default_route_products_url['products_url'], 'dispatch-data/instr-list') + if include_args: + redirection_url += '?a=4566&token=aaaaaaaaaa' + assert redirection_url == redirection_header_location_url + + @pytest.mark.fast @pytest.mark.parametrize("allow_redirect", [True, False]) @pytest.mark.parametrize("include_args", [True, False])