flows: add get_pending_user() for WithUserInfoChallenge

This commit is contained in:
Jens Langhammer 2021-02-21 18:30:40 +01:00
parent 27cd10e072
commit 88e5b22d16
4 changed files with 38 additions and 27 deletions

View file

@ -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)

View file

@ -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:

View file

@ -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():

View file

@ -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