core: add Serializer for UserSettings, used by stages and sources

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-03-24 17:46:31 +01:00
parent f695a3f40a
commit 83c3a116f3
5 changed files with 50 additions and 17 deletions

View File

@ -13,7 +13,7 @@ from structlog.stdlib import get_logger
from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer
from authentik.core.models import Source from authentik.core.models import Source
from authentik.flows.challenge import Challenge from authentik.core.types import UserSettingSerializer
from authentik.lib.templatetags.authentik_utils import verbose_name from authentik.lib.templatetags.authentik_utils import verbose_name
from authentik.lib.utils.reflection import all_subclasses from authentik.lib.utils.reflection import all_subclasses
from authentik.policies.engine import PolicyEngine from authentik.policies.engine import PolicyEngine
@ -77,14 +77,14 @@ class SourceViewSet(
) )
return Response(TypeCreateSerializer(data, many=True).data) return Response(TypeCreateSerializer(data, many=True).data)
@swagger_auto_schema(responses={200: Challenge(many=True)}) @swagger_auto_schema(responses={200: UserSettingSerializer(many=True)})
@action(detail=False) @action(detail=False)
def user_settings(self, request: Request) -> Response: def user_settings(self, request: Request) -> Response:
"""Get all sources the user can configure""" """Get all sources the user can configure"""
_all_sources: Iterable[Source] = Source.objects.filter( _all_sources: Iterable[Source] = Source.objects.filter(
enabled=True enabled=True
).select_subclasses() ).select_subclasses()
matching_sources: list[Challenge] = [] matching_sources: list[UserSettingSerializer] = []
for source in _all_sources: for source in _all_sources:
user_settings = source.ui_user_settings user_settings = source.ui_user_settings
if not user_settings: if not user_settings:
@ -94,6 +94,7 @@ class SourceViewSet(
if not policy_engine.passing: if not policy_engine.passing:
continue continue
source_settings = source.ui_user_settings source_settings = source.ui_user_settings
source_settings["object_uid"] = str(source.pk)
if not source_settings.is_valid(): if not source_settings.is_valid():
LOGGER.warning(source_settings.errors) LOGGER.warning(source_settings.errors)
matching_sources.append(source_settings.validated_data) matching_sources.append(source_settings.validated_data)

View File

@ -33,3 +33,17 @@ class UILoginButtonSerializer(Serializer):
def update(self, instance: Model, validated_data: dict) -> Model: def update(self, instance: Model, validated_data: dict) -> Model:
return Model() return Model()
class UserSettingSerializer(Serializer):
"""Serializer for User settings for stages and sources"""
object_uid = CharField()
component = CharField()
title = CharField()
def create(self, validated_data: dict) -> Model:
return Model()
def update(self, instance: Model, validated_data: dict) -> Model:
return Model()

View File

@ -12,8 +12,8 @@ from rest_framework.viewsets import GenericViewSet
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer
from authentik.core.types import UserSettingSerializer
from authentik.flows.api.flows import FlowSerializer from authentik.flows.api.flows import FlowSerializer
from authentik.flows.challenge import Challenge
from authentik.flows.models import Stage from authentik.flows.models import Stage
from authentik.lib.templatetags.authentik_utils import verbose_name from authentik.lib.templatetags.authentik_utils import verbose_name
from authentik.lib.utils.reflection import all_subclasses from authentik.lib.utils.reflection import all_subclasses
@ -77,7 +77,7 @@ class StageViewSet(
data = sorted(data, key=lambda x: x["name"]) data = sorted(data, key=lambda x: x["name"])
return Response(TypeCreateSerializer(data, many=True).data) return Response(TypeCreateSerializer(data, many=True).data)
@swagger_auto_schema(responses={200: Challenge(many=True)}) @swagger_auto_schema(responses={200: UserSettingSerializer(many=True)})
@action(detail=False) @action(detail=False)
def user_settings(self, request: Request) -> Response: def user_settings(self, request: Request) -> Response:
"""Get all stages the user can configure""" """Get all stages the user can configure"""
@ -87,8 +87,8 @@ class StageViewSet(
user_settings = stage.ui_user_settings user_settings = stage.ui_user_settings
if not user_settings: if not user_settings:
continue continue
stage_challenge = user_settings user_settings.initial_data["object_uid"] = stage.pk
if not stage_challenge.is_valid(): if not user_settings.is_valid():
LOGGER.warning(stage_challenge.errors) LOGGER.warning(user_settings.errors)
matching_stages.append(stage_challenge.initial_data) matching_stages.append(user_settings.initial_data)
return Response(matching_stages) return Response(matching_stages)

View File

@ -10,7 +10,7 @@ from model_utils.managers import InheritanceManager
from rest_framework.serializers import BaseSerializer from rest_framework.serializers import BaseSerializer
from structlog.stdlib import get_logger from structlog.stdlib import get_logger
from authentik.flows.challenge import Challenge from authentik.core.types import UserSettingSerializer
from authentik.lib.models import InheritanceForeignKey, SerializerModel from authentik.lib.models import InheritanceForeignKey, SerializerModel
from authentik.policies.models import PolicyBindingModel from authentik.policies.models import PolicyBindingModel
@ -65,7 +65,7 @@ class Stage(SerializerModel):
raise NotImplementedError raise NotImplementedError
@property @property
def ui_user_settings(self) -> Optional[Challenge]: def ui_user_settings(self) -> Optional[UserSettingSerializer]:
"""Entrypoint to integrate with User settings. Can either return None if no """Entrypoint to integrate with User settings. Can either return None if no
user settings are available, or a challenge.""" user settings are available, or a challenge."""
return None return None

View File

@ -7207,13 +7207,12 @@ paths:
type: integer type: integer
responses: responses:
'200': '200':
description: Challenge that gets sent to the client based on which stage description: Serializer for User settings for stages and sources
is currently active
schema: schema:
description: '' description: ''
type: array type: array
items: items:
$ref: '#/definitions/Challenge' $ref: '#/definitions/UserSetting'
tags: tags:
- sources - sources
parameters: [] parameters: []
@ -7859,13 +7858,12 @@ paths:
type: integer type: integer
responses: responses:
'200': '200':
description: Challenge that gets sent to the client based on which stage description: Serializer for User settings for stages and sources
is currently active
schema: schema:
description: '' description: ''
type: array type: array
items: items:
$ref: '#/definitions/Challenge' $ref: '#/definitions/UserSetting'
tags: tags:
- stages - stages
parameters: [] parameters: []
@ -13483,6 +13481,26 @@ definitions:
title: Verbose name plural title: Verbose name plural
type: string type: string
readOnly: true readOnly: true
UserSetting:
description: Serializer for User settings for stages and sources
required:
- object_uid
- component
- title
type: object
properties:
object_uid:
title: Object uid
type: string
minLength: 1
component:
title: Component
type: string
minLength: 1
title:
title: Title
type: string
minLength: 1
LDAPSource: LDAPSource:
description: LDAP Source Serializer description: LDAP Source Serializer
required: required: