Skip to content

Commit a01cb8b

Browse files
jdg-journeyfrontcellofellowpre-commit-ci[bot]
authored
Fix user_id type mismatch when user claim is not pk (#851)
* Fix user_id type mismatch when user claim is not pk 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. Also include a test of handling the case where the user is deleted when the token is blacklisted. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Josh Gardner <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a9ee40d commit a01cb8b

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

rest_framework_simplejwt/tokens.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from uuid import uuid4
44

55
from django.conf import settings
6+
from django.contrib.auth import get_user_model
67
from django.contrib.auth.models import AbstractBaseUser
78
from django.utils.module_loading import import_string
89
from django.utils.translation import gettext_lazy as _
@@ -273,12 +274,17 @@ def blacklist(self) -> BlacklistedToken:
273274
jti = self.payload[api_settings.JTI_CLAIM]
274275
exp = self.payload["exp"]
275276
user_id = self.payload.get(api_settings.USER_ID_CLAIM)
277+
User = get_user_model()
278+
try:
279+
user = User.objects.get(**{api_settings.USER_ID_FIELD: user_id})
280+
except User.DoesNotExist:
281+
user = None
276282

277283
# Ensure outstanding token exists with given jti
278284
token, _ = OutstandingToken.objects.get_or_create(
279285
jti=jti,
280286
defaults={
281-
"user_id": user_id,
287+
"user": user,
282288
"created_at": self.current_time,
283289
"token": str(self),
284290
"expires_at": datetime_from_epoch(exp),

tests/test_token_blacklist.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,34 @@ def test_outstanding_token_and_blacklisted_token_user(self):
160160
outstanding_token = OutstandingToken.objects.get(token=token)
161161
self.assertEqual(outstanding_token.user, self.user)
162162

163+
@override_api_settings(USER_ID_FIELD="email", USER_ID_CLAIM="email")
164+
def test_outstanding_token_and_blacklisted_token_created_at_with_modified_user_id_field(
165+
self,
166+
):
167+
token = RefreshToken.for_user(self.user)
168+
169+
token.blacklist()
170+
outstanding_token = OutstandingToken.objects.get(token=token)
171+
self.assertEqual(outstanding_token.created_at, token.current_time)
172+
173+
@override_api_settings(USER_ID_FIELD="email", USER_ID_CLAIM="email")
174+
def test_outstanding_token_and_blacklisted_token_user_with_modifed_user_id_field(
175+
self,
176+
):
177+
token = RefreshToken.for_user(self.user)
178+
179+
token.blacklist()
180+
outstanding_token = OutstandingToken.objects.get(token=token)
181+
self.assertEqual(outstanding_token.user, self.user)
182+
183+
@override_api_settings(USER_ID_FIELD="email", USER_ID_CLAIM="email")
184+
def test_outstanding_token_with_deleted_user_and_modifed_user_id_field(self):
185+
self.assertFalse(BlacklistedToken.objects.exists())
186+
token = RefreshToken.for_user(self.user)
187+
self.user.delete()
188+
token.blacklist()
189+
self.assertTrue(BlacklistedToken.objects.count(), 1)
190+
163191

164192
class TestTokenBlacklistFlushExpiredTokens(TestCase):
165193
def setUp(self):

0 commit comments

Comments
 (0)