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/core/api/tokens.py

92 lines
2.7 KiB
Python

"""Tokens API Viewset"""
from django.http.response import Http404
from drf_spectacular.utils import OpenApiResponse, extend_schema
from rest_framework.decorators import action
from rest_framework.fields import CharField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.serializers import ModelSerializer
from rest_framework.viewsets import ModelViewSet
from authentik.api.decorators import permission_required
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.users import UserSerializer
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import USER_ATTRIBUTE_TOKEN_EXPIRING, Token, TokenIntents
from authentik.events.models import Event, EventAction
from authentik.managed.api import ManagedSerializer
class TokenSerializer(ManagedSerializer, ModelSerializer):
"""Token Serializer"""
user = UserSerializer(required=False)
class Meta:
model = Token
fields = [
"pk",
"managed",
"identifier",
"intent",
"user",
"description",
"expires",
"expiring",
]
depth = 2
class TokenViewSerializer(PassiveSerializer):
"""Show token's current key"""
key = CharField(read_only=True)
class TokenViewSet(UsedByMixin, ModelViewSet):
"""Token Viewset"""
lookup_field = "identifier"
queryset = Token.objects.all()
serializer_class = TokenSerializer
search_fields = [
"identifier",
"intent",
"user__username",
"description",
]
filterset_fields = [
"identifier",
"intent",
"user__username",
"description",
"expires",
"expiring",
]
ordering = ["expires"]
def perform_create(self, serializer: TokenSerializer):
serializer.save(
user=self.request.user,
intent=TokenIntents.INTENT_API,
expiring=self.request.user.attributes.get(USER_ATTRIBUTE_TOKEN_EXPIRING, True),
)
@permission_required("authentik_core.view_token_key")
@extend_schema(
responses={
200: TokenViewSerializer(many=False),
404: OpenApiResponse(description="Token not found or expired"),
}
)
@action(detail=True, pagination_class=None, filter_backends=[])
# pylint: disable=unused-argument
def view_key(self, request: Request, identifier: str) -> Response:
"""Return token key and log access"""
token: Token = self.get_object()
if token.is_expired:
raise Http404
Event.new(EventAction.SECRET_VIEW, secret=token).from_http(request) # noqa # nosec
return Response(TokenViewSerializer({"key": token.key}).data)