From 2c7323a87def2a60581c162db34783a48307e9aa Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Wed, 14 Sep 2022 18:00:11 -0300 Subject: [PATCH] fix: Supports form_data param in old Explore endpoint (#21469) --- superset/views/core.py | 37 ++++++++++++++++++++++++++- tests/integration_tests/core_tests.py | 14 ++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/superset/views/core.py b/superset/views/core.py index 859b42ad97d7..9b4b4dae5084 100755 --- a/superset/views/core.py +++ b/superset/views/core.py @@ -90,6 +90,7 @@ SupersetSecurityException, SupersetTimeoutException, ) +from superset.explore.form_data.commands.create import CreateFormDataCommand from superset.explore.form_data.commands.get import GetFormDataCommand from superset.explore.form_data.commands.parameters import CommandParameters from superset.explore.permalink.commands.get import GetExplorePermalinkCommand @@ -164,6 +165,7 @@ get_datasource_info, get_form_data, get_viz, + loads_request_json, sanitize_datasource_data, ) from superset.viz import BaseViz @@ -736,6 +738,39 @@ def import_dashboards(self) -> FlaskResponse: "superset/import_dashboards.html", databases=databases ) + @staticmethod + def get_redirect_url() -> str: + """Assembles the redirect URL to the new endpoint. It also replaces + the form_data param with a form_data_key by saving the original content + to the cache layer. + """ + redirect_url = request.url.replace("/superset/explore", "/explore") + form_data_key = None + request_form_data = request.args.get("form_data") + if request_form_data: + parsed_form_data = loads_request_json(request_form_data) + slice_id = parsed_form_data.get( + "slice_id", int(request.args.get("slice_id", 0)) + ) + datasource = parsed_form_data.get("datasource") + if datasource: + datasource_id, datasource_type = datasource.split("__") + parameters = CommandParameters( + datasource_id=datasource_id, + datasource_type=datasource_type, + chart_id=slice_id, + form_data=request_form_data, + ) + form_data_key = CreateFormDataCommand(parameters).run() + if form_data_key: + url = parse.urlparse(redirect_url) + query = parse.parse_qs(url.query) + query.pop("form_data") + query["form_data_key"] = [form_data_key] + url = url._replace(query=parse.urlencode(query, True)) + redirect_url = parse.urlunparse(url) + return redirect_url + @has_access @event_logger.log_this @expose("/explore///", methods=["GET", "POST"]) @@ -753,7 +788,7 @@ def explore( self.__class__.__name__, ) if request.method == "GET": - return redirect(request.url.replace("/superset/explore", "/explore")) + return redirect(Superset.get_redirect_url()) initial_form_data = {} diff --git a/tests/integration_tests/core_tests.py b/tests/integration_tests/core_tests.py index 75314c153330..f25d87d08a8f 100644 --- a/tests/integration_tests/core_tests.py +++ b/tests/integration_tests/core_tests.py @@ -1694,6 +1694,20 @@ def test_stop_query_not_implemented( assert rv.status_code == 422 + @pytest.mark.usefixtures("load_energy_table_with_slice") + @mock.patch("superset.explore.form_data.commands.create.CreateFormDataCommand.run") + def test_explore_redirect(self, mock_command: mock.Mock): + self.login(username="admin") + random_key = "random_key" + mock_command.return_value = random_key + slice_name = f"Energy Sankey" + slice_id = self.get_slice(slice_name, db.session).id + form_data = {"slice_id": slice_id, "viz_type": "line", "datasource": "1__table"} + rv = self.client.get( + f"/superset/explore/?form_data={quote(json.dumps(form_data))}" + ) + self.assertRedirects(rv, f"/explore/?form_data_key={random_key}") + if __name__ == "__main__": unittest.main()