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