From 349572bfe4d527a851721d466cd5f9e2cbfd4635 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, 24 Jan 2025 18:40:02 +0100 Subject: [PATCH] flows: clear flow state before redirecting to final URL (cherry-pick #12788) (#12801) flows: clear flow state before redirecting to final URL (#12788) * providers/oauth2: clear flow state before redirecting to final URL * make flow executor invocation correct * actually we can do this centrally * make sure the state is really clean --------- Signed-off-by: Jens Langhammer Co-authored-by: Jens L. --- authentik/flows/planner.py | 9 ++++++++- authentik/flows/views/executor.py | 5 +++-- authentik/providers/oauth2/views/authorize.py | 4 ++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/authentik/flows/planner.py b/authentik/flows/planner.py index 1ede566e787c..d9688163e767 100644 --- a/authentik/flows/planner.py +++ b/authentik/flows/planner.py @@ -109,6 +109,8 @@ def next(self, http_request: HttpRequest | None) -> FlowStageBinding | None: def pop(self): """Pop next pending stage from bottom of list""" + if not self.markers and not self.bindings: + return self.markers.pop(0) self.bindings.pop(0) @@ -156,8 +158,13 @@ def to_redirect( final_stage: type[StageView] = self.bindings[-1].stage.view temp_exec = FlowExecutorView(flow=flow, request=request, plan=self) temp_exec.current_stage = self.bindings[-1].stage + temp_exec.current_stage_view = final_stage + temp_exec.setup(request, flow.slug) stage = final_stage(request=request, executor=temp_exec) - return stage.dispatch(request) + response = stage.dispatch(request) + # Ensure we clean the flow state we have in the session before we redirect away + temp_exec.stage_ok() + return response return redirect_with_qs( "authentik_core:if-flow", diff --git a/authentik/flows/views/executor.py b/authentik/flows/views/executor.py index 101913f13cbc..ad2eac6b05b1 100644 --- a/authentik/flows/views/executor.py +++ b/authentik/flows/views/executor.py @@ -103,7 +103,7 @@ class FlowExecutorView(APIView): permission_classes = [AllowAny] - flow: Flow + flow: Flow = None plan: FlowPlan | None = None current_binding: FlowStageBinding | None = None @@ -114,7 +114,8 @@ class FlowExecutorView(APIView): def setup(self, request: HttpRequest, flow_slug: str): super().setup(request, flow_slug=flow_slug) - self.flow = get_object_or_404(Flow.objects.select_related(), slug=flow_slug) + if not self.flow: + self.flow = get_object_or_404(Flow.objects.select_related(), slug=flow_slug) self._logger = get_logger().bind(flow_slug=flow_slug) set_tag("authentik.flow", self.flow.slug) diff --git a/authentik/providers/oauth2/views/authorize.py b/authentik/providers/oauth2/views/authorize.py index 3a4372c8f153..a0dd9bc15e8f 100644 --- a/authentik/providers/oauth2/views/authorize.py +++ b/authentik/providers/oauth2/views/authorize.py @@ -499,11 +499,11 @@ def redirect(self, uri: str) -> HttpResponse: ) challenge.is_valid() - + self.executor.stage_ok() return HttpChallengeResponse( challenge=challenge, ) - + self.executor.stage_ok() return HttpResponseRedirectScheme(uri, allowed_schemes=[parsed.scheme]) def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: