e28babb0b8
* rename consent permission Signed-off-by: Jens Langhammer <jens@goauthentik.io> * the user version Signed-off-by: Jens Langhammer <jens@goauthentik.io> t Signed-off-by: Jens Langhammer <jens@goauthentik.io> * initial role Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start form Signed-off-by: Jens Langhammer <jens@goauthentik.io> * some minor table refactoring Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix user, add assign Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add roles ui Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix backend Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add assign API for roles Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start adding toggle buttons Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start view page Signed-off-by: Jens Langhammer <jens@goauthentik.io> * exclude add_ permission for per-object perms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * small cleanup Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add permission list for roles Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make sidebar update Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix page header not re-rendering? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fixup Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add search Signed-off-by: Jens Langhammer <jens@goauthentik.io> * show first category in table groupBy except when its empty Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make model and object PK optional but required together Signed-off-by: Jens Langhammer <jens@goauthentik.io> * allow for setting global perms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * exclude non-authentik permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * exclude models which aren't allowed (base models etc) Signed-off-by: Jens Langhammer <jens@goauthentik.io> * ensure all models have verbose_name set, exclude some more internal objects Signed-off-by: Jens Langhammer <jens@goauthentik.io> * lint fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix role perm assign Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add unasign for global perms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add meta changes Signed-off-by: Jens Langhammer <jens@goauthentik.io> * clear modal state after submit Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add roles to our group Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix duplicate url names Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make recursive group query more usable Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add name field to role itself and move group creation to signal Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start sync Signed-off-by: Jens Langhammer <jens@goauthentik.io> * move rbac stuff to separate django app Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix lint and such Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix go Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start API changes Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add more API tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make admin interface not require superuser for now, improve error handling Signed-off-by: Jens Langhammer <jens@goauthentik.io> * replace some IsAdminUser where applicable Signed-off-by: Jens Langhammer <jens@goauthentik.io> * migrate flow inspector perms to actual permission Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix license not being a serializermodel Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add permission modal to models without view page Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add additional permissions to assign/unassign permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add action to unassign user permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add permissions tab to remaining view pages Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix flow inspector permission check Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix codecov config? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add more API tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * ensure viewsets have an order set Signed-off-by: Jens Langhammer <jens@goauthentik.io> * hopefully the last api name change Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make perm modal less confusing Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start user view permission page Signed-off-by: Jens Langhammer <jens@goauthentik.io> * only make delete bulk form expandable if usedBy is set Signed-off-by: Jens Langhammer <jens@goauthentik.io> * expand permission tables Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add more things Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add user global permission table Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix lint Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix tests' url names Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add tests for assign perms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add unassign tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * rebuild permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * prevent assigning/unassigning permissions to internal service accounts Signed-off-by: Jens Langhammer <jens@goauthentik.io> * only enable default api browser in debug Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix role object permissions showing duplicate Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix role link on role object permissions table Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix object permission modal having duplicate close buttons Signed-off-by: Jens Langhammer <jens@goauthentik.io> * return error if user has no global perm and no object perms also improve error display on table Signed-off-by: Jens Langhammer <jens@goauthentik.io> * small optimisation Signed-off-by: Jens Langhammer <jens@goauthentik.io> * optimise even more Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update locale Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add system permission for non-object permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * allow access to admin interface based on perm Signed-off-by: Jens Langhammer <jens@goauthentik.io> * clean Signed-off-by: Jens Langhammer <jens@goauthentik.io> * don't exclude base models Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
179 lines
5.1 KiB
Python
179 lines
5.1 KiB
Python
"""Challenge helpers"""
|
|
from dataclasses import asdict, is_dataclass
|
|
from enum import Enum
|
|
from typing import TYPE_CHECKING, Optional, TypedDict
|
|
from uuid import UUID
|
|
|
|
from django.core.serializers.json import DjangoJSONEncoder
|
|
from django.db import models
|
|
from django.http import JsonResponse
|
|
from rest_framework.fields import CharField, ChoiceField, DictField
|
|
from rest_framework.request import Request
|
|
|
|
from authentik.core.api.utils import PassiveSerializer
|
|
from authentik.lib.utils.errors import exception_to_string
|
|
|
|
if TYPE_CHECKING:
|
|
from authentik.flows.stage import StageView
|
|
|
|
PLAN_CONTEXT_TITLE = "title"
|
|
PLAN_CONTEXT_URL = "url"
|
|
PLAN_CONTEXT_ATTRS = "attrs"
|
|
|
|
|
|
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()
|
|
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")
|
|
|
|
|
|
class WithUserInfoChallenge(Challenge):
|
|
"""Challenge base which shows some user info"""
|
|
|
|
pending_user = CharField(allow_blank=True)
|
|
pending_user_avatar = CharField()
|
|
|
|
|
|
class FlowErrorChallenge(Challenge):
|
|
"""Challenge class when an unhandled error occurs during a stage. Normal users
|
|
are shown an error message, superusers are shown a full stacktrace."""
|
|
|
|
type = CharField(default=ChallengeTypes.NATIVE.value)
|
|
component = CharField(default="ak-stage-flow-error")
|
|
|
|
request_id = CharField()
|
|
|
|
error = CharField(required=False)
|
|
traceback = CharField(required=False)
|
|
|
|
def __init__(self, request: Optional[Request] = None, error: Optional[Exception] = None):
|
|
super().__init__(data={})
|
|
if not request or not error:
|
|
return
|
|
self.initial_data["request_id"] = request.request_id
|
|
from authentik.core.models import USER_ATTRIBUTE_DEBUG
|
|
|
|
if request.user and request.user.is_authenticated:
|
|
if request.user.is_superuser or request.user.group_attributes(request).get(
|
|
USER_ATTRIBUTE_DEBUG, False
|
|
):
|
|
self.initial_data["error"] = str(error)
|
|
self.initial_data["traceback"] = exception_to_string(error)
|
|
|
|
|
|
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 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(allow_blank=True), allow_empty=True)
|
|
title = CharField(required=False)
|
|
component = CharField(default="ak-stage-autosubmit")
|
|
|
|
|
|
class AutoSubmitChallengeResponse(ChallengeResponse):
|
|
"""Pseudo class for autosubmit response"""
|
|
|
|
component = CharField(default="ak-stage-autosubmit")
|
|
|
|
|
|
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:
|
|
super().__init__(challenge.data, encoder=DataclassEncoder, **kwargs)
|