From 0fefd5f522b4d174e91cfc79642f97438a8b4de6 Mon Sep 17 00:00:00 2001 From: "gcp-cherry-pick-bot[bot]" <98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 13:17:18 +0100 Subject: [PATCH] stages/email: fix duplicate querystring encoding (cherry-pick #7386) (#7425) stages/email: fix duplicate querystring encoding (#7386) Signed-off-by: Jens Langhammer Co-authored-by: Jens L --- authentik/stages/email/stage.py | 14 ++++------ authentik/stages/email/tests/test_stage.py | 30 +--------------------- 2 files changed, 6 insertions(+), 38 deletions(-) diff --git a/authentik/stages/email/stage.py b/authentik/stages/email/stage.py index 85af0cade..1d8250274 100644 --- a/authentik/stages/email/stage.py +++ b/authentik/stages/email/stage.py @@ -52,17 +52,13 @@ class EmailStageView(ChallengeStageView): kwargs={"flow_slug": self.executor.flow.slug}, ) # Parse query string from current URL (full query string) - query_params = QueryDict(self.request.META.get("QUERY_STRING", ""), mutable=True) + # this view is only run within a flow executor, where we need to get the query string + # from the query= parameter (double encoded); but for the redirect + # we need to expand it since it'll go through the flow interface + query_params = QueryDict(self.request.GET.get(QS_QUERY), mutable=True) query_params.pop(QS_KEY_TOKEN, None) - - # Check for nested query string used by flow executor, and remove any - # kind of flow token from that - if QS_QUERY in query_params: - inner_query_params = QueryDict(query_params.get(QS_QUERY), mutable=True) - inner_query_params.pop(QS_KEY_TOKEN, None) - query_params[QS_QUERY] = inner_query_params.urlencode() - query_params.update(kwargs) + print(query_params) full_url = base_url if len(query_params) > 0: full_url = f"{full_url}?{query_params.urlencode()}" diff --git a/authentik/stages/email/tests/test_stage.py b/authentik/stages/email/tests/test_stage.py index a63d105d9..853bc2a77 100644 --- a/authentik/stages/email/tests/test_stage.py +++ b/authentik/stages/email/tests/test_stage.py @@ -259,7 +259,7 @@ class TestEmailStage(FlowTestCase): session.save() url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}) - url += "?foo=bar" + url += "?query=" + urlencode({"foo": "bar"}) request = self.factory.get(url) stage_view = EmailStageView( FlowExecutorView( @@ -273,31 +273,3 @@ class TestEmailStage(FlowTestCase): stage_view.get_full_url(**{QS_KEY_TOKEN: token}), f"http://testserver/if/flow/{self.flow.slug}/?foo=bar&flow_token={token}", ) - - def test_url_existing_params_nested(self): - """Test to ensure that URL params are preserved in the URL being sent (including nested)""" - plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()]) - plan.context[PLAN_CONTEXT_PENDING_USER] = self.user - session = self.client.session - session[SESSION_KEY_PLAN] = plan - session.save() - - url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}) - url += "?foo=bar&" - url += "query=" + urlencode({"nested": "value"}) - request = self.factory.get(url) - stage_view = EmailStageView( - FlowExecutorView( - request=request, - flow=self.flow, - ), - request=request, - ) - token = generate_id() - self.assertEqual( - stage_view.get_full_url(**{QS_KEY_TOKEN: token}), - ( - f"http://testserver/if/flow/{self.flow.slug}" - f"/?foo=bar&query=nested%3Dvalue&flow_token={token}" - ), - )