flows: add get_pending_user() for WithUserInfoChallenge
This commit is contained in:
parent
27cd10e072
commit
88e5b22d16
|
@ -1,6 +1,5 @@
|
|||
"""authentik stage Base view"""
|
||||
from collections import namedtuple
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
|
||||
from django.http import HttpRequest
|
||||
from django.http.request import QueryDict
|
||||
|
@ -9,6 +8,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
from django.views.generic import TemplateView
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
|
@ -20,8 +20,6 @@ from authentik.flows.views import FlowExecutorView
|
|||
PLAN_CONTEXT_PENDING_USER_IDENTIFIER = "pending_user_identifier"
|
||||
LOGGER = get_logger()
|
||||
|
||||
FakeUser = namedtuple("User", ["username", "email"])
|
||||
|
||||
|
||||
class StageView(TemplateView):
|
||||
"""Abstract Stage, inherits TemplateView but can be combined with FormView"""
|
||||
|
@ -44,7 +42,7 @@ class StageView(TemplateView):
|
|||
if PLAN_CONTEXT_PENDING_USER in self.executor.plan.context:
|
||||
kwargs["user"] = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
|
||||
if PLAN_CONTEXT_PENDING_USER_IDENTIFIER in self.executor.plan.context:
|
||||
kwargs["user"] = FakeUser(
|
||||
kwargs["user"] = User(
|
||||
username=self.executor.plan.context.get(
|
||||
PLAN_CONTEXT_PENDING_USER_IDENTIFIER
|
||||
),
|
||||
|
@ -59,6 +57,22 @@ class ChallengeStageView(StageView):
|
|||
|
||||
response_class = ChallengeResponse
|
||||
|
||||
def get_pending_user(self) -> Optional[User]:
|
||||
"""Either show the matched User object or show what the user entered,
|
||||
based on what the earlier stage (mostly IdentificationStage) set.
|
||||
_USER_IDENTIFIER overrides the first User, as PENDING_USER is used for
|
||||
other things besides the form display"""
|
||||
if PLAN_CONTEXT_PENDING_USER_IDENTIFIER in self.executor.plan.context:
|
||||
return User(
|
||||
username=self.executor.plan.context.get(
|
||||
PLAN_CONTEXT_PENDING_USER_IDENTIFIER
|
||||
),
|
||||
email="",
|
||||
)
|
||||
if PLAN_CONTEXT_PENDING_USER in self.executor.plan.context:
|
||||
return self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
|
||||
return None
|
||||
|
||||
def get_response_instance(self, data: QueryDict) -> ChallengeResponse:
|
||||
"""Return the response class type"""
|
||||
return self.response_class(None, data=data, stage=self)
|
||||
|
|
|
@ -3,7 +3,6 @@ from django.http import HttpRequest, HttpResponse
|
|||
from django.utils.timezone import now
|
||||
from rest_framework.fields import CharField
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
|
@ -55,10 +54,9 @@ class ConsentStageView(ChallengeStageView):
|
|||
# If there's a pending user, update the `username` field
|
||||
# this field is only used by password managers.
|
||||
# If there's no user set, an error is raised later.
|
||||
if PLAN_CONTEXT_PENDING_USER in self.executor.plan.context:
|
||||
pending_user: User = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
|
||||
challenge.initial_data["pending_user"] = pending_user.username
|
||||
challenge.initial_data["pending_user_avatar"] = avatar(pending_user)
|
||||
if user := self.get_pending_user():
|
||||
challenge.initial_data["pending_user"] = user.username
|
||||
challenge.initial_data["pending_user_avatar"] = avatar(user)
|
||||
return challenge
|
||||
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
|
|
|
@ -86,10 +86,9 @@ class PasswordStageView(ChallengeStageView):
|
|||
# If there's a pending user, update the `username` field
|
||||
# this field is only used by password managers.
|
||||
# If there's no user set, an error is raised later.
|
||||
if PLAN_CONTEXT_PENDING_USER in self.executor.plan.context:
|
||||
pending_user: User = self.executor.plan.context[PLAN_CONTEXT_PENDING_USER]
|
||||
challenge.initial_data["pending_user"] = pending_user.username
|
||||
challenge.initial_data["pending_user_avatar"] = avatar(pending_user)
|
||||
if user := self.get_pending_user():
|
||||
challenge.initial_data["pending_user"] = user.username
|
||||
challenge.initial_data["pending_user_avatar"] = avatar(user)
|
||||
|
||||
recovery_flow = Flow.objects.filter(designation=FlowDesignation.RECOVERY)
|
||||
if recovery_flow.exists():
|
||||
|
|
26
swagger.yaml
26
swagger.yaml
|
@ -9657,22 +9657,22 @@ definitions:
|
|||
- authentik.sources.ldap
|
||||
- authentik.sources.oauth
|
||||
- authentik.sources.saml
|
||||
- authentik.stages.captcha
|
||||
- authentik.stages.consent
|
||||
- authentik.stages.dummy
|
||||
- authentik.stages.email
|
||||
- authentik.stages.prompt
|
||||
- authentik.stages.identification
|
||||
- authentik.stages.invitation
|
||||
- authentik.stages.user_delete
|
||||
- authentik.stages.user_login
|
||||
- authentik.stages.user_logout
|
||||
- authentik.stages.user_write
|
||||
- authentik.stages.authenticator_static
|
||||
- authentik.stages.authenticator_totp
|
||||
- authentik.stages.authenticator_validate
|
||||
- authentik.stages.authenticator_webauthn
|
||||
- authentik.stages.captcha
|
||||
- authentik.stages.consent
|
||||
- authentik.stages.dummy
|
||||
- authentik.stages.email
|
||||
- authentik.stages.identification
|
||||
- authentik.stages.invitation
|
||||
- authentik.stages.password
|
||||
- authentik.stages.prompt
|
||||
- authentik.stages.user_delete
|
||||
- authentik.stages.user_login
|
||||
- authentik.stages.user_logout
|
||||
- authentik.stages.user_write
|
||||
- authentik.managed
|
||||
- authentik.core
|
||||
ExpressionPolicy:
|
||||
|
@ -11742,8 +11742,8 @@ definitions:
|
|||
- password
|
||||
- number
|
||||
- checkbox
|
||||
- data
|
||||
- data-time
|
||||
- date
|
||||
- date-time
|
||||
- separator
|
||||
- hidden
|
||||
- static
|
||||
|
|
Reference in a new issue