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

159 lines
4.2 KiB
Python
Raw Normal View History

"""Challenge helpers"""
blueprints: v1 (#1573) * managed: move flowexporter to managed Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * *: implement SerializerModel in all models Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: add initial api Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: start blueprint Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: spec Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * version blueprint Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * yep Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove v2, improve v1 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * start custom tag, more rebrand Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add default flows Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * move blueprints out of website Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * try new things Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add !lookup, fix web Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * update and cleanup default Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix tags in lists Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * don't save field if its set to default value Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * more flow cleanup Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * format web Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix missing serializer for sms Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * ignore _set fields Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove custom file extension Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * migrate default flow to tenant Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * include blueprints Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix tests Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-07-31 15:11:44 +00:00
from dataclasses import asdict, is_dataclass
from enum import Enum
from typing import TYPE_CHECKING, Optional, TypedDict
blueprints: v1 (#1573) * managed: move flowexporter to managed Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * *: implement SerializerModel in all models Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: add initial api Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: start blueprint Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: spec Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * version blueprint Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * yep Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove v2, improve v1 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * start custom tag, more rebrand Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add default flows Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * move blueprints out of website Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * try new things Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add !lookup, fix web Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * update and cleanup default Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix tags in lists Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * don't save field if its set to default value Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * more flow cleanup Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * format web Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix missing serializer for sms Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * ignore _set fields Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove custom file extension Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * migrate default flow to tenant Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * include blueprints Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix tests Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-07-31 15:11:44 +00:00
from uuid import UUID
blueprints: v1 (#1573) * managed: move flowexporter to managed Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * *: implement SerializerModel in all models Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: add initial api Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: start blueprint Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: spec Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * version blueprint Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * yep Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove v2, improve v1 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * start custom tag, more rebrand Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add default flows Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * move blueprints out of website Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * try new things Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add !lookup, fix web Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * update and cleanup default Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix tags in lists Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * don't save field if its set to default value Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * more flow cleanup Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * format web Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix missing serializer for sms Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * ignore _set fields Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove custom file extension Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * migrate default flow to tenant Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * include blueprints Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix tests Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-07-31 15:11:44 +00:00
from django.core.serializers.json import DjangoJSONEncoder
2022-05-15 23:10:23 +00:00
from django.db import models
from django.http import JsonResponse
from rest_framework.fields import ChoiceField, DictField
from rest_framework.serializers import CharField
from authentik.core.api.utils import PassiveSerializer
if TYPE_CHECKING:
from authentik.flows.stage import StageView
PLAN_CONTEXT_TITLE = "title"
PLAN_CONTEXT_URL = "url"
PLAN_CONTEXT_ATTRS = "attrs"
2022-05-15 23:10:23 +00:00
class FlowLayout(models.TextChoices):
"""Flow layouts"""
STACKED = "stacked"
CONTENT_LEFT = "content_left"
CONTENT_RIGHT = "content_right"
SIDEBAR_LEFT = "sidebar_left"
SIDEBAR_RIGHT = "sidebar_right"
class ChallengeTypes(Enum):
"""Currently defined challenge types"""
NATIVE = "native"
SHELL = "shell"
REDIRECT = "redirect"
class ErrorDetailSerializer(PassiveSerializer):
"""Serializer for rest_framework's error messages"""
string = CharField()
code = CharField()
class ContextualFlowInfo(PassiveSerializer):
"""Contextual flow information for a challenge"""
title = CharField(required=False, allow_blank=True)
background = CharField(required=False)
cancel_url = CharField()
2022-05-15 23:10:23 +00:00
layout = ChoiceField(choices=[(x.value, x.name) for x in FlowLayout])
class Challenge(PassiveSerializer):
"""Challenge that gets sent to the client based on which stage
is currently active"""
type = ChoiceField(
choices=[(x.value, x.name) for x in ChallengeTypes],
)
flow_info = ContextualFlowInfo(required=False)
component = CharField(default="")
response_errors = DictField(
child=ErrorDetailSerializer(many=True), allow_empty=True, required=False
)
class RedirectChallenge(Challenge):
"""Challenge type to redirect the client"""
to = CharField()
component = CharField(default="xak-flow-redirect")
class ShellChallenge(Challenge):
"""challenge type to render HTML as-is"""
body = CharField()
component = CharField(default="xak-flow-shell")
2021-02-21 12:15:45 +00:00
class WithUserInfoChallenge(Challenge):
"""Challenge base which shows some user info"""
pending_user = CharField(allow_blank=True)
2021-02-21 12:15:45 +00:00
pending_user_avatar = CharField()
class AccessDeniedChallenge(WithUserInfoChallenge):
"""Challenge when a flow's active stage calls `stage_invalid()`."""
error_message = CharField(required=False)
component = CharField(default="ak-stage-access-denied")
class PermissionDict(TypedDict):
"""Consent Permission"""
id: str
name: str
class PermissionSerializer(PassiveSerializer):
2021-02-21 12:15:45 +00:00
"""Permission used for consent"""
name = CharField(allow_blank=True)
2021-02-21 12:15:45 +00:00
id = CharField()
class ChallengeResponse(PassiveSerializer):
"""Base class for all challenge responses"""
stage: Optional["StageView"]
component = CharField(default="xak-flow-response-default")
def __init__(self, instance=None, data=None, **kwargs):
self.stage = kwargs.pop("stage", None)
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")
blueprints: v1 (#1573) * managed: move flowexporter to managed Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * *: implement SerializerModel in all models Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: add initial api Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: start blueprint Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * managed: spec Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * version blueprint Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * yep Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove v2, improve v1 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * start custom tag, more rebrand Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add default flows Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * move blueprints out of website Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * try new things Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * add !lookup, fix web Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * update and cleanup default Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix tags in lists Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * don't save field if its set to default value Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * more flow cleanup Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * format web Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix missing serializer for sms Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * ignore _set fields Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove custom file extension Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * migrate default flow to tenant Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * include blueprints Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * fix tests Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-07-31 15:11:44 +00:00
class DataclassEncoder(DjangoJSONEncoder):
"""Convert any dataclass to json"""
def default(self, o):
if is_dataclass(o):
return asdict(o)
if isinstance(o, UUID):
return str(o)
if isinstance(o, Enum):
return o.value
return super().default(o) # pragma: no cover
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)