Skip to content

Commit

Permalink
Fix user_id type mismatch when user claim is not pk
Browse files Browse the repository at this point in the history
Regarding changes made at https://github.com/jazzband/djangorestframework-simplejwt/pull/806/files

We're using a USER_ID_CLAIM that is neither the primary key field nor is it the
same type as the primary key, and these previous changes fail at this point
when attempting to create an OutstandingToken, because it assumes that the ID
pulled out of the token claims is usable as the database key for a user.

So to mitigate this gets the user from the database using the USER_ID_FIELD
setting and uses that in the get_or_create call.
  • Loading branch information
jdg-journeyfront committed Jan 8, 2025
1 parent cb00a8b commit d2aae8f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
8 changes: 7 additions & 1 deletion rest_framework_simplejwt/tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from uuid import uuid4

from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractBaseUser
from django.utils.module_loading import import_string
from django.utils.translation import gettext_lazy as _
Expand Down Expand Up @@ -266,12 +267,17 @@ def blacklist(self) -> BlacklistedToken:
jti = self.payload[api_settings.JTI_CLAIM]
exp = self.payload["exp"]
user_id = self.payload.get(api_settings.USER_ID_CLAIM)
User = get_user_model()
try:
user = User.objects.get(**{api_settings.USER_ID_FIELD: user_id})
except User.DoesNotExist:
user = None

# Ensure outstanding token exists with given jti
token, _ = OutstandingToken.objects.get_or_create(
jti=jti,
defaults={
"user_id": user_id,
"user": user,
"created_at": self.current_time,
"token": str(self),
"expires_at": datetime_from_epoch(exp),
Expand Down
21 changes: 20 additions & 1 deletion tests/test_token_blacklist.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from django.db.models import BigAutoField
from django.test import TestCase
from django.utils import timezone

from rest_framework_simplejwt.exceptions import TokenError
from rest_framework_simplejwt.serializers import TokenVerifySerializer
from rest_framework_simplejwt.settings import api_settings
Expand Down Expand Up @@ -160,6 +159,26 @@ def test_outstanding_token_and_blacklisted_token_user(self):
outstanding_token = OutstandingToken.objects.get(token=token)
self.assertEqual(outstanding_token.user, self.user)

@override_api_settings(USER_ID_FIELD="email", USER_ID_CLAIM="email")
def test_outstanding_token_and_blacklisted_token_created_at_with_modified_user_id_field(
self,
):
token = RefreshToken.for_user(self.user)

token.blacklist()
outstanding_token = OutstandingToken.objects.get(token=token)
self.assertEqual(outstanding_token.created_at, token.current_time)

@override_api_settings(USER_ID_FIELD="email", USER_ID_CLAIM="email")
def test_outstanding_token_and_blacklisted_token_user_with_modifed_user_id_field(
self,
):
token = RefreshToken.for_user(self.user)

token.blacklist()
outstanding_token = OutstandingToken.objects.get(token=token)
self.assertEqual(outstanding_token.user, self.user)


class TestTokenBlacklistFlushExpiredTokens(TestCase):
def setUp(self):
Expand Down

0 comments on commit d2aae8f

Please sign in to comment.