This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/authentik/flows/challenge.py
Jens Langhammer dce869b566 flows: fix post-email continuation not working
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2021-03-24 12:46:54 +01:00

119 lines
3 KiB
Python

"""Challenge helpers"""
from enum import Enum
from typing import TYPE_CHECKING, Optional
from django.db.models.base import Model
from django.http import JsonResponse
from rest_framework.fields import ChoiceField, DictField
from rest_framework.serializers import CharField, Serializer
from authentik.flows.transfer.common import DataclassEncoder
if TYPE_CHECKING:
from authentik.flows.stage import StageView
class ChallengeTypes(Enum):
"""Currently defined challenge types"""
native = "native"
shell = "shell"
redirect = "redirect"
class ErrorDetailSerializer(Serializer):
"""Serializer for rest_framework's error messages"""
string = CharField()
code = CharField()
def create(self, validated_data: dict) -> Model:
return Model()
def update(self, instance: Model, validated_data: dict) -> Model:
return Model()
class Challenge(Serializer):
"""Challenge that gets sent to the client based on which stage
is currently active"""
type = ChoiceField(
choices=[(x.name, x.name) for x in ChallengeTypes],
)
component = CharField(required=False)
title = CharField(required=False)
background = CharField(required=False)
response_errors = DictField(
child=ErrorDetailSerializer(many=True), allow_empty=True, required=False
)
def create(self, validated_data: dict) -> Model:
return Model()
def update(self, instance: Model, validated_data: dict) -> Model:
return Model()
class RedirectChallenge(Challenge):
"""Challenge type to redirect the client"""
to = CharField()
class ShellChallenge(Challenge):
"""Legacy challenge type to render HTML as-is"""
body = CharField()
class WithUserInfoChallenge(Challenge):
"""Challenge base which shows some user info"""
pending_user = CharField()
pending_user_avatar = CharField()
class AccessDeniedChallenge(Challenge):
"""Challenge when a flow's active stage calls `stage_invalid()`."""
error_message = CharField(required=False)
class PermissionSerializer(Serializer):
"""Permission used for consent"""
name = CharField()
id = CharField()
def create(self, validated_data: dict) -> Model:
return Model()
def update(self, instance: Model, validated_data: dict) -> Model:
return Model()
class ChallengeResponse(Serializer):
"""Base class for all challenge responses"""
stage: Optional["StageView"]
def __init__(self, instance=None, data=None, **kwargs):
self.stage = kwargs.pop("stage", None)
super().__init__(instance=instance, data=data, **kwargs)
def create(self, validated_data: dict) -> Model:
return Model()
def update(self, instance: Model, validated_data: dict) -> Model:
return Model()
class HttpChallengeResponse(JsonResponse):
"""Subclass of JsonResponse that uses the `DataclassEncoder`"""
def __init__(self, challenge, **kwargs) -> None:
# pyright: reportGeneralTypeIssues=false
super().__init__(challenge.data, encoder=DataclassEncoder, **kwargs)