diff --git a/authentik/core/api/tokens.py b/authentik/core/api/tokens.py index ed69cd8c9..8e5c32d3e 100644 --- a/authentik/core/api/tokens.py +++ b/authentik/core/api/tokens.py @@ -31,8 +31,14 @@ class TokenSerializer(ManagedSerializer, ModelSerializer): def validate(self, attrs: dict[Any, str]) -> dict[Any, str]: """Ensure only API or App password tokens are created.""" - request: Request = self.context["request"] - attrs.setdefault("user", request.user) + request: Request = self.context.get("request") + if not request: + if "user" not in attrs: + raise ValidationError("Missing user") + if "intent" not in attrs: + raise ValidationError("Missing intent") + else: + attrs.setdefault("user", request.user) attrs.setdefault("intent", TokenIntents.INTENT_API) if attrs.get("intent") not in [TokenIntents.INTENT_API, TokenIntents.INTENT_APP_PASSWORD]: raise ValidationError(f"Invalid intent {attrs.get('intent')}") diff --git a/authentik/core/tests/test_token_api.py b/authentik/core/tests/test_token_api.py index bb57466d4..9f792d6d0 100644 --- a/authentik/core/tests/test_token_api.py +++ b/authentik/core/tests/test_token_api.py @@ -5,6 +5,7 @@ from django.urls.base import reverse from guardian.shortcuts import get_anonymous_user from rest_framework.test import APITestCase +from authentik.core.api.tokens import TokenSerializer from authentik.core.models import USER_ATTRIBUTE_TOKEN_EXPIRING, Token, TokenIntents, User from authentik.core.tests.utils import create_test_admin_user from authentik.lib.generators import generate_id @@ -99,3 +100,16 @@ class TestTokenAPI(APITestCase): self.assertEqual(len(body["results"]), 2) self.assertEqual(body["results"][0]["identifier"], token_should.identifier) self.assertEqual(body["results"][1]["identifier"], token_should_not.identifier) + + def test_serializer_no_request(self): + """Test serializer without request""" + self.assertTrue( + TokenSerializer( + data={ + "identifier": generate_id(), + "intent": TokenIntents.INTENT_APP_PASSWORD, + "key": generate_id(), + "user": self.user.pk, + } + ).is_valid(raise_exception=True) + )