stages/authenticator_validate: fix handling when single configuration stage is selected

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-02-12 17:16:50 +01:00
parent 3bfcf18492
commit f336f204cb
1 changed files with 11 additions and 8 deletions

View File

@ -62,7 +62,7 @@ class AuthenticatorValidationChallengeResponse(ChallengeResponse):
component = CharField(default="ak-stage-authenticator-validate") component = CharField(default="ak-stage-authenticator-validate")
def _challenge_allowed(self, classes: list): def _challenge_allowed(self, classes: list):
device_challenges: list[dict] = self.stage.request.session.get("device_challenges") device_challenges: list[dict] = self.stage.request.session.get(SESSION_DEVICE_CHALLENGES)
if not any(x["device_class"] in classes for x in device_challenges): if not any(x["device_class"] in classes for x in device_challenges):
raise ValidationError("No compatible device class allowed") raise ValidationError("No compatible device class allowed")
@ -87,7 +87,7 @@ class AuthenticatorValidationChallengeResponse(ChallengeResponse):
def validate_selected_challenge(self, challenge: dict) -> dict: def validate_selected_challenge(self, challenge: dict) -> dict:
"""Check which challenge the user has selected. Actual logic only used for SMS stage.""" """Check which challenge the user has selected. Actual logic only used for SMS stage."""
# First check if the challenge is valid # First check if the challenge is valid
for device_challenge in self.stage.request.session.get("device_challenges"): for device_challenge in self.stage.request.session.get(SESSION_DEVICE_CHALLENGES):
if device_challenge.get("device_class", "") != challenge.get("device_class", ""): if device_challenge.get("device_class", "") != challenge.get("device_class", ""):
raise ValidationError("invalid challenge selected") raise ValidationError("invalid challenge selected")
if device_challenge.get("device_uid", "") != challenge.get("device_uid", ""): if device_challenge.get("device_uid", "") != challenge.get("device_uid", ""):
@ -220,16 +220,19 @@ class AuthenticatorValidateStageView(ChallengeStageView):
).from_http(self.request).set_user(user).save() ).from_http(self.request).set_user(user).save()
return self.executor.stage_invalid() return self.executor.stage_invalid()
if stage.configuration_stages.count() == 1: if stage.configuration_stages.count() == 1:
self.request.session[SESSION_SELECTED_STAGE] = stage.configuration_stages.first() next_stage = Stage.objects.get_subclass(pk=stage.configuration_stages.first().pk)
LOGGER.debug( LOGGER.debug("Single stage configured, auto-selecting", stage=next_stage)
"Single stage configured, auto-selecting", self.request.session[SESSION_SELECTED_STAGE] = next_stage
stage=self.request.session[SESSION_SELECTED_STAGE], # Because that normal insetion only happens on post, we directly inject it here and
) # return it
self.executor.plan.insert_stage(next_stage)
return self.executor.stage_ok()
stages = Stage.objects.filter(pk__in=stage.configuration_stages.all()).select_subclasses() stages = Stage.objects.filter(pk__in=stage.configuration_stages.all()).select_subclasses()
self.request.session[SESSION_STAGES] = stages self.request.session[SESSION_STAGES] = stages
return super().get(self.request, *args, **kwargs) return super().get(self.request, *args, **kwargs)
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
res = super().post(request, *args, **kwargs)
if ( if (
SESSION_SELECTED_STAGE in self.request.session SESSION_SELECTED_STAGE in self.request.session
and self.executor.current_stage.not_configured_action == NotConfiguredAction.CONFIGURE and self.executor.current_stage.not_configured_action == NotConfiguredAction.CONFIGURE
@ -243,7 +246,7 @@ class AuthenticatorValidateStageView(ChallengeStageView):
# the configuration stage is next # the configuration stage is next
self.executor.plan.insert_stage(stage) self.executor.plan.insert_stage(stage)
return self.executor.stage_ok() return self.executor.stage_ok()
return super().post(request, *args, **kwargs) return res
def get_challenge(self) -> AuthenticatorValidationChallenge: def get_challenge(self) -> AuthenticatorValidationChallenge:
challenges = self.request.session.get(SESSION_DEVICE_CHALLENGES, []) challenges = self.request.session.get(SESSION_DEVICE_CHALLENGES, [])