|
7 | 7 |
|
8 | 8 | from rest_framework_simplejwt.exceptions import TokenError |
9 | 9 | from rest_framework_simplejwt.serializers import ( |
10 | | - TokenObtainPairSerializer, TokenObtainSerializer, |
| 10 | + TokenBlacklistSerializer, TokenObtainPairSerializer, TokenObtainSerializer, |
11 | 11 | TokenObtainSlidingSerializer, TokenRefreshSerializer, |
12 | 12 | TokenRefreshSlidingSerializer, TokenVerifySerializer, |
13 | 13 | ) |
@@ -365,3 +365,76 @@ def test_it_should_return_given_token_if_everything_ok(self): |
365 | 365 | self.assertTrue(s.is_valid()) |
366 | 366 |
|
367 | 367 | self.assertEqual(len(s.validated_data), 0) |
| 368 | + |
| 369 | + |
| 370 | +class TestTokenBlacklistSerializer(TestCase): |
| 371 | + def test_it_should_raise_token_error_if_token_invalid(self): |
| 372 | + token = RefreshToken() |
| 373 | + del token['exp'] |
| 374 | + |
| 375 | + s = TokenBlacklistSerializer(data={'refresh': str(token)}) |
| 376 | + |
| 377 | + with self.assertRaises(TokenError) as e: |
| 378 | + s.is_valid() |
| 379 | + |
| 380 | + self.assertIn("has no 'exp' claim", e.exception.args[0]) |
| 381 | + |
| 382 | + token.set_exp(lifetime=-timedelta(days=1)) |
| 383 | + |
| 384 | + s = TokenBlacklistSerializer(data={'refresh': str(token)}) |
| 385 | + |
| 386 | + with self.assertRaises(TokenError) as e: |
| 387 | + s.is_valid() |
| 388 | + |
| 389 | + self.assertIn('invalid or expired', e.exception.args[0]) |
| 390 | + |
| 391 | + def test_it_should_raise_token_error_if_token_has_wrong_type(self): |
| 392 | + token = RefreshToken() |
| 393 | + token[api_settings.TOKEN_TYPE_CLAIM] = 'wrong_type' |
| 394 | + |
| 395 | + s = TokenBlacklistSerializer(data={'refresh': str(token)}) |
| 396 | + |
| 397 | + with self.assertRaises(TokenError) as e: |
| 398 | + s.is_valid() |
| 399 | + |
| 400 | + self.assertIn("wrong type", e.exception.args[0]) |
| 401 | + |
| 402 | + def test_it_should_return_nothing_if_everything_ok(self): |
| 403 | + refresh = RefreshToken() |
| 404 | + refresh['test_claim'] = 'arst' |
| 405 | + |
| 406 | + # Serializer validates |
| 407 | + s = TokenBlacklistSerializer(data={'refresh': str(refresh)}) |
| 408 | + |
| 409 | + now = aware_utcnow() - api_settings.ACCESS_TOKEN_LIFETIME / 2 |
| 410 | + |
| 411 | + with patch('rest_framework_simplejwt.tokens.aware_utcnow') as fake_aware_utcnow: |
| 412 | + fake_aware_utcnow.return_value = now |
| 413 | + self.assertTrue(s.is_valid()) |
| 414 | + |
| 415 | + self.assertDictEqual(s.validated_data, {}) |
| 416 | + |
| 417 | + def test_it_should_blacklist_refresh_token_if_everything_ok(self): |
| 418 | + self.assertEqual(OutstandingToken.objects.count(), 0) |
| 419 | + self.assertEqual(BlacklistedToken.objects.count(), 0) |
| 420 | + |
| 421 | + refresh = RefreshToken() |
| 422 | + |
| 423 | + refresh['test_claim'] = 'arst' |
| 424 | + |
| 425 | + old_jti = refresh['jti'] |
| 426 | + |
| 427 | + # Serializer validates |
| 428 | + ser = TokenBlacklistSerializer(data={'refresh': str(refresh)}) |
| 429 | + |
| 430 | + now = aware_utcnow() - api_settings.ACCESS_TOKEN_LIFETIME / 2 |
| 431 | + |
| 432 | + with patch('rest_framework_simplejwt.tokens.aware_utcnow') as fake_aware_utcnow: |
| 433 | + fake_aware_utcnow.return_value = now |
| 434 | + self.assertTrue(ser.is_valid()) |
| 435 | + |
| 436 | + self.assertEqual(OutstandingToken.objects.count(), 1) |
| 437 | + self.assertEqual(BlacklistedToken.objects.count(), 1) |
| 438 | + |
| 439 | + # Assert old refresh token is blacklisted |
| 440 | + self.assertEqual(BlacklistedToken.objects.first().token.jti, old_jti) |
0 commit comments