diff --git a/authentik/flows/stage.py b/authentik/flows/stage.py index 78964fb47..5792a4dfe 100644 --- a/authentik/flows/stage.py +++ b/authentik/flows/stage.py @@ -13,9 +13,11 @@ from authentik.flows.challenge import ( Challenge, ChallengeResponse, HttpChallengeResponse, + WithUserInfoChallenge, ) from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER from authentik.flows.views import FlowExecutorView +from authentik.lib.templatetags.authentik_utils import avatar PLAN_CONTEXT_PENDING_USER_IDENTIFIER = "pending_user_identifier" LOGGER = get_logger() @@ -78,9 +80,7 @@ class ChallengeStageView(StageView): return self.response_class(None, data=data, stage=self) def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: - challenge = self.get_challenge(*args, **kwargs) - if "title" not in challenge.initial_data: - challenge.initial_data["title"] = self.executor.flow.title + challenge = self._get_challenge(*args, **kwargs) if not challenge.is_valid(): LOGGER.warning(challenge.errors) return HttpChallengeResponse(challenge) @@ -93,6 +93,19 @@ class ChallengeStageView(StageView): return self.challenge_invalid(challenge) return self.challenge_valid(challenge) + def _get_challenge(self, *args, **kwargs) -> Challenge: + challenge = self.get_challenge(*args, **kwargs) + if "title" not in challenge.initial_data: + challenge.initial_data["title"] = self.executor.flow.title + if isinstance(challenge, WithUserInfoChallenge): + # If there's a pending user, update the `username` field + # this field is only used by password managers. + # If there's no user set, an error is raised later. + if user := self.get_pending_user(): + challenge.initial_data["pending_user"] = user.username + challenge.initial_data["pending_user_avatar"] = avatar(user) + return challenge + def get_challenge(self, *args, **kwargs) -> Challenge: """Return the challenge that the client should solve""" raise NotImplementedError @@ -103,8 +116,7 @@ class ChallengeStageView(StageView): def challenge_invalid(self, response: ChallengeResponse) -> HttpResponse: """Callback when the challenge has the incorrect format""" - challenge_response = self.get_challenge() - challenge_response.initial_data["title"] = self.executor.flow.title + challenge_response = self._get_challenge() full_errors = {} for field, errors in response.errors.items(): for error in errors: diff --git a/authentik/stages/password/stage.py b/authentik/stages/password/stage.py index 6311f332f..19f39b46c 100644 --- a/authentik/stages/password/stage.py +++ b/authentik/stages/password/stage.py @@ -22,7 +22,6 @@ from authentik.flows.challenge import ( from authentik.flows.models import Flow, FlowDesignation from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER from authentik.flows.stage import ChallengeStageView -from authentik.lib.templatetags.authentik_utils import avatar from authentik.lib.utils.reflection import path_to_class from authentik.stages.password.models import PasswordStage @@ -83,13 +82,6 @@ class PasswordStageView(ChallengeStageView): "component": "ak-stage-password", } ) - # If there's a pending user, update the `username` field - # this field is only used by password managers. - # If there's no user set, an error is raised later. - if user := self.get_pending_user(): - challenge.initial_data["pending_user"] = user.username - challenge.initial_data["pending_user_avatar"] = avatar(user) - recovery_flow = Flow.objects.filter(designation=FlowDesignation.RECOVERY) if recovery_flow.exists(): challenge.initial_data["recovery_url"] = reverse(