authentik.api.validation
1from collections.abc import Callable 2from functools import wraps 3from typing import Literal 4 5from rest_framework.request import Request 6from rest_framework.response import Response 7from rest_framework.serializers import Serializer 8from rest_framework.viewsets import ViewSet 9 10 11def validate(serializer_type: type[Serializer], location: Literal["body", "query"] = "body"): 12 """Validate incoming data with the specified serializer. Raw data can either be taken 13 from request body or query string, defaulting to body. 14 15 Validated data is added to the function this decorator is used on with a named parameter 16 based on the location of the data. 17 18 Example: 19 20 @validate(MySerializer) 21 @validate(MyQuerySerializer, location="query") 22 def my_action(self, request, *, body: MySerializer, query: MyQuerySerializer): 23 ... 24 25 """ 26 27 def wrapper_outer(func: Callable): 28 29 @wraps(func) 30 def wrapper(self: ViewSet, request: Request, *args, **kwargs) -> Response: 31 data = {} 32 if location == "body": 33 data = request.data 34 elif location == "query": 35 data = request.query_params 36 else: 37 raise ValueError(f"Invalid data location '{location}'") 38 instance = serializer_type( 39 data=data, 40 context={ 41 "request": request, 42 }, 43 ) 44 instance.is_valid(raise_exception=True) 45 kwargs[location] = instance 46 return func(self, request, *args, **kwargs) 47 48 return wrapper 49 50 return wrapper_outer
def
validate( serializer_type: type[rest_framework.serializers.Serializer], location: Literal['body', 'query'] = 'body'):
12def validate(serializer_type: type[Serializer], location: Literal["body", "query"] = "body"): 13 """Validate incoming data with the specified serializer. Raw data can either be taken 14 from request body or query string, defaulting to body. 15 16 Validated data is added to the function this decorator is used on with a named parameter 17 based on the location of the data. 18 19 Example: 20 21 @validate(MySerializer) 22 @validate(MyQuerySerializer, location="query") 23 def my_action(self, request, *, body: MySerializer, query: MyQuerySerializer): 24 ... 25 26 """ 27 28 def wrapper_outer(func: Callable): 29 30 @wraps(func) 31 def wrapper(self: ViewSet, request: Request, *args, **kwargs) -> Response: 32 data = {} 33 if location == "body": 34 data = request.data 35 elif location == "query": 36 data = request.query_params 37 else: 38 raise ValueError(f"Invalid data location '{location}'") 39 instance = serializer_type( 40 data=data, 41 context={ 42 "request": request, 43 }, 44 ) 45 instance.is_valid(raise_exception=True) 46 kwargs[location] = instance 47 return func(self, request, *args, **kwargs) 48 49 return wrapper 50 51 return wrapper_outer
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):
...