flows: remove stage challenge type (#10476)
* flows: remove stage challenge type Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * improve coverage Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -8,7 +8,6 @@ from django.views import View
|
||||
from authentik.core.models import Application
|
||||
from authentik.flows.challenge import (
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
HttpChallengeResponse,
|
||||
RedirectChallenge,
|
||||
)
|
||||
@ -74,7 +73,6 @@ class RedirectToAppStage(ChallengeStageView):
|
||||
raise Http404
|
||||
return RedirectChallenge(
|
||||
instance={
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": launch,
|
||||
}
|
||||
)
|
||||
|
@ -32,14 +32,6 @@ class FlowLayout(models.TextChoices):
|
||||
SIDEBAR_RIGHT = "sidebar_right"
|
||||
|
||||
|
||||
class ChallengeTypes(Enum):
|
||||
"""Currently defined challenge types"""
|
||||
|
||||
NATIVE = "native"
|
||||
SHELL = "shell"
|
||||
REDIRECT = "redirect"
|
||||
|
||||
|
||||
class ErrorDetailSerializer(PassiveSerializer):
|
||||
"""Serializer for rest_framework's error messages"""
|
||||
|
||||
@ -60,9 +52,6 @@ class Challenge(PassiveSerializer):
|
||||
"""Challenge that gets sent to the client based on which stage
|
||||
is currently active"""
|
||||
|
||||
type = ChoiceField(
|
||||
choices=[(x.value, x.name) for x in ChallengeTypes],
|
||||
)
|
||||
flow_info = ContextualFlowInfo(required=False)
|
||||
component = CharField(default="")
|
||||
|
||||
@ -96,7 +85,6 @@ class FlowErrorChallenge(Challenge):
|
||||
"""Challenge class when an unhandled error occurs during a stage. Normal users
|
||||
are shown an error message, superusers are shown a full stacktrace."""
|
||||
|
||||
type = CharField(default=ChallengeTypes.NATIVE.value)
|
||||
component = CharField(default="ak-stage-flow-error")
|
||||
|
||||
request_id = CharField()
|
||||
|
@ -18,7 +18,6 @@ from authentik.flows.challenge import (
|
||||
AccessDeniedChallenge,
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
ContextualFlowInfo,
|
||||
HttpChallengeResponse,
|
||||
RedirectChallenge,
|
||||
@ -244,7 +243,6 @@ class AccessDeniedChallengeView(ChallengeStageView):
|
||||
return AccessDeniedChallenge(
|
||||
data={
|
||||
"error_message": str(self.error_message or "Unknown error"),
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-access-denied",
|
||||
}
|
||||
)
|
||||
@ -264,7 +262,6 @@ class RedirectStage(ChallengeStageView):
|
||||
)
|
||||
return RedirectChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": destination,
|
||||
}
|
||||
)
|
||||
|
@ -8,7 +8,6 @@ from django.urls.base import reverse
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.models import Flow
|
||||
|
||||
|
||||
@ -26,7 +25,6 @@ class FlowTestCase(APITestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
raw_response = loads(response.content.decode())
|
||||
self.assertIsNotNone(raw_response["component"])
|
||||
self.assertIsNotNone(raw_response["type"])
|
||||
if flow:
|
||||
self.assertIn("flow_info", raw_response)
|
||||
self.assertEqual(raw_response["flow_info"]["background"], flow.background_url)
|
||||
@ -46,6 +44,4 @@ class FlowTestCase(APITestCase):
|
||||
|
||||
def assertStageRedirects(self, response: HttpResponse, to: str) -> dict[str, Any]:
|
||||
"""Wrapper around assertStageResponse that checks for a redirect"""
|
||||
return self.assertStageResponse(
|
||||
response, component="xak-flow-redirect", to=to, type=ChallengeTypes.REDIRECT.value
|
||||
)
|
||||
return self.assertStageResponse(response, component="xak-flow-redirect", to=to)
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from authentik.flows.challenge import AutosubmitChallenge, ChallengeTypes
|
||||
from authentik.flows.challenge import AutosubmitChallenge
|
||||
|
||||
|
||||
class TestChallenges(TestCase):
|
||||
@ -12,7 +12,6 @@ class TestChallenges(TestCase):
|
||||
"""Test blank autosubmit"""
|
||||
challenge = AutosubmitChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"url": "http://localhost",
|
||||
"attrs": {},
|
||||
}
|
||||
@ -21,7 +20,6 @@ class TestChallenges(TestCase):
|
||||
# Test with an empty value
|
||||
challenge = AutosubmitChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"url": "http://localhost",
|
||||
"attrs": {"foo": ""},
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ from django.urls.base import reverse
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.models import FlowDesignation, FlowStageBinding, InvalidResponseAction
|
||||
from authentik.stages.dummy.models import DummyStage
|
||||
from authentik.stages.identification.models import IdentificationStage, UserFields
|
||||
@ -54,7 +53,6 @@ class TestFlowInspector(APITestCase):
|
||||
"layout": "stacked",
|
||||
},
|
||||
"flow_designation": "authentication",
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"password_fields": False,
|
||||
"primary_action": "Log in",
|
||||
"sources": [],
|
||||
|
@ -30,7 +30,6 @@ from authentik.flows.apps import HIST_FLOW_EXECUTION_STAGE_TIME
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
FlowErrorChallenge,
|
||||
HttpChallengeResponse,
|
||||
RedirectChallenge,
|
||||
@ -552,7 +551,6 @@ def to_stage_response(request: HttpRequest, source: HttpResponse) -> HttpRespons
|
||||
return HttpChallengeResponse(
|
||||
RedirectChallenge(
|
||||
{
|
||||
"type": ChallengeTypes.REDIRECT,
|
||||
"to": str(redirect_url),
|
||||
}
|
||||
)
|
||||
@ -561,7 +559,6 @@ def to_stage_response(request: HttpRequest, source: HttpResponse) -> HttpRespons
|
||||
return HttpChallengeResponse(
|
||||
ShellChallenge(
|
||||
{
|
||||
"type": ChallengeTypes.SHELL,
|
||||
"body": source.render().content.decode("utf-8"),
|
||||
}
|
||||
)
|
||||
@ -571,7 +568,6 @@ def to_stage_response(request: HttpRequest, source: HttpResponse) -> HttpRespons
|
||||
return HttpChallengeResponse(
|
||||
ShellChallenge(
|
||||
{
|
||||
"type": ChallengeTypes.SHELL,
|
||||
"body": source.content.decode("utf-8"),
|
||||
}
|
||||
)
|
||||
|
@ -10,7 +10,6 @@ from authentik.blueprints.tests import apply_blueprint
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
from authentik.providers.oauth2.constants import TOKEN_TYPE
|
||||
@ -327,7 +326,6 @@ class TestAuthorize(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": f"foo://localhost?code={code.code}&state={state}",
|
||||
},
|
||||
)
|
||||
@ -397,7 +395,6 @@ class TestAuthorize(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": (
|
||||
f"http://localhost#access_token={token.token}"
|
||||
f"&id_token={provider.encode(token.id_token.to_dict())}"
|
||||
@ -460,7 +457,6 @@ class TestAuthorize(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": (f"http://localhost#code={code.code}" f"&state={state}"),
|
||||
},
|
||||
)
|
||||
@ -516,7 +512,6 @@ class TestAuthorize(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "ak-stage-autosubmit",
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"url": "http://localhost",
|
||||
"title": f"Redirecting to {app.name}...",
|
||||
"attrs": {
|
||||
@ -564,7 +559,6 @@ class TestAuthorize(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "ak-stage-autosubmit",
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"url": "http://localhost",
|
||||
"title": f"Redirecting to {app.name}...",
|
||||
"attrs": {
|
||||
|
@ -8,7 +8,6 @@ from django.urls import reverse
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.providers.oauth2.constants import GRANT_TYPE_AUTHORIZATION_CODE
|
||||
from authentik.providers.oauth2.models import AuthorizationCode, OAuth2Provider
|
||||
@ -60,7 +59,6 @@ class TestTokenPKCE(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": f"foo://localhost?code={code.code}&state={state}",
|
||||
},
|
||||
)
|
||||
@ -123,7 +121,6 @@ class TestTokenPKCE(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": f"foo://localhost?code={code.code}&state={state}",
|
||||
},
|
||||
)
|
||||
@ -191,7 +188,6 @@ class TestTokenPKCE(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": f"foo://localhost?code={code.code}&state={state}",
|
||||
},
|
||||
)
|
||||
@ -242,7 +238,6 @@ class TestTokenPKCE(OAuthTestCase):
|
||||
response.content.decode(),
|
||||
{
|
||||
"component": "xak-flow-redirect",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": f"foo://localhost?code={code.code}&state={state}",
|
||||
},
|
||||
)
|
||||
|
@ -22,7 +22,6 @@ from authentik.events.signals import get_login_event
|
||||
from authentik.flows.challenge import (
|
||||
PLAN_CONTEXT_TITLE,
|
||||
AutosubmitChallenge,
|
||||
ChallengeTypes,
|
||||
HttpChallengeResponse,
|
||||
)
|
||||
from authentik.flows.exceptions import FlowNonApplicableException
|
||||
@ -484,7 +483,6 @@ class OAuthFulfillmentStage(StageView):
|
||||
|
||||
challenge = AutosubmitChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-autosubmit",
|
||||
"title": self.executor.plan.context.get(
|
||||
PLAN_CONTEXT_TITLE,
|
||||
|
@ -3,7 +3,7 @@
|
||||
from django.http import HttpResponse
|
||||
from rest_framework.fields import CharField
|
||||
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||
from authentik.flows.planner import FlowPlan
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
@ -38,7 +38,6 @@ class OAuthDeviceCodeFinishStage(ChallengeStageView):
|
||||
token.save()
|
||||
return OAuthDeviceCodeFinishChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-provider-oauth2-device-code-finish",
|
||||
}
|
||||
)
|
||||
|
@ -10,7 +10,7 @@ from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.brands.models import Brand
|
||||
from authentik.core.models import Application
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||
from authentik.flows.exceptions import FlowNonApplicableException
|
||||
from authentik.flows.models import in_memory_stage
|
||||
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_SSO, FlowPlanner
|
||||
@ -141,7 +141,6 @@ class OAuthDeviceCodeStage(ChallengeStageView):
|
||||
def get_challenge(self, *args, **kwargs) -> Challenge:
|
||||
return OAuthDeviceCodeChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-provider-oauth2-device-code",
|
||||
}
|
||||
)
|
||||
|
@ -16,7 +16,6 @@ from authentik.flows.challenge import (
|
||||
AutoSubmitChallengeResponse,
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
)
|
||||
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
@ -81,7 +80,6 @@ class SAMLFlowFinalView(ChallengeStageView):
|
||||
return super().get(
|
||||
self.request,
|
||||
**{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-autosubmit",
|
||||
"title": self.executor.plan.context.get(
|
||||
PLAN_CONTEXT_TITLE,
|
||||
|
@ -148,7 +148,6 @@ SPECTACULAR_SETTINGS = {
|
||||
},
|
||||
"ENUM_NAME_OVERRIDES": {
|
||||
"EventActions": "authentik.events.models.EventAction",
|
||||
"ChallengeChoices": "authentik.flows.challenge.ChallengeTypes",
|
||||
"FlowDesignationEnum": "authentik.flows.models.FlowDesignation",
|
||||
"FlowLayoutEnum": "authentik.flows.models.FlowLayout",
|
||||
"PolicyEngineMode": "authentik.policies.models.PolicyEngineMode",
|
||||
|
@ -9,7 +9,7 @@ from jwt import decode, encode
|
||||
from rest_framework.fields import CharField
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||
from authentik.sources.oauth.clients.oauth2 import OAuth2Client
|
||||
from authentik.sources.oauth.models import OAuthSource
|
||||
from authentik.sources.oauth.types.registry import SourceType, registry
|
||||
@ -130,6 +130,5 @@ class AppleType(SourceType):
|
||||
"scope": "name email",
|
||||
"redirect_uri": args["redirect_uri"],
|
||||
"state": args["state"],
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
}
|
||||
)
|
||||
|
@ -8,7 +8,7 @@ from django.templatetags.static import static
|
||||
from django.urls.base import reverse
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.flows.challenge import Challenge, ChallengeTypes, RedirectChallenge
|
||||
from authentik.flows.challenge import Challenge, RedirectChallenge
|
||||
from authentik.sources.oauth.models import OAuthSource
|
||||
from authentik.sources.oauth.views.callback import OAuthCallback
|
||||
from authentik.sources.oauth.views.redirect import OAuthRedirect
|
||||
@ -48,7 +48,6 @@ class SourceType:
|
||||
"""Allow types to return custom challenges"""
|
||||
return RedirectChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": reverse(
|
||||
"authentik_sources_oauth:oauth-client-login",
|
||||
kwargs={"source_slug": source.slug},
|
||||
|
@ -10,7 +10,7 @@ from rest_framework.serializers import BaseSerializer, Serializer
|
||||
|
||||
from authentik.core.models import Source, UserSourceConnection
|
||||
from authentik.core.types import UILoginButton, UserSettingSerializer
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||
from authentik.lib.generators import generate_id
|
||||
|
||||
|
||||
@ -71,7 +71,6 @@ class PlexSource(Source):
|
||||
return UILoginButton(
|
||||
challenge=PlexAuthenticationChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-source-plex",
|
||||
"client_id": self.client_id,
|
||||
"slug": self.slug,
|
||||
|
@ -10,7 +10,7 @@ from rest_framework.serializers import Serializer
|
||||
from authentik.core.models import Source, UserSourceConnection
|
||||
from authentik.core.types import UILoginButton, UserSettingSerializer
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.flows.challenge import ChallengeTypes, RedirectChallenge
|
||||
from authentik.flows.challenge import RedirectChallenge
|
||||
from authentik.flows.models import Flow
|
||||
from authentik.lib.utils.time import timedelta_string_validator
|
||||
from authentik.sources.saml.processors.constants import (
|
||||
@ -204,7 +204,6 @@ class SAMLSource(Source):
|
||||
return UILoginButton(
|
||||
challenge=RedirectChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
"to": reverse(
|
||||
"authentik_sources_saml:login",
|
||||
kwargs={"source_slug": self.slug},
|
||||
|
@ -21,7 +21,6 @@ from authentik.flows.challenge import (
|
||||
AutosubmitChallenge,
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
)
|
||||
from authentik.flows.exceptions import FlowNonApplicableException
|
||||
from authentik.flows.models import in_memory_stage
|
||||
@ -52,7 +51,6 @@ class AutosubmitStageView(ChallengeStageView):
|
||||
def get_challenge(self, *args, **kwargs) -> Challenge:
|
||||
return AutosubmitChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-autosubmit",
|
||||
"title": self.executor.plan.context.get(PLAN_CONTEXT_TITLE, ""),
|
||||
"url": self.executor.plan.context.get(PLAN_CONTEXT_URL, ""),
|
||||
|
@ -8,7 +8,6 @@ from authentik.events.models import Event, EventAction
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
@ -61,7 +60,6 @@ class AuthenticatorDuoStageView(ChallengeStageView):
|
||||
enroll = self.request.session[SESSION_KEY_DUO_ENROLL]
|
||||
return AuthenticatorDuoChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"activation_barcode": enroll["activation_barcode"],
|
||||
"activation_code": enroll["activation_code"],
|
||||
"stage_uuid": str(stage.stage_uuid),
|
||||
|
@ -10,7 +10,6 @@ from rest_framework.fields import BooleanField, CharField, IntegerField
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
@ -90,7 +89,6 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
def get_challenge(self, *args, **kwargs) -> Challenge:
|
||||
return AuthenticatorSMSChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"phone_number_required": self._has_phone_number() is None,
|
||||
}
|
||||
)
|
||||
|
@ -3,7 +3,7 @@
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from rest_framework.fields import CharField, ListField
|
||||
|
||||
from authentik.flows.challenge import ChallengeResponse, ChallengeTypes, WithUserInfoChallenge
|
||||
from authentik.flows.challenge import ChallengeResponse, WithUserInfoChallenge
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.stages.authenticator_static.models import (
|
||||
@ -38,7 +38,6 @@ class AuthenticatorStaticStageView(ChallengeStageView):
|
||||
tokens: list[StaticToken] = self.request.session[SESSION_STATIC_TOKENS]
|
||||
return AuthenticatorStaticChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"codes": [token.token for token in tokens],
|
||||
}
|
||||
)
|
||||
|
@ -11,7 +11,6 @@ from rest_framework.serializers import ValidationError
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
@ -55,7 +54,6 @@ class AuthenticatorTOTPStageView(ChallengeStageView):
|
||||
device: TOTPDevice = self.request.session[SESSION_TOTP_DEVICE]
|
||||
return AuthenticatorTOTPChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"config_url": device.config_url.replace(
|
||||
OTP_TOTP_ISSUER, quote(self.request.brand.branding_title)
|
||||
),
|
||||
|
@ -13,7 +13,7 @@ from rest_framework.serializers import ValidationError
|
||||
from authentik.core.api.utils import JSONDictField, PassiveSerializer
|
||||
from authentik.core.models import User
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.flows.challenge import ChallengeResponse, ChallengeTypes, WithUserInfoChallenge
|
||||
from authentik.flows.challenge import ChallengeResponse, WithUserInfoChallenge
|
||||
from authentik.flows.exceptions import FlowSkipStageException, StageInvalidException
|
||||
from authentik.flows.models import FlowDesignation, NotConfiguredAction, Stage
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
|
||||
@ -337,7 +337,6 @@ class AuthenticatorValidateStageView(ChallengeStageView):
|
||||
return AuthenticatorValidationChallenge(
|
||||
data={
|
||||
"component": "ak-stage-authenticator-validate",
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"device_challenges": challenges,
|
||||
"configuration_stages": stage_challenges,
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ from authentik.core.models import User
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
@ -144,7 +143,6 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||
self.request.session.save()
|
||||
return AuthenticatorWebAuthnChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"registration": loads(options_to_json(registration_options)),
|
||||
}
|
||||
)
|
||||
|
@ -9,7 +9,6 @@ from rest_framework.serializers import ValidationError
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
@ -80,7 +79,6 @@ class CaptchaStageView(ChallengeStageView):
|
||||
return CaptchaChallenge(
|
||||
data={
|
||||
"js_url": self.executor.current_stage.js_url,
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"site_key": self.executor.current_stage.public_key,
|
||||
}
|
||||
)
|
||||
|
@ -10,7 +10,6 @@ from authentik.core.api.utils import PassiveSerializer
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, PLAN_CONTEXT_PENDING_USER
|
||||
@ -58,7 +57,6 @@ class ConsentStageView(ChallengeStageView):
|
||||
token = str(uuid4())
|
||||
self.request.session[SESSION_KEY_CONSENT_TOKEN] = token
|
||||
data = {
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"permissions": self.executor.plan.context.get(PLAN_CONTEXT_CONSENT_PERMISSIONS, []),
|
||||
"additional_permissions": self.executor.plan.context.get(
|
||||
PLAN_CONTEXT_CONSENT_EXTRA_PERMISSIONS, []
|
||||
|
@ -3,7 +3,7 @@
|
||||
from django.http.response import HttpResponse
|
||||
from rest_framework.fields import CharField
|
||||
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.lib.sentry import SentryIgnoredException
|
||||
|
||||
@ -34,7 +34,6 @@ class DummyStageView(ChallengeStageView):
|
||||
raise SentryIgnoredException("Test error")
|
||||
return DummyChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"title": self.executor.current_stage.name,
|
||||
"name": self.executor.current_stage.name,
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ from rest_framework.fields import CharField
|
||||
from rest_framework.serializers import ValidationError
|
||||
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||
from authentik.flows.exceptions import StageInvalidException
|
||||
from authentik.flows.models import FlowDesignation, FlowToken
|
||||
from authentik.flows.planner import PLAN_CONTEXT_IS_RESTORED, PLAN_CONTEXT_PENDING_USER
|
||||
@ -160,7 +160,6 @@ class EmailStageView(ChallengeStageView):
|
||||
def get_challenge(self) -> Challenge:
|
||||
challenge = EmailChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"title": _("Email sent."),
|
||||
}
|
||||
)
|
||||
|
@ -20,7 +20,6 @@ from authentik.events.utils import sanitize_item
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
RedirectChallenge,
|
||||
)
|
||||
from authentik.flows.models import FlowDesignation
|
||||
@ -194,7 +193,6 @@ class IdentificationStageView(ChallengeStageView):
|
||||
current_stage: IdentificationStage = self.executor.current_stage
|
||||
challenge = IdentificationChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-identification",
|
||||
"primary_action": self.get_primary_action(),
|
||||
"user_fields": current_stage.user_fields,
|
||||
|
@ -4,7 +4,6 @@ from django.urls import reverse
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.models import FlowDesignation, FlowStageBinding
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.lib.generators import generate_id
|
||||
@ -90,7 +89,6 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
@ -126,7 +124,6 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
@ -189,7 +186,6 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
@ -240,7 +236,6 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
}
|
||||
],
|
||||
@ -276,7 +271,6 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
@ -304,7 +298,6 @@ class TestIdentificationStage(FlowTestCase):
|
||||
"challenge": {
|
||||
"component": "xak-flow-redirect",
|
||||
"to": "/source/oauth/login/test/",
|
||||
"type": ChallengeTypes.REDIRECT.value,
|
||||
},
|
||||
"icon_url": "/static/authentik/sources/default.svg",
|
||||
"name": "test",
|
||||
|
@ -18,7 +18,6 @@ from authentik.core.signals import login_failed
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.exceptions import StageInvalidException
|
||||
@ -135,11 +134,7 @@ class PasswordStageView(ChallengeStageView):
|
||||
response_class = PasswordChallengeResponse
|
||||
|
||||
def get_challenge(self) -> Challenge:
|
||||
challenge = PasswordChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
}
|
||||
)
|
||||
challenge = PasswordChallenge(data={})
|
||||
recovery_flow = Flow.objects.filter(designation=FlowDesignation.RECOVERY)
|
||||
if recovery_flow.exists():
|
||||
recover_url = reverse(
|
||||
|
@ -11,7 +11,7 @@ from rest_framework.viewsets import ModelViewSet
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.expression.exceptions import PropertyMappingExpressionException
|
||||
from authentik.flows.api.stages import StageSerializer
|
||||
from authentik.flows.challenge import ChallengeTypes, HttpChallengeResponse
|
||||
from authentik.flows.challenge import HttpChallengeResponse
|
||||
from authentik.flows.planner import FlowPlan
|
||||
from authentik.flows.views.executor import FlowExecutorView
|
||||
from authentik.lib.generators import generate_id
|
||||
@ -115,7 +115,6 @@ class PromptViewSet(UsedByMixin, ModelViewSet):
|
||||
)
|
||||
challenge = PromptChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"fields": fields,
|
||||
},
|
||||
)
|
||||
|
@ -21,7 +21,7 @@ from rest_framework.serializers import ValidationError
|
||||
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||
from authentik.flows.planner import FlowPlan
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.policies.engine import PolicyEngine
|
||||
@ -227,7 +227,6 @@ class PromptStageView(ChallengeStageView):
|
||||
serializers = self.get_prompt_challenge_fields(fields, context_prompt)
|
||||
challenge = PromptChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"fields": serializers,
|
||||
},
|
||||
)
|
||||
|
@ -7,7 +7,6 @@ from django.urls import reverse
|
||||
from rest_framework.exceptions import ErrorDetail, ValidationError
|
||||
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.flows.challenge import ChallengeTypes
|
||||
from authentik.flows.markers import StageMarker
|
||||
from authentik.flows.models import FlowStageBinding
|
||||
from authentik.flows.planner import FlowPlan
|
||||
@ -596,7 +595,6 @@ class TestPromptStage(FlowTestCase):
|
||||
self.assertJSONEqual(
|
||||
response.content.decode(),
|
||||
{
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"component": "ak-stage-prompt",
|
||||
"fields": [
|
||||
{
|
||||
|
@ -10,7 +10,7 @@ from rest_framework.fields import BooleanField, CharField
|
||||
|
||||
from authentik.core.models import AuthenticatedSession, User
|
||||
from authentik.events.middleware import audit_ignore
|
||||
from authentik.flows.challenge import ChallengeResponse, ChallengeTypes, WithUserInfoChallenge
|
||||
from authentik.flows.challenge import ChallengeResponse, WithUserInfoChallenge
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, PLAN_CONTEXT_SOURCE
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
@ -45,11 +45,7 @@ class UserLoginStageView(ChallengeStageView):
|
||||
response_class = UserLoginChallengeResponse
|
||||
|
||||
def get_challenge(self, *args, **kwargs) -> UserLoginChallenge:
|
||||
return UserLoginChallenge(
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
}
|
||||
)
|
||||
return UserLoginChallenge(data={})
|
||||
|
||||
def dispatch(self, request: HttpRequest) -> HttpResponse:
|
||||
"""Check for remember_me, and do login"""
|
||||
|
@ -129,6 +129,11 @@ class TestUserLoginStage(FlowTestCase):
|
||||
session[SESSION_KEY_PLAN] = plan
|
||||
session.save()
|
||||
|
||||
response = self.client.get(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
)
|
||||
self.assertStageResponse(response, component="ak-stage-user-login")
|
||||
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
data={"remember_me": True},
|
||||
|
@ -8,6 +8,7 @@ const (
|
||||
StageIdentification = StageComponent("ak-stage-identification")
|
||||
StagePassword = StageComponent("ak-stage-password")
|
||||
StageUserLogin = StageComponent("ak-stage-user-login")
|
||||
StageRedirect = StageComponent("xak-flow-redirect")
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -110,9 +110,8 @@ func (fe *FlowExecutor) ApiClient() *api.APIClient {
|
||||
return fe.api
|
||||
}
|
||||
|
||||
type challengeInt interface {
|
||||
type challengeCommon interface {
|
||||
GetComponent() string
|
||||
GetType() api.ChallengeChoices
|
||||
GetResponseErrors() map[string][]api.ErrorDetail
|
||||
}
|
||||
|
||||
@ -181,9 +180,8 @@ func (fe *FlowExecutor) getInitialChallenge() (*api.ChallengeTypes, error) {
|
||||
if i == nil {
|
||||
return nil, errors.New("response instance was null")
|
||||
}
|
||||
ch := i.(challengeInt)
|
||||
fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got challenge")
|
||||
gcsp.SetTag("authentik.flow.challenge", string(ch.GetType()))
|
||||
ch := i.(challengeCommon)
|
||||
fe.log.WithField("component", ch.GetComponent()).Debug("Got challenge")
|
||||
gcsp.SetTag("authentik.flow.component", ch.GetComponent())
|
||||
gcsp.Finish()
|
||||
FlowTimingGet.With(prometheus.Labels{
|
||||
@ -201,7 +199,7 @@ func (fe *FlowExecutor) solveFlowChallenge(challenge *api.ChallengeTypes, depth
|
||||
if i == nil {
|
||||
return false, errors.New("response request instance was null")
|
||||
}
|
||||
ch := i.(challengeInt)
|
||||
ch := i.(challengeCommon)
|
||||
|
||||
// Check for any validation errors that we might've gotten
|
||||
if len(ch.GetResponseErrors()) > 0 {
|
||||
@ -212,13 +210,12 @@ func (fe *FlowExecutor) solveFlowChallenge(challenge *api.ChallengeTypes, depth
|
||||
}
|
||||
}
|
||||
|
||||
switch ch.GetType() {
|
||||
case api.CHALLENGECHOICES_REDIRECT:
|
||||
switch ch.GetComponent() {
|
||||
case string(StageAccessDenied):
|
||||
return false, nil
|
||||
case string(StageRedirect):
|
||||
return true, nil
|
||||
case api.CHALLENGECHOICES_NATIVE:
|
||||
if ch.GetComponent() == string(StageAccessDenied) {
|
||||
return false, nil
|
||||
}
|
||||
default:
|
||||
solver, ok := fe.solvers[StageComponent(ch.GetComponent())]
|
||||
if !ok {
|
||||
return false, fmt.Errorf("unsupported challenge type %s", ch.GetComponent())
|
||||
@ -238,9 +235,8 @@ func (fe *FlowExecutor) solveFlowChallenge(challenge *api.ChallengeTypes, depth
|
||||
if i == nil {
|
||||
return false, errors.New("response instance was null")
|
||||
}
|
||||
ch = i.(challengeInt)
|
||||
fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got response")
|
||||
scsp.SetTag("authentik.flow.challenge", string(ch.GetType()))
|
||||
ch = i.(challengeCommon)
|
||||
fe.log.WithField("component", ch.GetComponent()).Debug("Got response")
|
||||
scsp.SetTag("authentik.flow.component", ch.GetComponent())
|
||||
scsp.Finish()
|
||||
FlowTimingPost.With(prometheus.Labels{
|
||||
|
13
internal/outpost/flow/executor_test.go
Normal file
13
internal/outpost/flow/executor_test.go
Normal file
@ -0,0 +1,13 @@
|
||||
package flow
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"goauthentik.io/api/v3"
|
||||
)
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
var a challengeCommon = api.NewIdentificationChallengeWithDefaults()
|
||||
assert.NotNil(t, a)
|
||||
}
|
78
schema.yml
78
schema.yml
@ -32844,8 +32844,6 @@ components:
|
||||
type: object
|
||||
description: Challenge when a flow's active stage calls `stage_invalid()`.
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -32866,7 +32864,6 @@ components:
|
||||
required:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
AlgEnum:
|
||||
enum:
|
||||
- rsa
|
||||
@ -32955,8 +32952,6 @@ components:
|
||||
description: Special challenge for apple-native authentication flow, which happens
|
||||
on the client.
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -32981,7 +32976,6 @@ components:
|
||||
- redirect_uri
|
||||
- scope
|
||||
- state
|
||||
- type
|
||||
Application:
|
||||
type: object
|
||||
description: Application Serializer
|
||||
@ -33252,8 +33246,6 @@ components:
|
||||
type: object
|
||||
description: Duo Challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -33281,7 +33273,6 @@ components:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- stage_uuid
|
||||
- type
|
||||
AuthenticatorDuoChallengeResponseRequest:
|
||||
type: object
|
||||
description: Pseudo class for duo response
|
||||
@ -33414,8 +33405,6 @@ components:
|
||||
type: object
|
||||
description: SMS Setup challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -33437,7 +33426,6 @@ components:
|
||||
required:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
AuthenticatorSMSChallengeResponseRequest:
|
||||
type: object
|
||||
description: SMS Challenge response, device is set by get_response_instance
|
||||
@ -33580,8 +33568,6 @@ components:
|
||||
type: object
|
||||
description: Static authenticator challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -33605,7 +33591,6 @@ components:
|
||||
- codes
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
AuthenticatorStaticChallengeResponseRequest:
|
||||
type: object
|
||||
description: Pseudo class for static response
|
||||
@ -33704,8 +33689,6 @@ components:
|
||||
type: object
|
||||
description: TOTP Setup challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -33727,7 +33710,6 @@ components:
|
||||
- config_url
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
AuthenticatorTOTPChallengeResponseRequest:
|
||||
type: object
|
||||
description: TOTP Challenge response, device is set by get_response_instance
|
||||
@ -33934,8 +33916,6 @@ components:
|
||||
type: object
|
||||
description: Authenticator challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -33964,7 +33944,6 @@ components:
|
||||
- device_challenges
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
AuthenticatorValidationChallengeResponseRequest:
|
||||
type: object
|
||||
description: Challenge used for Code-based and WebAuthn authenticators
|
||||
@ -33990,8 +33969,6 @@ components:
|
||||
type: object
|
||||
description: WebAuthn Challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -34014,7 +33991,6 @@ components:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- registration
|
||||
- type
|
||||
AuthenticatorWebAuthnChallengeResponseRequest:
|
||||
type: object
|
||||
description: WebAuthn Challenge response
|
||||
@ -34142,8 +34118,6 @@ components:
|
||||
type: object
|
||||
description: Autosubmit challenge used to send and navigate a POST request
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -34165,7 +34139,6 @@ components:
|
||||
type: string
|
||||
required:
|
||||
- attrs
|
||||
- type
|
||||
- url
|
||||
BackendsEnum:
|
||||
enum:
|
||||
@ -34395,8 +34368,6 @@ components:
|
||||
type: object
|
||||
description: Site public key
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -34421,7 +34392,6 @@ components:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- site_key
|
||||
- type
|
||||
CaptchaChallengeResponseRequest:
|
||||
type: object
|
||||
description: Validate captcha token
|
||||
@ -34652,12 +34622,6 @@ components:
|
||||
required:
|
||||
- certificate_data
|
||||
- name
|
||||
ChallengeChoices:
|
||||
enum:
|
||||
- native
|
||||
- shell
|
||||
- redirect
|
||||
type: string
|
||||
ChallengeTypes:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/AccessDeniedChallenge'
|
||||
@ -34790,8 +34754,6 @@ components:
|
||||
type: object
|
||||
description: Challenge info for consent screens
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -34825,7 +34787,6 @@ components:
|
||||
- pending_user_avatar
|
||||
- permissions
|
||||
- token
|
||||
- type
|
||||
ConsentChallengeResponseRequest:
|
||||
type: object
|
||||
description: Consent challenge response, any valid response request is valid
|
||||
@ -35274,8 +35235,6 @@ components:
|
||||
type: object
|
||||
description: Dummy challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -35291,7 +35250,6 @@ components:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- type
|
||||
DummyChallengeResponseRequest:
|
||||
type: object
|
||||
description: Dummy challenge response
|
||||
@ -35474,8 +35432,6 @@ components:
|
||||
type: object
|
||||
description: Email challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -35487,8 +35443,6 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ErrorDetail'
|
||||
required:
|
||||
- type
|
||||
EmailChallengeResponseRequest:
|
||||
type: object
|
||||
description: |-
|
||||
@ -36314,9 +36268,6 @@ components:
|
||||
Challenge class when an unhandled error occurs during a stage. Normal users
|
||||
are shown an error message, superusers are shown a full stacktrace.
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
default: native
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -37098,8 +37049,6 @@ components:
|
||||
type: object
|
||||
description: Identification challenges with all UI elements
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -37141,7 +37090,6 @@ components:
|
||||
- password_fields
|
||||
- primary_action
|
||||
- show_source_labels
|
||||
- type
|
||||
- user_fields
|
||||
IdentificationChallengeResponseRequest:
|
||||
type: object
|
||||
@ -39160,8 +39108,6 @@ components:
|
||||
type: object
|
||||
description: OAuth Device code challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -39173,8 +39119,6 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ErrorDetail'
|
||||
required:
|
||||
- type
|
||||
OAuthDeviceCodeChallengeResponseRequest:
|
||||
type: object
|
||||
description: Response that includes the user-entered device code
|
||||
@ -39191,8 +39135,6 @@ components:
|
||||
type: object
|
||||
description: Final challenge after user enters their code
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -39204,8 +39146,6 @@ components:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ErrorDetail'
|
||||
required:
|
||||
- type
|
||||
OAuthDeviceCodeFinishChallengeResponseRequest:
|
||||
type: object
|
||||
description: Response that device has been authenticated and tab can be closed
|
||||
@ -40996,8 +40936,6 @@ components:
|
||||
type: object
|
||||
description: Password challenge UI fields
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -41018,7 +40956,6 @@ components:
|
||||
required:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
PasswordChallengeResponseRequest:
|
||||
type: object
|
||||
description: Password challenge response
|
||||
@ -43909,8 +43846,6 @@ components:
|
||||
type: object
|
||||
description: Challenge shown to the user in identification stage
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -43929,7 +43864,6 @@ components:
|
||||
required:
|
||||
- client_id
|
||||
- slug
|
||||
- type
|
||||
PlexAuthenticationChallengeResponseRequest:
|
||||
type: object
|
||||
description: Pseudo class for plex response
|
||||
@ -44378,8 +44312,6 @@ components:
|
||||
type: object
|
||||
description: Initial challenge being sent, define fields
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -44397,7 +44329,6 @@ components:
|
||||
$ref: '#/components/schemas/StagePrompt'
|
||||
required:
|
||||
- fields
|
||||
- type
|
||||
PromptChallengeResponseRequest:
|
||||
type: object
|
||||
description: |-
|
||||
@ -45459,8 +45390,6 @@ components:
|
||||
type: object
|
||||
description: Challenge type to redirect the client
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -45476,7 +45405,6 @@ components:
|
||||
type: string
|
||||
required:
|
||||
- to
|
||||
- type
|
||||
Reputation:
|
||||
type: object
|
||||
description: Reputation Serializer
|
||||
@ -46959,8 +46887,6 @@ components:
|
||||
type: object
|
||||
description: challenge type to render HTML as-is
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -46976,7 +46902,6 @@ components:
|
||||
type: string
|
||||
required:
|
||||
- body
|
||||
- type
|
||||
SignatureAlgorithmEnum:
|
||||
enum:
|
||||
- http://www.w3.org/2000/09/xmldsig#rsa-sha1
|
||||
@ -48097,8 +48022,6 @@ components:
|
||||
type: object
|
||||
description: Empty challenge
|
||||
properties:
|
||||
type:
|
||||
$ref: '#/components/schemas/ChallengeChoices'
|
||||
flow_info:
|
||||
$ref: '#/components/schemas/ContextualFlowInfo'
|
||||
component:
|
||||
@ -48117,7 +48040,6 @@ components:
|
||||
required:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
UserLoginChallengeResponseRequest:
|
||||
type: object
|
||||
description: User login challenge
|
||||
|
@ -33,7 +33,6 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import {
|
||||
CapabilitiesEnum,
|
||||
ChallengeChoices,
|
||||
ChallengeTypes,
|
||||
ContextualFlowInfo,
|
||||
FetchError,
|
||||
@ -254,7 +253,6 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||
body = error.message;
|
||||
}
|
||||
const challenge: FlowErrorChallenge = {
|
||||
type: ChallengeChoices.Native,
|
||||
component: "ak-stage-flow-error",
|
||||
error: body,
|
||||
requestId: "",
|
||||
@ -280,7 +278,11 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||
}
|
||||
}
|
||||
|
||||
async renderChallengeNativeElement(): Promise<TemplateResult> {
|
||||
async renderChallenge(): Promise<TemplateResult> {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state ?loading=${true} header=${msg("Loading")}>
|
||||
</ak-empty-state>`;
|
||||
}
|
||||
switch (this.challenge?.component) {
|
||||
case "ak-stage-access-denied":
|
||||
await import("@goauthentik/flow/stages/access_denied/AccessDeniedStage");
|
||||
@ -411,31 +413,17 @@ export class FlowExecutor extends Interface implements StageHost {
|
||||
.host=${this as StageHost}
|
||||
.challenge=${this.challenge}
|
||||
></ak-stage-flow-error>`;
|
||||
default:
|
||||
return html`Invalid native challenge element`;
|
||||
}
|
||||
}
|
||||
|
||||
async renderChallenge(): Promise<TemplateResult> {
|
||||
if (!this.challenge) {
|
||||
return html`<ak-empty-state ?loading=${true} header=${msg("Loading")}>
|
||||
</ak-empty-state>`;
|
||||
}
|
||||
switch (this.challenge.type) {
|
||||
case ChallengeChoices.Redirect:
|
||||
case "xak-flow-redirect":
|
||||
return html`<ak-stage-redirect
|
||||
.host=${this as StageHost}
|
||||
.challenge=${this.challenge}
|
||||
?promptUser=${this.inspectorOpen}
|
||||
>
|
||||
</ak-stage-redirect>`;
|
||||
case ChallengeChoices.Shell:
|
||||
case "xak-flow-shell":
|
||||
return html`${unsafeHTML((this.challenge as ShellChallenge).body)}`;
|
||||
case ChallengeChoices.Native:
|
||||
return await this.renderChallengeNativeElement();
|
||||
default:
|
||||
console.debug(`authentik/flows: unexpected data type ${this.challenge.type}`);
|
||||
return html``;
|
||||
return html`Invalid native challenge element`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { html } from "lit";
|
||||
|
||||
import "@patternfly/patternfly/components/Login/login.css";
|
||||
|
||||
import { AccessDeniedChallenge, ChallengeChoices, UiThemeEnum } from "@goauthentik/api";
|
||||
import { AccessDeniedChallenge, UiThemeEnum } from "@goauthentik/api";
|
||||
|
||||
import "../../../stories/flow-interface";
|
||||
import "./AccessDeniedStage";
|
||||
@ -39,7 +39,6 @@ export const Challenge: StoryObj = {
|
||||
args: {
|
||||
theme: "automatic",
|
||||
challenge: {
|
||||
type: ChallengeChoices.Native,
|
||||
pendingUser: "foo",
|
||||
pendingUserAvatar: "https://picsum.photos/64",
|
||||
errorMessage: "This is an error message",
|
||||
|
@ -4,7 +4,7 @@ import { html } from "lit";
|
||||
|
||||
import "@patternfly/patternfly/components/Login/login.css";
|
||||
|
||||
import { AuthenticatorTOTPChallenge, ChallengeChoices, UiThemeEnum } from "@goauthentik/api";
|
||||
import { AuthenticatorTOTPChallenge, UiThemeEnum } from "@goauthentik/api";
|
||||
|
||||
import "../../../stories/flow-interface";
|
||||
import "./AuthenticatorTOTPStage";
|
||||
@ -41,7 +41,6 @@ export const Challenge: StoryObj = {
|
||||
args: {
|
||||
theme: "automatic",
|
||||
challenge: {
|
||||
type: ChallengeChoices.Native,
|
||||
pendingUser: "foo",
|
||||
pendingUserAvatar: "https://picsum.photos/64",
|
||||
configUrl: "",
|
||||
|
@ -4,7 +4,7 @@ import { html } from "lit";
|
||||
|
||||
import "@patternfly/patternfly/components/Login/login.css";
|
||||
|
||||
import { CaptchaChallenge, ChallengeChoices, UiThemeEnum } from "@goauthentik/api";
|
||||
import { CaptchaChallenge, UiThemeEnum } from "@goauthentik/api";
|
||||
|
||||
import "../../../stories/flow-interface";
|
||||
import "./CaptchaStage";
|
||||
@ -39,7 +39,6 @@ export const ChallengeGoogleReCaptcha: StoryObj = {
|
||||
args: {
|
||||
theme: "automatic",
|
||||
challenge: {
|
||||
type: ChallengeChoices.Native,
|
||||
pendingUser: "foo",
|
||||
pendingUserAvatar: "https://picsum.photos/64",
|
||||
jsUrl: "https://www.google.com/recaptcha/api.js",
|
||||
@ -70,7 +69,6 @@ export const ChallengeHCaptcha: StoryObj = {
|
||||
args: {
|
||||
theme: "automatic",
|
||||
challenge: {
|
||||
type: ChallengeChoices.Native,
|
||||
pendingUser: "foo",
|
||||
pendingUserAvatar: "https://picsum.photos/64",
|
||||
jsUrl: "https://js.hcaptcha.com/1/api.js",
|
||||
@ -101,7 +99,6 @@ export const ChallengeTurnstile: StoryObj = {
|
||||
args: {
|
||||
theme: "automatic",
|
||||
challenge: {
|
||||
type: ChallengeChoices.Native,
|
||||
pendingUser: "foo",
|
||||
pendingUserAvatar: "https://picsum.photos/64",
|
||||
jsUrl: "https://challenges.cloudflare.com/turnstile/v0/api.js",
|
||||
|
@ -20,7 +20,6 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import {
|
||||
ChallengeChoices,
|
||||
ChallengeTypes,
|
||||
FlowChallengeResponseRequest,
|
||||
FlowErrorChallenge,
|
||||
@ -116,7 +115,6 @@ export class UserSettingsFlowExecutor
|
||||
body = error.message;
|
||||
}
|
||||
const challenge: FlowErrorChallenge = {
|
||||
type: ChallengeChoices.Native,
|
||||
component: "ak-stage-flow-error",
|
||||
error: body,
|
||||
requestId: "",
|
||||
@ -146,8 +144,15 @@ export class UserSettingsFlowExecutor
|
||||
if (!this.challenge) {
|
||||
return html``;
|
||||
}
|
||||
switch (this.challenge.type) {
|
||||
case ChallengeChoices.Redirect:
|
||||
switch (this.challenge.component) {
|
||||
case "ak-stage-prompt":
|
||||
return html`<ak-user-stage-prompt
|
||||
.host=${this as StageHost}
|
||||
.challenge=${this.challenge}
|
||||
></ak-user-stage-prompt>`;
|
||||
case "xak-flow-shell":
|
||||
return html`${unsafeHTML((this.challenge as ShellChallenge).body)}`;
|
||||
case "xak-flow-redirect":
|
||||
if ((this.challenge as RedirectChallenge).to !== "/") {
|
||||
return html`<a
|
||||
href="${(this.challenge as RedirectChallenge).to}"
|
||||
@ -166,30 +171,16 @@ export class UserSettingsFlowExecutor
|
||||
});
|
||||
return html`<ak-empty-state ?loading=${true} header=${msg("Loading")}>
|
||||
</ak-empty-state>`;
|
||||
case ChallengeChoices.Shell:
|
||||
return html`${unsafeHTML((this.challenge as ShellChallenge).body)}`;
|
||||
case ChallengeChoices.Native:
|
||||
switch (this.challenge.component) {
|
||||
case "ak-stage-prompt":
|
||||
return html`<ak-user-stage-prompt
|
||||
.host=${this as StageHost}
|
||||
.challenge=${this.challenge}
|
||||
></ak-user-stage-prompt>`;
|
||||
default:
|
||||
console.debug(
|
||||
`authentik/user/flows: unsupported stage type ${this.challenge.component}`,
|
||||
);
|
||||
return html`
|
||||
<a href="/if/flow/${this.flowSlug}/" class="pf-c-button pf-m-primary">
|
||||
${msg("Open settings")}
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
default:
|
||||
console.debug(`authentik/user/flows: unexpected data type ${this.challenge.type}`);
|
||||
break;
|
||||
console.debug(
|
||||
`authentik/user/flows: unsupported stage type ${this.challenge.component}`,
|
||||
);
|
||||
return html`
|
||||
<a href="/if/flow/${this.flowSlug}/" class="pf-c-button pf-m-primary">
|
||||
${msg("Open settings")}
|
||||
</a>
|
||||
`;
|
||||
}
|
||||
return html``;
|
||||
}
|
||||
|
||||
renderChallengeWrapper(): TemplateResult {
|
||||
|
Reference in New Issue
Block a user