stages/identification: dynamically find login challenges (#11571)

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L.
2024-09-30 23:27:17 +02:00
committed by GitHub
parent e7698d2c33
commit dc4f341399
4 changed files with 21 additions and 11 deletions

View File

@ -15,12 +15,13 @@ 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
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
from authentik.stages.identification.stage import LoginChallengeMixin
LOGGER = get_logger() LOGGER = get_logger()
APPLE_CLIENT_ID_PARTS = 3 APPLE_CLIENT_ID_PARTS = 3
class AppleLoginChallenge(Challenge): class AppleLoginChallenge(LoginChallengeMixin, Challenge):
"""Special challenge for apple-native authentication flow, which happens on the client.""" """Special challenge for apple-native authentication flow, which happens on the client."""
client_id = CharField() client_id = CharField()

View File

@ -19,9 +19,10 @@ from authentik.core.models import (
from authentik.core.types import UILoginButton, UserSettingSerializer from authentik.core.types import UILoginButton, UserSettingSerializer
from authentik.flows.challenge import Challenge, ChallengeResponse from authentik.flows.challenge import Challenge, ChallengeResponse
from authentik.lib.generators import generate_id from authentik.lib.generators import generate_id
from authentik.stages.identification.stage import LoginChallengeMixin
class PlexAuthenticationChallenge(Challenge): class PlexAuthenticationChallenge(LoginChallengeMixin, Challenge):
"""Challenge shown to the user in identification stage""" """Challenge shown to the user in identification stage"""
client_id = CharField() client_id = CharField()

View File

@ -26,23 +26,31 @@ from authentik.flows.models import FlowDesignation
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
from authentik.flows.stage import PLAN_CONTEXT_PENDING_USER_IDENTIFIER, ChallengeStageView from authentik.flows.stage import PLAN_CONTEXT_PENDING_USER_IDENTIFIER, ChallengeStageView
from authentik.flows.views.executor import SESSION_KEY_APPLICATION_PRE, SESSION_KEY_GET from authentik.flows.views.executor import SESSION_KEY_APPLICATION_PRE, SESSION_KEY_GET
from authentik.lib.utils.reflection import all_subclasses
from authentik.lib.utils.urls import reverse_with_qs from authentik.lib.utils.urls import reverse_with_qs
from authentik.root.middleware import ClientIPMiddleware from authentik.root.middleware import ClientIPMiddleware
from authentik.sources.oauth.types.apple import AppleLoginChallenge
from authentik.sources.plex.models import PlexAuthenticationChallenge
from authentik.stages.identification.models import IdentificationStage from authentik.stages.identification.models import IdentificationStage
from authentik.stages.identification.signals import identification_failed from authentik.stages.identification.signals import identification_failed
from authentik.stages.password.stage import authenticate from authentik.stages.password.stage import authenticate
class LoginChallengeMixin:
"""Base login challenge for Identification stage"""
def get_login_serializers():
mapping = {
RedirectChallenge().fields["component"].default: RedirectChallenge,
}
for cls in all_subclasses(LoginChallengeMixin):
mapping[cls().fields["component"].default] = cls
return mapping
@extend_schema_field( @extend_schema_field(
PolymorphicProxySerializer( PolymorphicProxySerializer(
component_name="LoginChallengeTypes", component_name="LoginChallengeTypes",
serializers={ serializers=get_login_serializers,
RedirectChallenge().fields["component"].default: RedirectChallenge,
PlexAuthenticationChallenge().fields["component"].default: PlexAuthenticationChallenge,
AppleLoginChallenge().fields["component"].default: AppleLoginChallenge,
},
resource_type_field_name="component", resource_type_field_name="component",
) )
) )

View File

@ -41620,14 +41620,14 @@ components:
LoginChallengeTypes: LoginChallengeTypes:
oneOf: oneOf:
- $ref: '#/components/schemas/RedirectChallenge' - $ref: '#/components/schemas/RedirectChallenge'
- $ref: '#/components/schemas/PlexAuthenticationChallenge'
- $ref: '#/components/schemas/AppleLoginChallenge' - $ref: '#/components/schemas/AppleLoginChallenge'
- $ref: '#/components/schemas/PlexAuthenticationChallenge'
discriminator: discriminator:
propertyName: component propertyName: component
mapping: mapping:
xak-flow-redirect: '#/components/schemas/RedirectChallenge' xak-flow-redirect: '#/components/schemas/RedirectChallenge'
ak-source-plex: '#/components/schemas/PlexAuthenticationChallenge'
ak-source-oauth-apple: '#/components/schemas/AppleLoginChallenge' ak-source-oauth-apple: '#/components/schemas/AppleLoginChallenge'
ak-source-plex: '#/components/schemas/PlexAuthenticationChallenge'
LoginMetrics: LoginMetrics:
type: object type: object
description: Login Metrics per 1h description: Login Metrics per 1h