diff --git a/authentik/flows/challenge.py b/authentik/flows/challenge.py index 051978be9..b4766f44c 100644 --- a/authentik/flows/challenge.py +++ b/authentik/flows/challenge.py @@ -12,6 +12,10 @@ from authentik.flows.transfer.common import DataclassEncoder if TYPE_CHECKING: from authentik.flows.stage import StageView +PLAN_CONTEXT_TITLE = "title" +PLAN_CONTEXT_URL = "url" +PLAN_CONTEXT_ATTRS = "attrs" + class ChallengeTypes(Enum): """Currently defined challenge types""" @@ -97,6 +101,21 @@ class ChallengeResponse(PassiveSerializer): super().__init__(instance=instance, data=data, **kwargs) +class AutosubmitChallenge(Challenge): + """Autosubmit challenge used to send and navigate a POST request""" + + url = CharField() + attrs = DictField(child=CharField()) + title = CharField(required=False) + component = CharField(default="ak-stage-autosubmit") + + +class AutoSubmitChallengeResponse(ChallengeResponse): + """Pseudo class for autosubmit response""" + + component = CharField(default="ak-stage-autosubmit") + + class HttpChallengeResponse(JsonResponse): """Subclass of JsonResponse that uses the `DataclassEncoder`""" diff --git a/authentik/providers/oauth2/views/authorize.py b/authentik/providers/oauth2/views/authorize.py index 6912841a1..f8581c54f 100644 --- a/authentik/providers/oauth2/views/authorize.py +++ b/authentik/providers/oauth2/views/authorize.py @@ -15,7 +15,12 @@ from structlog.stdlib import get_logger from authentik.core.models import Application from authentik.events.models import Event, EventAction from authentik.events.utils import get_user -from authentik.flows.challenge import ChallengeTypes, HttpChallengeResponse +from authentik.flows.challenge import ( + PLAN_CONTEXT_TITLE, + AutosubmitChallenge, + ChallengeTypes, + HttpChallengeResponse, +) from authentik.flows.models import in_memory_stage from authentik.flows.planner import ( PLAN_CONTEXT_APPLICATION, @@ -51,8 +56,6 @@ from authentik.providers.oauth2.models import ( ) from authentik.providers.oauth2.utils import HttpResponseRedirectScheme from authentik.providers.oauth2.views.userinfo import UserInfoView -from authentik.providers.saml.views.flows import AutosubmitChallenge -from authentik.sources.saml.views import PLAN_CONTEXT_TITLE from authentik.stages.consent.models import ConsentMode, ConsentStage from authentik.stages.consent.stage import ( PLAN_CONTEXT_CONSENT_HEADER, diff --git a/authentik/providers/saml/views/flows.py b/authentik/providers/saml/views/flows.py index d0b3841fa..bf489fcd4 100644 --- a/authentik/providers/saml/views/flows.py +++ b/authentik/providers/saml/views/flows.py @@ -5,12 +5,18 @@ from django.http.response import HttpResponseBadRequest from django.shortcuts import get_object_or_404, redirect from django.utils.http import urlencode from django.utils.translation import gettext as _ -from rest_framework.fields import CharField, DictField from structlog.stdlib import get_logger from authentik.core.models import Application from authentik.events.models import Event, EventAction -from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes +from authentik.flows.challenge import ( + PLAN_CONTEXT_TITLE, + AutosubmitChallenge, + AutoSubmitChallengeResponse, + Challenge, + ChallengeResponse, + ChallengeTypes, +) from authentik.flows.planner import PLAN_CONTEXT_APPLICATION from authentik.flows.stage import ChallengeStageView from authentik.lib.views import bad_request_message @@ -19,7 +25,6 @@ from authentik.providers.saml.processors.assertion import AssertionProcessor from authentik.providers.saml.processors.request_parser import AuthNRequest from authentik.providers.saml.utils.encoding import deflate_and_base64_encode, nice64 from authentik.sources.saml.exceptions import SAMLException -from authentik.sources.saml.views import PLAN_CONTEXT_TITLE LOGGER = get_logger() URL_VALIDATOR = URLValidator(schemes=("http", "https")) @@ -31,22 +36,6 @@ REQUEST_KEY_RELAY_STATE = "RelayState" SESSION_KEY_AUTH_N_REQUEST = "authn_request" - -class AutosubmitChallenge(Challenge): - """Autosubmit challenge used to send and navigate a POST request""" - - url = CharField() - attrs = DictField(child=CharField()) - title = CharField(required=False) - component = CharField(default="ak-stage-autosubmit") - - -class AutoSubmitChallengeResponse(ChallengeResponse): - """Pseudo class for autosubmit response""" - - component = CharField(default="ak-stage-autosubmit") - - # This View doesn't have a URL on purpose, as its called by the FlowExecutor class SAMLFlowFinalView(ChallengeStageView): """View used by FlowExecutor after all stages have passed. Logs the authorization, diff --git a/authentik/sources/saml/views.py b/authentik/sources/saml/views.py index 2219b7a1d..d27112842 100644 --- a/authentik/sources/saml/views.py +++ b/authentik/sources/saml/views.py @@ -13,7 +13,15 @@ from django.views.decorators.csrf import csrf_exempt from structlog.stdlib import get_logger from xmlsec import InternalError, VerificationError -from authentik.flows.challenge import Challenge, ChallengeResponse, ChallengeTypes +from authentik.flows.challenge import ( + PLAN_CONTEXT_ATTRS, + PLAN_CONTEXT_TITLE, + PLAN_CONTEXT_URL, + AutosubmitChallenge, + Challenge, + ChallengeResponse, + ChallengeTypes, +) from authentik.flows.models import in_memory_stage from authentik.flows.planner import ( PLAN_CONTEXT_REDIRECT, @@ -26,7 +34,6 @@ from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET, SESSI from authentik.lib.utils.urls import redirect_with_qs from authentik.lib.views import bad_request_message from authentik.providers.saml.utils.encoding import nice64 -from authentik.providers.saml.views.flows import AutosubmitChallenge from authentik.sources.saml.exceptions import MissingSAMLResponse, UnsupportedNameIDFormat from authentik.sources.saml.models import SAMLBindingTypes, SAMLSource from authentik.sources.saml.processors.metadata import MetadataProcessor @@ -38,9 +45,6 @@ from authentik.stages.consent.stage import ( ConsentStageView, ) -PLAN_CONTEXT_TITLE = "title" -PLAN_CONTEXT_URL = "url" -PLAN_CONTEXT_ATTRS = "attrs" LOGGER = get_logger()