stages/authenticator_validate: fix stage not working without pending user (#5096)
closes #5094 Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
parent
0d6481c4d5
commit
4218ece2a5
|
@ -377,9 +377,7 @@ class AuthenticatorValidateStageView(ChallengeStageView):
|
|||
def challenge_valid(self, response: AuthenticatorValidationChallengeResponse) -> HttpResponse:
|
||||
# All validation is done by the serializer
|
||||
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
|
||||
if not user:
|
||||
if "webauthn" not in response.data:
|
||||
return self.executor.stage_invalid()
|
||||
if not user and "webauthn" in response.data:
|
||||
webauthn_device: WebAuthnDevice = response.device
|
||||
self.logger.debug("Set user from user-less flow", user=webauthn_device.user)
|
||||
self.executor.plan.context[PLAN_CONTEXT_PENDING_USER] = webauthn_device.user
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
"""Test validator stage"""
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from django.contrib.sessions.middleware import SessionMiddleware
|
||||
from django.test.client import RequestFactory
|
||||
from django.urls.base import reverse
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.flows.models import FlowStageBinding, NotConfiguredAction
|
||||
from authentik.flows.models import FlowDesignation, FlowStageBinding, NotConfiguredAction
|
||||
from authentik.flows.planner import FlowPlan
|
||||
from authentik.flows.stage import StageView
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import FlowExecutorView
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN, FlowExecutorView
|
||||
from authentik.lib.generators import generate_id, generate_key
|
||||
from authentik.lib.tests.utils import dummy_get_response
|
||||
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
|
||||
from authentik.stages.authenticator_validate.api import AuthenticatorValidateStageSerializer
|
||||
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage
|
||||
from authentik.stages.authenticator_validate.models import AuthenticatorValidateStage, DeviceClasses
|
||||
from authentik.stages.authenticator_validate.stage import (
|
||||
SESSION_KEY_DEVICE_CHALLENGES,
|
||||
AuthenticatorValidationChallengeResponse,
|
||||
|
@ -115,3 +119,57 @@ class AuthenticatorValidateStageTests(FlowTestCase):
|
|||
"device_uid": "1",
|
||||
}
|
||||
)
|
||||
|
||||
@patch(
|
||||
"authentik.stages.authenticator_duo.models.AuthenticatorDuoStage.auth_client",
|
||||
MagicMock(
|
||||
return_value=MagicMock(
|
||||
auth=MagicMock(
|
||||
return_value={
|
||||
"result": "allow",
|
||||
"status": "allow",
|
||||
"status_msg": "Success. Logging you in...",
|
||||
}
|
||||
)
|
||||
)
|
||||
),
|
||||
)
|
||||
def test_non_authentication_flow(self):
|
||||
"""Test full in an authorization flow (no pending user)"""
|
||||
self.client.force_login(self.user)
|
||||
duo_stage = AuthenticatorDuoStage.objects.create(
|
||||
name=generate_id(),
|
||||
client_id=generate_id(),
|
||||
client_secret=generate_key(),
|
||||
api_hostname="",
|
||||
)
|
||||
duo_device = DuoDevice.objects.create(
|
||||
user=self.user,
|
||||
stage=duo_stage,
|
||||
)
|
||||
|
||||
flow = create_test_flow(FlowDesignation.AUTHORIZATION)
|
||||
stage = AuthenticatorValidateStage.objects.create(
|
||||
name=generate_id(),
|
||||
device_classes=[DeviceClasses.DUO],
|
||||
)
|
||||
|
||||
plan = FlowPlan(flow_pk=flow.pk.hex)
|
||||
plan.append(FlowStageBinding.objects.create(target=flow, stage=stage, order=2))
|
||||
session = self.client.session
|
||||
session[SESSION_KEY_PLAN] = plan
|
||||
session.save()
|
||||
|
||||
response = self.client.get(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}),
|
||||
{"duo": duo_device.pk},
|
||||
follow=True,
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
|
|
Reference in a new issue