mirror of
https://github.com/goauthentik/authentik
synced 2026-05-12 01:47:06 +02:00
* api: add decorator to validate serializer in @action endpoints Signed-off-by: Jens Langhammer <jens@goauthentik.io> * rework to support query params Signed-off-by: Jens Langhammer <jens@goauthentik.io> * docs Signed-off-by: Jens Langhammer <jens@goauthentik.io> * migrate more Signed-off-by: Jens Langhammer <jens@goauthentik.io> * aaand some more Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix again Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
51 lines
1.6 KiB
Python
51 lines
1.6 KiB
Python
from collections.abc import Callable
|
|
from functools import wraps
|
|
from typing import Literal
|
|
|
|
from rest_framework.request import Request
|
|
from rest_framework.response import Response
|
|
from rest_framework.serializers import Serializer
|
|
from rest_framework.viewsets import ViewSet
|
|
|
|
|
|
def validate(serializer_type: type[Serializer], location: Literal["body", "query"] = "body"):
|
|
"""Validate incoming data with the specified serializer. Raw data can either be taken
|
|
from request body or query string, defaulting to body.
|
|
|
|
Validated data is added to the function this decorator is used on with a named parameter
|
|
based on the location of the data.
|
|
|
|
Example:
|
|
|
|
@validate(MySerializer)
|
|
@validate(MyQuerySerializer, location="query")
|
|
def my_action(self, request, *, body: MySerializer, query: MyQuerySerializer):
|
|
...
|
|
|
|
"""
|
|
|
|
def wrapper_outer(func: Callable):
|
|
|
|
@wraps(func)
|
|
def wrapper(self: ViewSet, request: Request, *args, **kwargs) -> Response:
|
|
data = {}
|
|
if location == "body":
|
|
data = request.data
|
|
elif location == "query":
|
|
data = request.query_params
|
|
else:
|
|
raise ValueError(f"Invalid data location '{location}'")
|
|
instance = serializer_type(
|
|
data=data,
|
|
context={
|
|
"request": request,
|
|
},
|
|
)
|
|
instance.is_valid(raise_exception=True)
|
|
kwargs[location] = instance
|
|
return func(self, request, *args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
return wrapper_outer
|