From a92adef751cb3ccd385a02b7c4be2a53a7a3cd20 Mon Sep 17 00:00:00 2001 From: Marc Salat Date: Tue, 25 Jan 2022 05:56:29 +0100 Subject: [PATCH 001/171] Fix ES locale translation error (#499) --- rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 6e647115c..5165bb4a5 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -51,7 +51,7 @@ msgstr "El token es inválido o ha expirado" #: serializers.py:24 msgid "No active account found with the given credentials" -msgstr "La combination de credenciales no tiene una cuenta activa" +msgstr "La combinación de credenciales no tiene una cuenta activa" #: settings.py:63 msgid "" From 3071865d10a204b1e72618c0b3c54374483172fc Mon Sep 17 00:00:00 2001 From: Christofer Bertonha Date: Tue, 25 Jan 2022 05:57:25 +0100 Subject: [PATCH 002/171] chore: test on Django 4.0 (#495) * chore: test on Django 4.0 * Remove Django 3.1 support from trove * Remove Django 3.1 from tox * Remove 3.1 reference in tox.ini Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- .github/workflows/test.yml | 10 ++-------- setup.py | 2 +- tox.ini | 15 +++++++-------- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2c57cba90..a344ba8f3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,19 +16,13 @@ jobs: max-parallel: 5 matrix: python-version: ['3.7', '3.8', '3.9', '3.10'] - django-version: ['2.2', '3.1', '3.2', 'main'] - drf-version: ['3.10', '3.11', '3.12'] + django-version: ['2.2', '3.2', '4.0', 'main'] + drf-version: ['3.10', '3.11', '3.12', '3.13'] exclude: - python-version: '3.7' django-version: 'main' - - python-version: '3.8' - django-version: 'main' - - django-version: '3.1' - drf-version: '3.10' - python-version: '3.10' django-version: '2.2' - - python-version: '3.10' - django-version: '3.1' steps: - uses: actions/checkout@v2 diff --git a/setup.py b/setup.py index 3d4e7e235..286921f00 100755 --- a/setup.py +++ b/setup.py @@ -66,8 +66,8 @@ "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 2.2", - "Framework :: Django :: 3.1", "Framework :: Django :: 3.2", + "Framework :: Django :: 4.0", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", diff --git a/tox.ini b/tox.ini index 8839a7ef4..bcd2cd76c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,29 +1,28 @@ [tox] envlist= py{37,38,39}-dj22-drf310-tests - py{37,38,39}-dj{22,31}-drf{311,312}-tests - py{37,38,39,310}-dj32-drf{311,312}-tests - py{38,39,310}-djmain-drf312-tests + py{37,38,39,310}-dj{22,32}-drf{311,312,313}-tests + py{38,39,310}-dj{40,main}-drf313-tests docs [gh-actions] python= 3.7: py37 - 3.8: py38, docs, lint + 3.8: py38, docs 3.9: py39 3.10: py310 [gh-actions:env] DJANGO= 2.2: dj22 - 3.0: dj30 - 3.1: dj31 3.2: dj32 + 4.0: dj40 main: djmain DRF= 3.10: drf310 3.11: drf311 3.12: drf312 + 3.13: drf313 [testenv] usedevelop=True @@ -35,13 +34,13 @@ setenv= PYTHONDONTWRITEBYTECODE=1 deps= dj22: Django>=2.2,<2.3 - dj31: Django>=3.1,<3.2 dj32: Django>=3.2,<3.3 + dj40: Django>=4.0,<4.1 drf310: djangorestframework>=3.10,<3.11 drf311: djangorestframework>=3.11,<3.12 drf312: djangorestframework>=3.12,<3.13 + drf313: djangorestframework>=3.13,<3.14 djmain: https://github.com/django/django/archive/main.tar.gz - djmain: pytz allowlist_externals=make [testenv:docs] From 9014f14bd983b630e94d9107faddf472c9120adb Mon Sep 17 00:00:00 2001 From: vainu-arto <70135394+vainu-arto@users.noreply.github.com> Date: Tue, 25 Jan 2022 06:57:37 +0200 Subject: [PATCH 003/171] Stop deleting blacklist on user delete (#516) * OutstandingToken user on_delete should be null * Add test to verify that deleting a User doesn't remove tokens from the blacklist This is a rather unexpected default behavior. Deleting a User means that their blacklisted tokens become live again. * Add migration for cascading User deletion to SET_NULL instead of DELETE * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .../0012_alter_outstandingtoken_user.py | 26 +++++++++++++++++++ .../token_blacklist/models.py | 2 +- tests/test_token_blacklist.py | 23 ++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 rest_framework_simplejwt/token_blacklist/migrations/0012_alter_outstandingtoken_user.py diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0012_alter_outstandingtoken_user.py b/rest_framework_simplejwt/token_blacklist/migrations/0012_alter_outstandingtoken_user.py new file mode 100644 index 000000000..652f06b69 --- /dev/null +++ b/rest_framework_simplejwt/token_blacklist/migrations/0012_alter_outstandingtoken_user.py @@ -0,0 +1,26 @@ +# Generated by Django 3.2.10 on 2022-01-24 06:42 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ("token_blacklist", "0011_linearizes_history"), + ] + + operations = [ + migrations.AlterField( + model_name="outstandingtoken", + name="user", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to=settings.AUTH_USER_MODEL, + ), + ), + ] diff --git a/rest_framework_simplejwt/token_blacklist/models.py b/rest_framework_simplejwt/token_blacklist/models.py index b646cd23a..c84b8c4ae 100644 --- a/rest_framework_simplejwt/token_blacklist/models.py +++ b/rest_framework_simplejwt/token_blacklist/models.py @@ -5,7 +5,7 @@ class OutstandingToken(models.Model): id = models.BigAutoField(primary_key=True, serialize=False) user = models.ForeignKey( - settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True + settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True ) jti = models.CharField(unique=True, max_length=255) diff --git a/tests/test_token_blacklist.py b/tests/test_token_blacklist.py index 8286c936b..67ea7fada 100644 --- a/tests/test_token_blacklist.py +++ b/tests/test_token_blacklist.py @@ -172,6 +172,29 @@ def test_it_should_delete_any_expired_tokens(self): [not_expired_2["jti"], not_expired_3["jti"]], ) + def test_token_blacklist_will_not_be_removed_on_User_delete(self): + token = RefreshToken.for_user(self.user) + outstanding_token = OutstandingToken.objects.first() + + # Should raise no exception + RefreshToken(str(token)) + + # Add token to blacklist + BlacklistedToken.objects.create(token=outstanding_token) + + with self.assertRaises(TokenError) as e: + # Should raise exception + RefreshToken(str(token)) + self.assertIn("blacklisted", e.exception.args[0]) + + # Delete the User and try again + self.user.delete() + + with self.assertRaises(TokenError) as e: + # Should raise exception + RefreshToken(str(token)) + self.assertIn("blacklisted", e.exception.args[0]) + class TestPopulateJtiHexMigration(MigrationTestCase): migrate_from = ("token_blacklist", "0002_outstandingtoken_jti_hex") From 72dd1a586f919b9e8fe902afe6386e32f375f075 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Jan 2022 23:58:24 -0500 Subject: [PATCH 004/171] [pre-commit.ci] pre-commit autoupdate (#498) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.0.1 → v4.1.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.0.1...v4.1.0) - [github.com/asottile/yesqa: v1.2.3 → v1.3.0](https://github.com/asottile/yesqa/compare/v1.2.3...v1.3.0) - [github.com/pycqa/isort: 5.9.3 → 5.10.1](https://github.com/pycqa/isort/compare/5.9.3...5.10.1) - [github.com/psf/black: 21.9b0 → 21.12b0](https://github.com/psf/black/compare/21.9b0...21.12b0) - [github.com/pre-commit/pre-commit-hooks: v4.0.1 → v4.1.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.0.1...v4.1.0) - [github.com/asottile/pyupgrade: v2.28.0 → v2.31.0](https://github.com/asottile/pyupgrade/compare/v2.28.0...v2.31.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f692d7f62..1996be7e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,24 +1,24 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.0.1' + rev: 'v4.1.0' hooks: - id: check-merge-conflict - repo: https://github.com/asottile/yesqa - rev: v1.2.3 + rev: v1.3.0 hooks: - id: yesqa - repo: https://github.com/pycqa/isort - rev: '5.9.3' + rev: '5.10.1' hooks: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '21.9b0' + rev: '21.12b0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.0.1' + rev: 'v4.1.0' hooks: - id: end-of-file-fixer exclude: >- @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.28.0' + rev: 'v2.31.0' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From 92124cfc1fbb2401e88ed0f72ce28fb60f377554 Mon Sep 17 00:00:00 2001 From: vainu-arto <70135394+vainu-arto@users.noreply.github.com> Date: Fri, 28 Jan 2022 18:03:26 +0200 Subject: [PATCH 005/171] Enable ECDSA algorithms supported by PyJWT (#520) * Parameterize some tests to reduce duplication and make it easy to add more algorithms This way new algorithms can be added to the basic test set simply by adding their backends to TestTokenBackend.backends. * Enable ECDSA algorithms supported by PyJWT Enable the algorithms and add basic tests for them. Also convert the ALLOWED_ALGORITHMS constant to a set for a minor style cleanup. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/backends.py | 7 +- tests/keys.py | 15 ++ tests/test_backends.py | 221 ++++++++++++--------------- 3 files changed, 121 insertions(+), 122 deletions(-) diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index 40ceee486..49282b486 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -5,14 +5,17 @@ from .exceptions import TokenBackendError from .utils import format_lazy -ALLOWED_ALGORITHMS = ( +ALLOWED_ALGORITHMS = { "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", -) + "ES256", + "ES384", + "ES512", +} class TokenBackend: diff --git a/tests/keys.py b/tests/keys.py index 09a977de0..aa93d7d95 100644 --- a/tests/keys.py +++ b/tests/keys.py @@ -110,3 +110,18 @@ E01hmaHk9xlOpo73IjUxhXUCAwEAAQ== -----END PUBLIC KEY----- """ + +ES256_PRIVATE_KEY = """ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIMtBPxiLHcJCrAGdz4jHvTtAh6Rw7351AckG3whXq2WOoAoGCCqGSM49 +AwEHoUQDQgAEMZHyNxbkr7+zqQ1dQk/zug2pwYdztmjhpC+XqK88q5NfIS1cBYYt +zhHUS4vGpazNqbW8HA3ZIvJRmx4L96O6/w== +-----END EC PRIVATE KEY----- +""" + +ES256_PUBLIC_KEY = """ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMZHyNxbkr7+zqQ1dQk/zug2pwYdz +tmjhpC+XqK88q5NfIS1cBYYtzhHUS4vGpazNqbW8HA3ZIvJRmx4L96O6/w== +-----END PUBLIC KEY----- +""" diff --git a/tests/test_backends.py b/tests/test_backends.py index d6e16398b..94a56829e 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -9,7 +9,14 @@ from rest_framework_simplejwt.backends import TokenBackend from rest_framework_simplejwt.exceptions import TokenBackendError from rest_framework_simplejwt.utils import aware_utcnow, datetime_to_epoch, make_utc -from tests.keys import PRIVATE_KEY, PRIVATE_KEY_2, PUBLIC_KEY, PUBLIC_KEY_2 +from tests.keys import ( + ES256_PRIVATE_KEY, + ES256_PUBLIC_KEY, + PRIVATE_KEY, + PRIVATE_KEY_2, + PUBLIC_KEY, + PUBLIC_KEY_2, +) SECRET = "not_secret" @@ -31,6 +38,13 @@ def setUp(self): "RS256", PRIVATE_KEY, PUBLIC_KEY, AUDIENCE, ISSUER ) self.payload = {"foo": "bar"} + self.backends = ( + self.hmac_token_backend, + self.rsa_token_backend, + TokenBackend("ES256", ES256_PRIVATE_KEY, ES256_PUBLIC_KEY), + TokenBackend("ES384", ES256_PRIVATE_KEY, ES256_PUBLIC_KEY), + TokenBackend("ES512", ES256_PRIVATE_KEY, ES256_PUBLIC_KEY), + ) def test_init(self): # Should reject unknown algorithms @@ -41,18 +55,12 @@ def test_init(self): @patch.object(algorithms, "has_crypto", new=False) def test_init_fails_for_rs_algorithms_when_crypto_not_installed(self): - with self.assertRaisesRegex( - TokenBackendError, "You must have cryptography installed to use RS256." - ): - TokenBackend("RS256", "not_secret") - with self.assertRaisesRegex( - TokenBackendError, "You must have cryptography installed to use RS384." - ): - TokenBackend("RS384", "not_secret") - with self.assertRaisesRegex( - TokenBackendError, "You must have cryptography installed to use RS512." - ): - TokenBackend("RS512", "not_secret") + for algo in ("RS256", "RS384", "RS512", "ES256"): + with self.assertRaisesRegex( + TokenBackendError, + f"You must have cryptography installed to use {algo}.", + ): + TokenBackend(algo, "not_secret") def test_encode_hmac(self): # Should return a JSON web token for the given payload @@ -113,127 +121,100 @@ def test_encode_aud_iss(self): ), ) - def test_decode_hmac_with_no_expiry(self): - no_exp_token = jwt.encode(self.payload, SECRET, algorithm="HS256") + def test_decode_with_no_expiry(self): + for backend in self.backends: + with self.subTest("Test decode with no expiry for f{backend.algorithm}"): + no_exp_token = jwt.encode( + self.payload, backend.signing_key, algorithm=backend.algorithm + ) - self.hmac_token_backend.decode(no_exp_token) + backend.decode(no_exp_token) - def test_decode_hmac_with_no_expiry_no_verify(self): - no_exp_token = jwt.encode(self.payload, SECRET, algorithm="HS256") + def test_decode_with_no_expiry_no_verify(self): + for backend in self.backends: + with self.subTest( + "Test decode with no expiry and no verify for f{backend.algorithm}" + ): + no_exp_token = jwt.encode( + self.payload, backend.signing_key, algorithm=backend.algorithm + ) - self.assertEqual( - self.hmac_token_backend.decode(no_exp_token, verify=False), - self.payload, - ) + self.assertEqual( + backend.decode(no_exp_token, verify=False), + self.payload, + ) - def test_decode_hmac_with_expiry(self): + def test_decode_with_expiry(self): self.payload["exp"] = aware_utcnow() - timedelta(seconds=1) + for backend in self.backends: + with self.subTest("Test decode with expiry for f{backend.algorithm}"): - expired_token = jwt.encode(self.payload, SECRET, algorithm="HS256") - - with self.assertRaises(TokenBackendError): - self.hmac_token_backend.decode(expired_token) - - def test_decode_hmac_with_invalid_sig(self): - self.payload["exp"] = aware_utcnow() + timedelta(days=1) - token_1 = jwt.encode(self.payload, SECRET, algorithm="HS256") - self.payload["foo"] = "baz" - token_2 = jwt.encode(self.payload, SECRET, algorithm="HS256") - - token_2_payload = token_2.rsplit(".", 1)[0] - token_1_sig = token_1.rsplit(".", 1)[-1] - invalid_token = token_2_payload + "." + token_1_sig - - with self.assertRaises(TokenBackendError): - self.hmac_token_backend.decode(invalid_token) + expired_token = jwt.encode( + self.payload, backend.signing_key, algorithm=backend.algorithm + ) - def test_decode_hmac_with_invalid_sig_no_verify(self): - self.payload["exp"] = aware_utcnow() + timedelta(days=1) - token_1 = jwt.encode(self.payload, SECRET, algorithm="HS256") - self.payload["foo"] = "baz" - token_2 = jwt.encode(self.payload, SECRET, algorithm="HS256") - # Payload copied - self.payload["exp"] = datetime_to_epoch(self.payload["exp"]) - - token_2_payload = token_2.rsplit(".", 1)[0] - token_1_sig = token_1.rsplit(".", 1)[-1] - invalid_token = token_2_payload + "." + token_1_sig - - self.assertEqual( - self.hmac_token_backend.decode(invalid_token, verify=False), - self.payload, - ) - - def test_decode_hmac_success(self): - self.payload["exp"] = aware_utcnow() + timedelta(days=1) - self.payload["foo"] = "baz" - - token = jwt.encode(self.payload, SECRET, algorithm="HS256") - # Payload copied - self.payload["exp"] = datetime_to_epoch(self.payload["exp"]) + with self.assertRaises(TokenBackendError): + backend.decode(expired_token) - self.assertEqual(self.hmac_token_backend.decode(token), self.payload) - - def test_decode_rsa_with_no_expiry(self): - no_exp_token = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - - self.rsa_token_backend.decode(no_exp_token) - - def test_decode_rsa_with_no_expiry_no_verify(self): - no_exp_token = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - - self.assertEqual( - self.hmac_token_backend.decode(no_exp_token, verify=False), - self.payload, - ) - - def test_decode_rsa_with_expiry(self): + def test_decode_with_invalid_sig(self): self.payload["exp"] = aware_utcnow() - timedelta(seconds=1) - - expired_token = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - - with self.assertRaises(TokenBackendError): - self.rsa_token_backend.decode(expired_token) - - def test_decode_rsa_with_invalid_sig(self): - self.payload["exp"] = aware_utcnow() + timedelta(days=1) - token_1 = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - self.payload["foo"] = "baz" - token_2 = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - - token_2_payload = token_2.rsplit(".", 1)[0] - token_1_sig = token_1.rsplit(".", 1)[-1] - invalid_token = token_2_payload + "." + token_1_sig - - with self.assertRaises(TokenBackendError): - self.rsa_token_backend.decode(invalid_token) - - def test_decode_rsa_with_invalid_sig_no_verify(self): + for backend in self.backends: + with self.subTest("Test decode with invalid sig for f{backend.algorithm}"): + payload = self.payload.copy() + payload["exp"] = aware_utcnow() + timedelta(days=1) + token_1 = jwt.encode( + payload, backend.signing_key, algorithm=backend.algorithm + ) + payload["foo"] = "baz" + token_2 = jwt.encode( + payload, backend.signing_key, algorithm=backend.algorithm + ) + + token_2_payload = token_2.rsplit(".", 1)[0] + token_1_sig = token_1.rsplit(".", 1)[-1] + invalid_token = token_2_payload + "." + token_1_sig + + with self.assertRaises(TokenBackendError): + backend.decode(invalid_token) + + def test_decode_with_invalid_sig_no_verify(self): self.payload["exp"] = aware_utcnow() + timedelta(days=1) - token_1 = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - self.payload["foo"] = "baz" - token_2 = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - - token_2_payload = token_2.rsplit(".", 1)[0] - token_1_sig = token_1.rsplit(".", 1)[-1] - invalid_token = token_2_payload + "." + token_1_sig - # Payload copied - self.payload["exp"] = datetime_to_epoch(self.payload["exp"]) - - self.assertEqual( - self.hmac_token_backend.decode(invalid_token, verify=False), - self.payload, - ) - - def test_decode_rsa_success(self): + for backend in self.backends: + with self.subTest("Test decode with invalid sig for f{backend.algorithm}"): + payload = self.payload.copy() + token_1 = jwt.encode( + payload, backend.signing_key, algorithm=backend.algorithm + ) + payload["foo"] = "baz" + token_2 = jwt.encode( + payload, backend.signing_key, algorithm=backend.algorithm + ) + # Payload copied + payload["exp"] = datetime_to_epoch(payload["exp"]) + + token_2_payload = token_2.rsplit(".", 1)[0] + token_1_sig = token_1.rsplit(".", 1)[-1] + invalid_token = token_2_payload + "." + token_1_sig + + self.assertEqual( + backend.decode(invalid_token, verify=False), + payload, + ) + + def test_decode_success(self): self.payload["exp"] = aware_utcnow() + timedelta(days=1) self.payload["foo"] = "baz" + for backend in self.backends: + with self.subTest("Test decode success for f{backend.algorithm}"): - token = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - # Payload copied - self.payload["exp"] = datetime_to_epoch(self.payload["exp"]) + token = jwt.encode( + self.payload, backend.signing_key, algorithm=backend.algorithm + ) + # Payload copied + payload = self.payload.copy() + payload["exp"] = datetime_to_epoch(self.payload["exp"]) - self.assertEqual(self.rsa_token_backend.decode(token), self.payload) + self.assertEqual(backend.decode(token), payload) def test_decode_aud_iss_success(self): self.payload["exp"] = aware_utcnow() + timedelta(days=1) From 1b2e20e48c05f0f2975c2fafbb12146cecc32882 Mon Sep 17 00:00:00 2001 From: vainu-arto <70135394+vainu-arto@users.noreply.github.com> Date: Sat, 29 Jan 2022 05:56:23 +0200 Subject: [PATCH 006/171] Simplify using custom token classes in serializers (#517) For most cases this could be done by overriding get_token, which is simple enough. The exception was TokenRefreshSerializer.validate where the entire method needed to be copy-pasted to allow using a custom replacement for RefreshToken. The other cases are changed the same way mainly for consistency. --- rest_framework_simplejwt/serializers.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index 8e98ceda6..64213c722 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -24,6 +24,7 @@ def __init__(self, *args, **kwargs): class TokenObtainSerializer(serializers.Serializer): username_field = get_user_model().USERNAME_FIELD + token_class = None default_error_messages = { "no_active_account": _("No active account found with the given credentials") @@ -57,15 +58,11 @@ def validate(self, attrs): @classmethod def get_token(cls, user): - raise NotImplementedError( - "Must implement `get_token` method for `TokenObtainSerializer` subclasses" - ) + return cls.token_class.for_user(user) class TokenObtainPairSerializer(TokenObtainSerializer): - @classmethod - def get_token(cls, user): - return RefreshToken.for_user(user) + token_class = RefreshToken def validate(self, attrs): data = super().validate(attrs) @@ -82,9 +79,7 @@ def validate(self, attrs): class TokenObtainSlidingSerializer(TokenObtainSerializer): - @classmethod - def get_token(cls, user): - return SlidingToken.for_user(user) + token_class = SlidingToken def validate(self, attrs): data = super().validate(attrs) @@ -102,9 +97,10 @@ def validate(self, attrs): class TokenRefreshSerializer(serializers.Serializer): refresh = serializers.CharField() access = serializers.CharField(read_only=True) + token_class = RefreshToken def validate(self, attrs): - refresh = RefreshToken(attrs["refresh"]) + refresh = self.token_class(attrs["refresh"]) data = {"access": str(refresh.access_token)} @@ -129,9 +125,10 @@ def validate(self, attrs): class TokenRefreshSlidingSerializer(serializers.Serializer): token = serializers.CharField() + token_class = SlidingToken def validate(self, attrs): - token = SlidingToken(attrs["token"]) + token = self.token_class(attrs["token"]) # Check that the timestamp in the "refresh_exp" claim has not # passed @@ -163,9 +160,10 @@ def validate(self, attrs): class TokenBlacklistSerializer(serializers.Serializer): refresh = serializers.CharField() + token_class = RefreshToken def validate(self, attrs): - refresh = RefreshToken(attrs["refresh"]) + refresh = self.token_class(attrs["refresh"]) try: refresh.blacklist() except AttributeError: From 4feb37aede0da3471a4c6007c44707f99ae65185 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 1 Feb 2022 02:57:15 +0900 Subject: [PATCH 007/171] [pre-commit.ci] pre-commit autoupdate (#524) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 21.12b0 → 22.1.0](https://github.com/psf/black/compare/21.12b0...22.1.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1996be7e3..861b9281a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '21.12b0' + rev: '22.1.0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ From ed0f7b61ed4570f8e2a9f17f0a377be5dcf106b8 Mon Sep 17 00:00:00 2001 From: yeongkwang Date: Wed, 2 Feb 2022 15:20:05 +0900 Subject: [PATCH 008/171] Make the token serializer configurable (#521) --- rest_framework_simplejwt/settings.py | 6 ++++++ rest_framework_simplejwt/views.py | 22 ++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/rest_framework_simplejwt/settings.py b/rest_framework_simplejwt/settings.py index e6463b4f7..b4bac42ff 100644 --- a/rest_framework_simplejwt/settings.py +++ b/rest_framework_simplejwt/settings.py @@ -34,6 +34,12 @@ "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp", "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5), "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1), + "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer", + "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer", + "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer", + "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer", + "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer", + "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer", } IMPORT_STRINGS = ( diff --git a/rest_framework_simplejwt/views.py b/rest_framework_simplejwt/views.py index 7a13eb59d..f523469ac 100644 --- a/rest_framework_simplejwt/views.py +++ b/rest_framework_simplejwt/views.py @@ -1,9 +1,11 @@ +from django.utils.module_loading import import_string from rest_framework import generics, status from rest_framework.response import Response from . import serializers from .authentication import AUTH_HEADER_TYPES from .exceptions import InvalidToken, TokenError +from .settings import api_settings class TokenViewBase(generics.GenericAPIView): @@ -14,6 +16,14 @@ class TokenViewBase(generics.GenericAPIView): www_authenticate_realm = "api" + def get_serializer_class(self): + # Get the serializer from settings + try: + return import_string(self._serializer_class) + except ImportError: + msg = "Could not import serializer '%s'" % self._serializer_class + raise ImportError(msg) + def get_authenticate_header(self, request): return '{} realm="{}"'.format( AUTH_HEADER_TYPES[0], @@ -37,7 +47,7 @@ class TokenObtainPairView(TokenViewBase): token pair to prove the authentication of those credentials. """ - serializer_class = serializers.TokenObtainPairSerializer + _serializer_class = api_settings.TOKEN_OBTAIN_SERIALIZER token_obtain_pair = TokenObtainPairView.as_view() @@ -49,7 +59,7 @@ class TokenRefreshView(TokenViewBase): token if the refresh token is valid. """ - serializer_class = serializers.TokenRefreshSerializer + _serializer_class = api_settings.TOKEN_REFRESH_SERIALIZER token_refresh = TokenRefreshView.as_view() @@ -61,7 +71,7 @@ class TokenObtainSlidingView(TokenViewBase): prove the authentication of those credentials. """ - serializer_class = serializers.TokenObtainSlidingSerializer + _serializer_class = api_settings.SLIDING_TOKEN_OBTAIN_SERIALIZER token_obtain_sliding = TokenObtainSlidingView.as_view() @@ -73,7 +83,7 @@ class TokenRefreshSlidingView(TokenViewBase): token's refresh period has not expired. """ - serializer_class = serializers.TokenRefreshSlidingSerializer + _serializer_class = api_settings.SLIDING_TOKEN_REFRESH_SERIALIZER token_refresh_sliding = TokenRefreshSlidingView.as_view() @@ -85,7 +95,7 @@ class TokenVerifyView(TokenViewBase): information about a token's fitness for a particular use. """ - serializer_class = serializers.TokenVerifySerializer + _serializer_class = api_settings.TOKEN_VERIFY_SERIALIZER token_verify = TokenVerifyView.as_view() @@ -97,7 +107,7 @@ class TokenBlacklistView(TokenViewBase): `rest_framework_simplejwt.token_blacklist` app installed. """ - serializer_class = serializers.TokenBlacklistSerializer + _serializer_class = api_settings.TOKEN_BLACKLIST_SERIALIZER token_blacklist = TokenBlacklistView.as_view() From 40a7cb1200468ce4ed9d2357463820e935c6daca Mon Sep 17 00:00:00 2001 From: yeongkwang Date: Thu, 3 Feb 2022 00:21:51 +0900 Subject: [PATCH 009/171] Update translation files (#526) --- .../locale/cs/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/de_CH/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/es/LC_MESSAGES/django.mo | Bin 2349 -> 2350 bytes .../locale/es/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/es_AR/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/es_CL/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/fa_IR/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/fr/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/id_ID/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/it_IT/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/ko_KR/LC_MESSAGES/django.po | 12 ++--- .../locale/nl_NL/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/pl_PL/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/pt_BR/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/ru_RU/LC_MESSAGES/django.po | 42 +++++++-------- .../locale/tr/LC_MESSAGES/django.po | 16 +++--- .../locale/uk_UA/LC_MESSAGES/django.po | 49 ++++++++---------- .../locale/zh_Hans/LC_MESSAGES/django.po | 47 ++++++++--------- 18 files changed, 333 insertions(+), 337 deletions(-) diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index 16fd7ad4c..022575397 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -11,65 +11,65 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "Autorizační hlavička musí obsahovat dvě hodnoty oddělené mezerou" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Daný token není validní pro žádný typ tokenu" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "Token neobsahoval žádnou rozpoznatelnou identifikaci uživatele" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Uživatel nenalezen" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Uživatel není aktivní" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Nerozpoznaný typ algoritmu '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "Nastavení '{}' bylo odstraněno. Dostupná nastavení jsou v '{}'" -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "uživatel" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "vytvořený v" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "platí do" @@ -81,26 +81,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Nelze vytvořit token bez zadaného typu nebo životnosti" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Token nemá žádný identifikátor" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Token nemá žádný typ" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Token má špatný typ" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Token nemá žádnou hodnotu '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Hodnota tokenu '{}' vypršela" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po index 5b70353ff..7970628af 100644 --- a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po @@ -12,48 +12,48 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "Der Authorizationheader muss zwei leerzeichen-getrennte Werte enthalten" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Der Token ist für keinen Tokentyp gültig" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "Token enthält keine erkennbare Benutzeridentifikation" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Benutzer nicht gefunden" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Inaktiver Benutzer" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Unerkannter Algorithmustyp '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -61,19 +61,19 @@ msgstr "" "Die Einstellung '{}' wurde gelöscht. Bitte beachte '{}' für verfügbare " "Einstellungen." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "Benutzer" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "erstellt am" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "läuft ab am" @@ -85,26 +85,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Ein Token ohne Typ oder Lebensdauer kann nicht erstellt werden" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Token hat keine Id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Token hat keinen Typ" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Token hat den falschen Typ" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Token hat kein '{}' Recht" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Das Tokenrecht '{}' ist abgelaufen" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.mo index a25a73868622601b4d4334a14a5556943f346482..803232a04c46f44157ee3177176d8d8bb809f5d5 100644 GIT binary patch delta 173 zcmWm6y$XV07>41;G=Byiq{M~>OCoS-j^<9GS&X2gsIemmItV5BwpIrZpt-{c8oR&c zz24#BZqqJ(dd_7l>E%l`esPV5K$_wecX-DV-#Eb^W*CQ3fhEpyk4rqF-QRGAE!y6I e8~k8|NkqmzImg8X($>m6oNDYf=iZpXKaKv<

QD delta 172 zcmZ1{v{q;X3uC<{0|Ub@HU@@7ApHeMYXIpmb_NDfAYBinZGiMtAguzVF9B&0ApIRk zivejK4h9BAAgv6fWr4ISkX8oL$v_&Uz8y$Q0_inC8f4xvAZ-Ao?*M5|AkE7OGzP>F e2NKLcS`kPC&1O*DJd;tImAND{fAa~pG$sJF=o4T7 diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 5165bb4a5..694972af9 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -12,48 +12,48 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "El encabezado 'Authorization' debe contener valores delimitados por espacios" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "El token dado no es valido para ningun tipo de token" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "El token no contenía identificación de usuario reconocible" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "Debe tener criptografía instalada para usar {}." -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "Algoritmo especificado no válido" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "La combinación de credenciales no tiene una cuenta activa" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -61,19 +61,19 @@ msgstr "" "La configuración '{}' fue removida. Por favor, refiérase a '{}' para " "consultar las disponibles." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "usuario" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "creado en" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "expira en" @@ -85,26 +85,26 @@ msgstr "Lista negra de Tokens" msgid "Cannot create token with no type or lifetime" msgstr "No se puede crear un token sin tipo o de tan larga vida" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index ebec2a3de..a5365b6c7 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -17,49 +17,49 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "El header de autorización debe contener dos valores delimitados por espacio" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "El token dado no es válido para ningún tipo de token" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "El token no contiene ninguna identificación de usuario" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales dadas" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -67,19 +67,19 @@ msgstr "" "La configuración '{}' fue removida. Por favor, refiérase a '{}' para " "consultar las configuraciones disponibles." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "usuario" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "creado en" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "expira en" @@ -91,26 +91,26 @@ msgstr "Lista negra de Tokens" msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "El token está en la lista negra" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index 2869d6b0d..229c8ab21 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -12,49 +12,49 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "El header de autorización debe contener dos valores delimitados por espacio" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "El token provisto no es válido para ningún tipo de token" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "El token no contiene identificación de usuario reconocible" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token inválido o expirado" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -62,19 +62,19 @@ msgstr "" "La configuración '{}' fue removida. Por favor, refiérase a '{}' para " "configuraciones disponibles." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "Usuario" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "creado en" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "expira en" @@ -86,26 +86,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Token no tiene id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Token no tiene tipo" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Token tiene tipo erróneo" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Token no tiene privilegio '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "El provilegio '{}' del token está expirado" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index f39b6b162..8a81f3b22 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -11,65 +11,65 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا شده با فاصله باشد" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "کاربر یافت نشد" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "تنظیمات '{}' حذف شده است. لطفا به '{}' برای تنظیمات موجود مراجعه کنید." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "کاربر" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "زمان ایجاد" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "زمان انقضا" @@ -81,26 +81,26 @@ msgstr "لیست سیاه توکن" msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index fd2cd1c16..9f6dcbcfd 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -11,49 +11,49 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "L'en-tête 'Authorization' doit contenir deux valeurs séparées par des espaces" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Le type de jeton fourni n'est pas valide" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "" "Le jeton ne contient aucune information permettant d'identifier l'utilisateur" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "L'utilisateur n'a pas été trouvé" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "L'utilisateur est désactivé" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Type d'algorithme non reconnu '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "Vous devez installer cryptography afin d'utiliser {}." -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "L'algorithme spécifié est invalide" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -61,19 +61,19 @@ msgstr "" "Le paramètre '{}' a été supprimé. Voir '{}' pour la liste des paramètres " "disponibles." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "Utilisateur" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "Créé le" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "Expire le" @@ -85,26 +85,26 @@ msgstr "Liste des jetons bannis" msgid "Cannot create token with no type or lifetime" msgstr "Ne peut pas créer de jeton sans type ni durée de vie" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Le jeton n'a pas d'id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Le jeton n'a pas de type" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Le jeton a un type erroné" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Le jeton n'a pas le privilège '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Le privilège '{}' du jeton a expiré" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index bab7fc973..f0e338ede 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -12,47 +12,47 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "Header otorisasi harus berisi dua nilai yang dipisahkan spasi" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Token yang diberikan tidak valid untuk semua jenis token" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "Token tidak mengandung identifikasi pengguna yang dapat dikenali" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Pengguna tidak ditemukan" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Pengguna tidak aktif" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Jenis algoritma tidak dikenal '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "Anda harus memasang kriptografi untuk menggunakan {}." -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "Algoritma yang ditentukan tidak valid" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -60,19 +60,19 @@ msgstr "" "Setelan '{}' telah dihapus. Silakan merujuk ke '{}' untuk pengaturan yang " "tersedia." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "pengguna" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "created at" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "kedaluwarsa pada" @@ -84,26 +84,26 @@ msgstr "Daftar Hitam Token" msgid "Cannot create token with no type or lifetime" msgstr "Tidak dapat membuat token tanpa tipe atau masa pakai" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Token tidak memiliki id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Token tidak memiliki tipe" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Jenis token salah" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Token tidak memiliki klaim '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Klaim token '{}' telah kedaluwarsa" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index ec5212282..18ecc95f9 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -15,48 +15,48 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "L'header di autorizzazione deve contenere due valori delimitati da uno spazio" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Il token dato non è valido per qualsiasi tipo di token" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "Il token non conteneva nessuna informazione riconoscibile dell'utente" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Utente non trovato" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Utente non attivo" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Algoritmo di tipo '{}' non riconosciuto" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "Devi avere installato cryptography per usare '{}'." -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "L'algoritmo specificato non è valido" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Nessun account attivo trovato con queste credenziali" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -64,19 +64,19 @@ msgstr "" "L'impostazione '{}' è stata rimossa. Per favore utilizza '{}' per " "visualizzare le impostazioni valide." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "utente" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "creato il" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "scade il" @@ -88,26 +88,26 @@ msgstr "Blacklist dei token" msgid "Cannot create token with no type or lifetime" msgstr "Impossibile creare un token senza tipo o durata" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Il token non ha un id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Il token non ha un tipo" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Il token ha un tipo sbagliato" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Il token non contiene il parametro '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Il parametro '{}' del token è scaduto" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index 2ea681584..230d00b38 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -32,27 +32,27 @@ msgstr "찾을 수 없는 사용자" msgid "User is inactive" msgstr "비활성화된 사용자" -#: backends.py:51 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "알 수 없는 알고리즘 유형 '{}'" -#: backends.py:57 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "{}를 사용하려면 암호화가 설치되어 있어야 합니다." -#: backends.py:109 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "잘못된 알고리즘이 지정되었습니다" -#: backends.py:111 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "유효하지 않거나 만료된 토큰" -#: serializers.py:29 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: settings.py:62 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index 856e1f97f..404077417 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -11,67 +11,67 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "Authorisatie header moet twee waarden bevatten, gescheiden door een spatie" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Het token is voor geen enkel token-type geldig" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "Token bevat geen herkenbare gebruikersidentificatie" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Gebruiker niet gevonden" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Gebruiker is inactief" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Niet herkend algoritme type '{}" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token is niet geldig of verlopen" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Geen actief account gevonden voor deze gegevens" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "" "De '{}' instelling bestaat niet meer. Zie '{}' for beschikbareinstellingen." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "gebruiker" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "aangemaakt op" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "verloopt op" @@ -83,26 +83,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Kan geen token maken zonder type of levensduur" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Token heeft geen id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Token heeft geen type" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Token heeft het verkeerde type" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Token heeft geen '{}' recht" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Token '{}' recht is verlopen" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index 425320a6f..ab85a4c7e 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -11,66 +11,66 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "Nagłówek autoryzacji musi zawierać dwie wartości rodzielone spacjami" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Podany token jest błędny dla każdego typu tokena" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "Token nie zawierał rozpoznawalnej identyfikacji użytkownika" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Użytkownik nie znaleziony" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Użytkownik jest nieaktywny" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Nierozpoznany typ algorytmu '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token jest niepoprawny lub wygasł" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "" "Ustawienie '{}' zostało usunięte. Dostępne ustawienia znajdują sie w '{}'" -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "użytkownik" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "stworzony w" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "wygasa o" @@ -82,26 +82,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Nie można utworzyć tokena bez podanego typu lub żywotności" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Token nie posiada numeru identyfikacyjnego" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Token nie posiada typu" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Token posiada zły typ" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Token nie posiada upoważnienia '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Upoważnienie tokena '{}' wygasło" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index e36cecfc2..0cae6abc2 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -12,48 +12,48 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "Cabeçalho de autorização deve conter dois valores delimitados por espaço" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "O token informado não é válido para qualquer tipo de token" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "O token não continha nenhuma identificação reconhecível do usuário" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Usuário não encontrado" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Usuário está inativo" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo '{}' não reconhecido" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "Você deve ter criptografia instalada para usar {}." -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "Algoritmo inválido especificado" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "O token é inválido ou expirado" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -61,19 +61,19 @@ msgstr "" "A configuração '{}' foi removida. Por favor, consulte '{}' para disponível " "definições." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "usuário" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "criado em" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "expira em" @@ -85,26 +85,26 @@ msgstr "Lista negra de Tokens" msgid "Cannot create token with no type or lifetime" msgstr "Não é possível criar token sem tipo ou tempo de vida" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "Token não tem id" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Token não tem nenhum tipo" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Token tem tipo errado" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Token não tem '{}' privilégio" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "O privilégio '{}' do token expirou" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index afafee8b6..7c6801bcb 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -16,48 +16,48 @@ msgstr "" "%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" "X-Generator: Poedit 2.2.1\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "" "Заголовок авторизации должен содержать два значения, разделенных пробелом" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Данный токен недействителен для любого типа токена" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "Токен не содержит идентификатор пользователя" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Пользователь не найден" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Пользователь неактивен" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Нераспознанный тип алгоритма '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Токен недействителен или просрочен" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Не найдено активной учетной записи с указанными данными" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -65,19 +65,19 @@ msgstr "" "Параметр '{}' был удален. Пожалуйста, обратитесь к '{}' для просмотра " "доступных настроек." -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "пользователь" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "создан" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "истекает" @@ -89,26 +89,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Невозможно создать токен без типа или времени жизни" -#: tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "У токена нет идентификатора" -#: tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "Токен не имеет типа" -#: tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "Токен имеет неправильный тип" -#: tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "Токен не содержит '{}'" -#: tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Токен имеет просроченное значение '{}'" -#: tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index ba7060c7d..4496ee4bd 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -14,7 +14,9 @@ msgstr "" #: authentication.py:78 msgid "Authorization header must contain two space-delimited values" -msgstr "Yetkilendirme header'i boşlukla sınırlandırılmış iki değer bulundurmak zorunda" +msgstr "" +"Yetkilendirme header'i boşlukla sınırlandırılmış iki değer bulundurmak " +"zorunda" #: authentication.py:104 msgid "Given token not valid for any token type" @@ -32,27 +34,27 @@ msgstr "Kullanıcı bulunamadı" msgid "User is inactive" msgstr "Kullanıcı etkin değil" -#: backends.py:47 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Tanınmayan algortima tipi '{}'" -#: backends.py:53 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "{} kullanmak için cryptography yüklemeniz gerekiyor." -#: backends.py:105 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "Geçersiz algoritma belirtildi" -#: backends.py:107 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token geçersiz veya süresi geçmiş" -#: serializers.py:29 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: settings.py:62 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index 13bdf0192..cd5d4392e 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -15,99 +15,96 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: rest_framework_simplejwt/authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "Авторизаційний заголовок має містити два значення розділені пробілом" -#: rest_framework_simplejwt/authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "Наданий токен не відповідає жодному типу ключа" -#: rest_framework_simplejwt/authentication.py:111 -#: rest_framework_simplejwt/authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "Наданий токен не мітить жодної ідентифікаційної інформації" -#: rest_framework_simplejwt/authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "Користувач не знайдений" -#: rest_framework_simplejwt/authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "Користувач неактивний" -#: rest_framework_simplejwt/backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "Тип алгоритму '{}' не розпізнаний" -#: rest_framework_simplejwt/backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "Встановіть модуль cryptography щоб використовувати {}" -#: rest_framework_simplejwt/backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "Вказаний невірний алгоритм" -#: rest_framework_simplejwt/backends.py:76 -#: rest_framework_simplejwt/exceptions.py:38 -#: rest_framework_simplejwt/tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Токен некоректний або термін його дії вичерпаний" -#: rest_framework_simplejwt/serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: rest_framework_simplejwt/settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "Налаштування '{}' видалене. Подивіться у '{}' для інших доступних" -#: rest_framework_simplejwt/token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: rest_framework_simplejwt/token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "користувач" -#: rest_framework_simplejwt/token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "створений о" -#: rest_framework_simplejwt/token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "дійстний по" -#: rest_framework_simplejwt/token_blacklist/apps.py:7 +#: token_blacklist/apps.py:7 msgid "Token Blacklist" msgstr "Чорний список токенів" -#: rest_framework_simplejwt/tokens.py:30 +#: tokens.py:30 msgid "Cannot create token with no type or lifetime" msgstr "Неможливо створити токен без типу або строку дії" -#: rest_framework_simplejwt/tokens.py:98 +#: tokens.py:97 msgid "Token has no id" msgstr "У ключі доступу не міститься id" -#: rest_framework_simplejwt/tokens.py:109 +#: tokens.py:108 msgid "Token has no type" msgstr "У ключі доступу не міститься тип" -#: rest_framework_simplejwt/tokens.py:112 +#: tokens.py:111 msgid "Token has wrong type" msgstr "токен позначений невірним типом" -#: rest_framework_simplejwt/tokens.py:149 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "У токені не міститься '{}' заголовку" -#: rest_framework_simplejwt/tokens.py:153 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "Заголовок '{}' токена не дійсний" -#: rest_framework_simplejwt/tokens.py:192 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index 3ba45f0f3..f435a7769 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -2,7 +2,6 @@ # Copyright (C) 2021 # This file is distributed under the same license as the Simple JWT package. # zengqiu , 2021. - msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" @@ -16,67 +15,65 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:79 +#: authentication.py:78 msgid "Authorization header must contain two space-delimited values" msgstr "授权头必须包含两个用空格分隔的值" -#: authentication.py:100 +#: authentication.py:104 msgid "Given token not valid for any token type" msgstr "此令牌对任何类型的令牌无效" -#: authentication.py:111 authentication.py:133 +#: authentication.py:116 authentication.py:138 msgid "Token contained no recognizable user identification" msgstr "令牌未包含用户标识符" -#: authentication.py:116 +#: authentication.py:121 msgid "User not found" msgstr "未找到该用户" -#: authentication.py:119 +#: authentication.py:124 msgid "User is inactive" msgstr "该用户已禁用" -#: backends.py:37 +#: backends.py:50 msgid "Unrecognized algorithm type '{}'" msgstr "未知算法类型 '{}'" -#: backends.py:40 +#: backends.py:56 msgid "You must have cryptography installed to use {}." msgstr "你必须安装 cryptography 才能使用 {}。" -#: backends.py:74 +#: backends.py:108 msgid "Invalid algorithm specified" msgstr "指定的算法无效" -#: backends.py:76 exceptions.py:38 tokens.py:44 +#: backends.py:110 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "令牌无效或已过期" -#: serializers.py:24 +#: serializers.py:30 msgid "No active account found with the given credentials" msgstr "找不到指定凭据对应的有效用户" -#: settings.py:63 +#: settings.py:68 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." -msgstr "" -"'{}' 配置已被移除。 请参阅 '{}' 获取可用的" -"配置。" +msgstr "'{}' 配置已被移除。 请参阅 '{}' 获取可用的配置。" -#: token_blacklist/admin.py:72 +#: token_blacklist/admin.py:68 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:77 +#: token_blacklist/admin.py:74 msgid "user" msgstr "用户" -#: token_blacklist/admin.py:82 +#: token_blacklist/admin.py:80 msgid "created at" msgstr "创建时间" -#: token_blacklist/admin.py:87 +#: token_blacklist/admin.py:86 msgid "expires at" msgstr "过期时间" @@ -88,26 +85,26 @@ msgstr "令牌黑名单" msgid "Cannot create token with no type or lifetime" msgstr "无法创建没有类型或生存期的令牌" -#: tokens.py:96 +#: tokens.py:97 msgid "Token has no id" msgstr "令牌没有标识符" -#: tokens.py:107 +#: tokens.py:108 msgid "Token has no type" msgstr "令牌没有类型" -#: tokens.py:110 +#: tokens.py:111 msgid "Token has wrong type" msgstr "令牌类型错误" -#: tokens.py:147 +#: tokens.py:163 msgid "Token has no '{}' claim" msgstr "令牌没有 '{}' 声明" -#: tokens.py:151 +#: tokens.py:167 msgid "Token '{}' claim has expired" msgstr "令牌 '{}' 声明已过期" -#: tokens.py:194 +#: tokens.py:217 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" From dc42547ebddaefb997380aaa7ee7708bd9a4435a Mon Sep 17 00:00:00 2001 From: Oscar Y Chen Date: Sat, 5 Feb 2022 22:08:27 -0700 Subject: [PATCH 010/171] Add default __getattr__ behavior to models.TokenUser (#528) * Add default __getattr__ behavior to models.TokenUser to allow getting custom claims defined in serializers * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/models.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rest_framework_simplejwt/models.py b/rest_framework_simplejwt/models.py index 391c1162a..959b7f597 100644 --- a/rest_framework_simplejwt/models.py +++ b/rest_framework_simplejwt/models.py @@ -103,3 +103,7 @@ def is_authenticated(self): def get_username(self): return self.username + + def __getattr__(self, attr): + """This acts as a backup attribute getter for custom claims defined in Token serializers.""" + return self.token.get(attr, None) From 5338fd67a4ba61c694df364cd8759a413b3c13cb Mon Sep 17 00:00:00 2001 From: vainu-arto <70135394+vainu-arto@users.noreply.github.com> Date: Tue, 8 Feb 2022 01:48:21 +0200 Subject: [PATCH 011/171] Allow overriding access token class (#529) --- rest_framework_simplejwt/tokens.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 28b49bda9..5ea78eecc 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -272,6 +272,11 @@ def __init__(self, *args, **kwargs): ) +class AccessToken(Token): + token_type = "access" + lifetime = api_settings.ACCESS_TOKEN_LIFETIME + + class RefreshToken(BlacklistMixin, Token): token_type = "refresh" lifetime = api_settings.REFRESH_TOKEN_LIFETIME @@ -285,6 +290,7 @@ class RefreshToken(BlacklistMixin, Token): api_settings.JTI_CLAIM, "jti", ) + access_token_class = AccessToken @property def access_token(self): @@ -293,7 +299,7 @@ def access_token(self): claims present in this refresh token to the new access token except those claims listed in the `no_copy_claims` attribute. """ - access = AccessToken() + access = self.access_token_class() # Use instantiation time of refresh token as relative timestamp for # access token "exp" claim. This ensures that both a refresh and @@ -310,11 +316,6 @@ def access_token(self): return access -class AccessToken(Token): - token_type = "access" - lifetime = api_settings.ACCESS_TOKEN_LIFETIME - - class UntypedToken(Token): token_type = "untyped" lifetime = timedelta(seconds=0) From 1f3e73d103d8b41e81aa4eccba1844312fa09345 Mon Sep 17 00:00:00 2001 From: vainu-arto <70135394+vainu-arto@users.noreply.github.com> Date: Tue, 8 Feb 2022 15:37:01 +0200 Subject: [PATCH 012/171] Maintain compatibility with serializer_class overrides (#530) --- rest_framework_simplejwt/views.py | 8 +++++++- tests/test_views.py | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/views.py b/rest_framework_simplejwt/views.py index f523469ac..fd5c66610 100644 --- a/rest_framework_simplejwt/views.py +++ b/rest_framework_simplejwt/views.py @@ -13,11 +13,17 @@ class TokenViewBase(generics.GenericAPIView): authentication_classes = () serializer_class = None + _serializer_class = "" www_authenticate_realm = "api" def get_serializer_class(self): - # Get the serializer from settings + """ + If serializer_class is set, use it directly. Otherwise get the class from settings. + """ + + if self.serializer_class: + return self.serializer_class try: return import_string(self._serializer_class) except ImportError: diff --git a/tests/test_views.py b/tests/test_views.py index 34bae1d3a..8a9e16f26 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -4,6 +4,7 @@ from django.contrib.auth import get_user_model from django.utils import timezone +from rest_framework.test import APIRequestFactory from rest_framework_simplejwt import serializers from rest_framework_simplejwt.settings import api_settings @@ -13,6 +14,7 @@ datetime_from_epoch, datetime_to_epoch, ) +from rest_framework_simplejwt.views import TokenViewBase from .utils import APIViewTestCase, override_api_settings @@ -431,3 +433,15 @@ def test_it_should_return_401_if_token_is_blacklisted(self): del self.view_name self.assertEqual(res.status_code, 401) + + +class TestCustomTokenView(APIViewTestCase): + def test_custom_view_class(self): + class CustomTokenView(TokenViewBase): + serializer_class = serializers.TokenObtainPairSerializer + + factory = APIRequestFactory() + view = CustomTokenView.as_view() + request = factory.post("/", {}, format="json") + res = view(request) + self.assertEqual(res.status_code, 400) From 1ea72de4e276afbb61b2cd83b32d352c8ca6fb8d Mon Sep 17 00:00:00 2001 From: totycro Date: Thu, 10 Feb 2022 22:32:50 +0100 Subject: [PATCH 013/171] Consider leeway when checking expiry (#458) --- rest_framework_simplejwt/tokens.py | 10 ++++++++-- tests/test_tokens.py | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 5ea78eecc..f0cfb846c 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -163,7 +163,8 @@ def check_exp(self, claim="exp", current_time=None): raise TokenError(format_lazy(_("Token has no '{}' claim"), claim)) claim_time = datetime_from_epoch(claim_value) - if claim_time <= current_time: + leeway = self.get_token_backend().leeway + if claim_time <= current_time - timedelta(seconds=leeway): raise TokenError(format_lazy(_("Token '{}' claim has expired"), claim)) @classmethod @@ -183,13 +184,18 @@ def for_user(cls, user): _token_backend = None - def get_token_backend(self): + @property + def token_backend(self): if self._token_backend is None: self._token_backend = import_string( "rest_framework_simplejwt.state.token_backend" ) return self._token_backend + def get_token_backend(self): + # Backward compatibility. + return self.token_backend + class BlacklistMixin: """ diff --git a/tests/test_tokens.py b/tests/test_tokens.py index 8e5670030..1472fdbb0 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -309,6 +309,20 @@ def test_check_exp(self): "refresh_exp", current_time=current_time + timedelta(days=2) ) + def test_check_token_not_expired_if_in_leeway(self): + token = MyToken() + token.set_exp("refresh_exp", lifetime=timedelta(days=1)) + + datetime_in_leeway = token.current_time + timedelta(days=1) + + with self.assertRaises(TokenError): + token.check_exp("refresh_exp", current_time=datetime_in_leeway) + + # a token 1 day expired is valid if leeway is 2 days + token.token_backend.leeway = timedelta(days=2).total_seconds() + token.check_exp("refresh_exp", current_time=datetime_in_leeway) + token.token_backend.leeway = 0 + def test_for_user(self): username = "test_user" user = User.objects.create_user( From 6587c2a1f2761f5e7cede25de5e722864fa47ce5 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Mon, 28 Feb 2022 13:21:50 -0500 Subject: [PATCH 014/171] Add locale checker to CI (#456) * Add locale checker to CI * Just pip install Django * Add gettext package to OS * Add sudo to apt-get * Use @2ykwang 's updated script * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Only update on push to master * To avoid pain points of PRs and histories being split * Trying to use Andrew's username for pushing to see if that works * Use separate workflow file Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .github/workflows/i18n.yml | 61 +++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 10 +++++- scripts/i18n_updater.py | 58 +++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/i18n.yml create mode 100644 scripts/i18n_updater.py diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml new file mode 100644 index 000000000..671de4807 --- /dev/null +++ b/.github/workflows/i18n.yml @@ -0,0 +1,61 @@ +name: Locale Updater + +on: + push: + branches: + - master + - main + +jobs: + locale-updater: + name: Locale updater + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + + - name: Set up Python 3.9 + uses: actions/setup-python@v2 + with: + python-version: '3.9' + + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: Cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: + 3.9-v1-${{ hashFiles('**/setup.py') }} + restore-keys: | + 3.9-v1- + + - name: Install dependencies + run: | + sudo apt-get install -y gettext + python -m pip install --upgrade pip wheel setuptools + pip install -e .[dev] + + - name: Run locale + working-directory: rest_framework_simplejwt + run: | + python ../scripts/i18n_updater.py + + - name: Commit locale changes + uses: stefanzweifel/git-auto-commit-action@v4 + id: auto-commit-action + with: + commit_message: "Update locale files" + file_pattern: rest_framework_simplejwt/locale/** + commit_user_name: Andrew-Chen-Wang + commit_user_email: acwangpython@gmail.com + commit_author: Andrew-Chen-Wang + + - name: Tell whether locale updated + if: steps.auto-commit-action.outputs.changes_detected == 'true' + run: echo "Locale files updated" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 152109f4b..caf375ffd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,12 +18,20 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.8 + python-version: 3.9 - name: Install dependencies run: | + sudo apt-get install -y gettext python -m pip install -U pip python -m pip install -U setuptools twine wheel + pip install -e .[dev] + + - name: Check locale + run: | + echo "Checking if locale files need updating. If they do, cd rest_framework_simplejwt && run python ../scripts/i18n_updater.py" + python ../scripts/i18n_updater.py + git diff --exit-code - name: Build package run: | diff --git a/scripts/i18n_updater.py b/scripts/i18n_updater.py new file mode 100644 index 000000000..bea42c762 --- /dev/null +++ b/scripts/i18n_updater.py @@ -0,0 +1,58 @@ +import contextlib +import os +import subprocess + + +def get_list_of_files(dir_name: str, extension: str): + file_list = os.listdir(dir_name) + + result = [] + for entry in file_list: + full_path = os.path.join(dir_name, entry) + if os.path.isdir(full_path): + result = result + get_list_of_files(full_path, extension) + else: + if entry[-len(extension) : len(entry)] == extension: + result.append(full_path) + + return result + + +@contextlib.contextmanager +def cache_creation(): + # DO NOT cache the line number; the file may change + cache: dict[str, str] = {} + for file in get_list_of_files("./", ".po"): + if os.path.isdir(file): + continue + + with open(file) as f: + for line in f.readlines(): + if line.startswith('"POT-Creation-Date: '): + cache[file] = line + break + yield + for file, line_cache in cache.items(): + with open(file, "r+") as f: + lines = f.readlines() + # clear file + f.seek(0) + f.truncate() + + # find line + index = [ + lines.index(x) for x in lines if x.startswith('"POT-Creation-Date: ') + ][0] + + lines[index] = line_cache + f.writelines(lines) + + +def main(): + with cache_creation(): + subprocess.run(["django-admin", "makemessages", "-a"]) + subprocess.run(["django-admin", "compilemessages"]) + + +if __name__ == "__main__": + main() From d51841e90f072a2e57d34cbb0f22d91377c33c62 Mon Sep 17 00:00:00 2001 From: yeongkwang Date: Tue, 1 Mar 2022 03:23:28 +0900 Subject: [PATCH 015/171] Update CHANGELOG.md for v5.1.0 (#527) * Update CHANGELOG.md for v5.0.1 * Update CHANGELOG.md * Remove looking for maintainers in README since Jazzband Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- CHANGELOG.md | 23 +++++++++++++++++++++-- README.rst | 6 ------ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6877bcb96..c38d69200 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ ## Unreleased +## Version 5.1.0 + +* Add back support for PyJWT 1.7.1 ([#536](https://github.com/jazzband/djangorestframework-simplejwt/pull/536)) +* Make the token serializer configurable ([#521](https://github.com/jazzband/djangorestframework-simplejwt/pull/521)) +* Simplify using custom token classes in serializers ([#517](https://github.com/jazzband/djangorestframework-simplejwt/pull/517)) +* Fix default_app_config deprecation ([#415](https://github.com/jazzband/djangorestframework-simplejwt/pull/415)) +* Add missing integration instructions for drf-yasg ([#505](https://github.com/jazzband/djangorestframework-simplejwt/pull/505)) +* Add blacklist view to log out users ([#306](https://github.com/jazzband/djangorestframework-simplejwt/pull/306)) +* Set default verifying key to empty str ([#487](https://github.com/jazzband/djangorestframework-simplejwt/pull/487)) +* Add docs about TOKEN_USER_CLASS ([#455](https://github.com/jazzband/djangorestframework-simplejwt/pull/440)) + +Meta: +* Add auto locale updater ([#456](https://github.com/jazzband/djangorestframework-simplejwt/pull/456)) + +Translations: + +* Added Korean translations ([#501](https://github.com/jazzband/djangorestframework-simplejwt/pull/501)) +* Added Turkish translations ([#508](https://github.com/jazzband/djangorestframework-simplejwt/pull/508)) + ## Version 5.0.0 #### Breaking @@ -12,8 +31,7 @@ * Updated import list ([#459](https://github.com/jazzband/djangorestframework-simplejwt/pull/459)) * Repair generation of OpenAPI with Spectacular ([#452](https://github.com/jazzband/djangorestframework-simplejwt/pull/452)) * Add "iat" claim to token ([#192](https://github.com/jazzband/djangorestframework-simplejwt/pull/192)) -* Add blacklist view to log out users ([#306](https://github.com/jazzband/djangorestframework-simplejwt/pull/306)) -* updated import list in docs ([#459](https://github.com/jazzband/djangorestframework-simplejwt/pull/459)) +* Add blacklist view to log out users ([#306](https://github.com/jazzband/djangorestframework-simplejwt/pull/306)) ## Version 4.8.0 @@ -36,6 +54,7 @@ * Fix invalid syntax in docs for `INSTALLED_APPS` ([#416](https://github.com/jazzband/django-rest-framework-simplejwt/pull/416)) Translations: + * Added Dutch translations ([#422](https://github.com/jazzband/django-rest-framework-simplejwt/pull/422)) * Added Ukrainian translations ([#423](https://github.com/jazzband/django-rest-framework-simplejwt/pull/423)) * Added Simplified Chinese translations ([#427](https://github.com/jazzband/django-rest-framework-simplejwt/pull/427)) diff --git a/README.rst b/README.rst index 0dd78628b..4df9d74c7 100644 --- a/README.rst +++ b/README.rst @@ -26,9 +26,3 @@ Framework `__. For full documentation, visit `django-rest-framework-simplejwt.readthedocs.io `__. - -Looking for Maintainers ------------------------ - -For more information, see `here -`__. From 483d9b88e182a051b1e2c014478328a408517eeb Mon Sep 17 00:00:00 2001 From: yeongkwang Date: Tue, 1 Mar 2022 03:45:56 +0900 Subject: [PATCH 016/171] Fix i18n CI (#538) --- .github/workflows/i18n.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index 671de4807..ddadbd2e3 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -54,7 +54,7 @@ jobs: file_pattern: rest_framework_simplejwt/locale/** commit_user_name: Andrew-Chen-Wang commit_user_email: acwangpython@gmail.com - commit_author: Andrew-Chen-Wang + commit_author: Andrew-Chen-Wang - name: Tell whether locale updated if: steps.auto-commit-action.outputs.changes_detected == 'true' From fdc79239f2906fcc086d738201a541ba580b74ec Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Mon, 28 Feb 2022 15:41:48 -0500 Subject: [PATCH 017/171] Open PR on i18n (#539) --- .github/workflows/i18n.yml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index ddadbd2e3..02bcb6c6d 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -46,16 +46,15 @@ jobs: run: | python ../scripts/i18n_updater.py - - name: Commit locale changes - uses: stefanzweifel/git-auto-commit-action@v4 + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 id: auto-commit-action with: + branch: i18n-auto-update + title: "[i18n] Update" + body: "Updated locale files on master branch" commit_message: "Update locale files" - file_pattern: rest_framework_simplejwt/locale/** - commit_user_name: Andrew-Chen-Wang - commit_user_email: acwangpython@gmail.com - commit_author: Andrew-Chen-Wang + add-paths: rest_framework_simplejwt/locale/** - name: Tell whether locale updated - if: steps.auto-commit-action.outputs.changes_detected == 'true' - run: echo "Locale files updated" + run: echo "Locale updated at ${steps.auto-commit-aciton.outputs.pull-request-url}" From 09d659968c873eae7fc3c5ddaa1e91241fa9d0a8 Mon Sep 17 00:00:00 2001 From: yeongkwang Date: Tue, 1 Mar 2022 06:27:06 +0900 Subject: [PATCH 018/171] fix small typo (#540) --- .github/workflows/i18n.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index 02bcb6c6d..376807f54 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -53,8 +53,8 @@ jobs: branch: i18n-auto-update title: "[i18n] Update" body: "Updated locale files on master branch" - commit_message: "Update locale files" + commit-message: "Update locale files" add-paths: rest_framework_simplejwt/locale/** - name: Tell whether locale updated - run: echo "Locale updated at ${steps.auto-commit-aciton.outputs.pull-request-url}" + run: echo "Locale files updated" From 304819ccf0300a41302a92e19864afaa77e476a1 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Tue, 1 Mar 2022 08:55:47 -0500 Subject: [PATCH 019/171] Setup initial PyJWT 1.7.1 support (#536) --- rest_framework_simplejwt/backends.py | 14 ++++++-- setup.py | 2 +- tests/test_backends.py | 48 ++++++++++++++++++++++------ tox.ini | 9 +++--- 4 files changed, 56 insertions(+), 17 deletions(-) diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index 49282b486..6bc2fafb0 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -1,10 +1,17 @@ import jwt from django.utils.translation import gettext_lazy as _ -from jwt import InvalidAlgorithmError, InvalidTokenError, PyJWKClient, algorithms +from jwt import InvalidAlgorithmError, InvalidTokenError, algorithms from .exceptions import TokenBackendError from .utils import format_lazy +try: + from jwt import PyJWKClient + + JWK_CLIENT_AVAILABLE = True +except ImportError: + JWK_CLIENT_AVAILABLE = False + ALLOWED_ALGORITHMS = { "HS256", "HS384", @@ -37,7 +44,10 @@ def __init__( self.audience = audience self.issuer = issuer - self.jwks_client = PyJWKClient(jwk_url) if jwk_url else None + if JWK_CLIENT_AVAILABLE: + self.jwks_client = PyJWKClient(jwk_url) if jwk_url else None + else: + self.jwks_client = None self.leeway = leeway def _validate_algorithm(self, algorithm): diff --git a/setup.py b/setup.py index 286921f00..5687b6604 100755 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ install_requires=[ "django", "djangorestframework", - "pyjwt>=2,<3", + "pyjwt>=1.7.1,<3", ], python_requires=">=3.7", extras_require=extras_require, diff --git a/tests/test_backends.py b/tests/test_backends.py index 94a56829e..14bb6b9ad 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -3,10 +3,13 @@ from unittest.mock import patch import jwt +import pytest from django.test import TestCase -from jwt import PyJWS, algorithms +from jwt import PyJWS +from jwt import __version__ as jwt_version +from jwt import algorithms -from rest_framework_simplejwt.backends import TokenBackend +from rest_framework_simplejwt.backends import JWK_CLIENT_AVAILABLE, TokenBackend from rest_framework_simplejwt.exceptions import TokenBackendError from rest_framework_simplejwt.utils import aware_utcnow, datetime_to_epoch, make_utc from tests.keys import ( @@ -28,6 +31,8 @@ LEEWAY = 100 +IS_OLD_JWT = jwt_version == "1.7.1" + class TestTokenBackend(TestCase): def setUp(self): @@ -159,7 +164,7 @@ def test_decode_with_expiry(self): def test_decode_with_invalid_sig(self): self.payload["exp"] = aware_utcnow() - timedelta(seconds=1) for backend in self.backends: - with self.subTest("Test decode with invalid sig for f{backend.algorithm}"): + with self.subTest(f"Test decode with invalid sig for {backend.algorithm}"): payload = self.payload.copy() payload["exp"] = aware_utcnow() + timedelta(days=1) token_1 = jwt.encode( @@ -170,6 +175,10 @@ def test_decode_with_invalid_sig(self): payload, backend.signing_key, algorithm=backend.algorithm ) + if IS_OLD_JWT: + token_1 = token_1.decode("utf-8") + token_2 = token_2.decode("utf-8") + token_2_payload = token_2.rsplit(".", 1)[0] token_1_sig = token_1.rsplit(".", 1)[-1] invalid_token = token_2_payload + "." + token_1_sig @@ -189,8 +198,12 @@ def test_decode_with_invalid_sig_no_verify(self): token_2 = jwt.encode( payload, backend.signing_key, algorithm=backend.algorithm ) - # Payload copied - payload["exp"] = datetime_to_epoch(payload["exp"]) + if IS_OLD_JWT: + token_1 = token_1.decode("utf-8") + token_2 = token_2.decode("utf-8") + else: + # Payload copied + payload["exp"] = datetime_to_epoch(payload["exp"]) token_2_payload = token_2.rsplit(".", 1)[0] token_1_sig = token_1.rsplit(".", 1)[-1] @@ -210,9 +223,13 @@ def test_decode_success(self): token = jwt.encode( self.payload, backend.signing_key, algorithm=backend.algorithm ) - # Payload copied - payload = self.payload.copy() - payload["exp"] = datetime_to_epoch(self.payload["exp"]) + if IS_OLD_JWT: + token = token.decode("utf-8") + payload = self.payload + else: + # Payload copied + payload = self.payload.copy() + payload["exp"] = datetime_to_epoch(self.payload["exp"]) self.assertEqual(backend.decode(token), payload) @@ -223,11 +240,18 @@ def test_decode_aud_iss_success(self): self.payload["iss"] = ISSUER token = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") - # Payload copied - self.payload["exp"] = datetime_to_epoch(self.payload["exp"]) + if IS_OLD_JWT: + token = token.decode("utf-8") + else: + # Payload copied + self.payload["exp"] = datetime_to_epoch(self.payload["exp"]) self.assertEqual(self.aud_iss_token_backend.decode(token), self.payload) + @pytest.mark.skipif( + not JWK_CLIENT_AVAILABLE, + reason="PyJWT 1.7.1 doesn't have JWK client", + ) def test_decode_rsa_aud_iss_jwk_success(self): self.payload["exp"] = aware_utcnow() + timedelta(days=1) self.payload["foo"] = "baz" @@ -261,6 +285,8 @@ def test_decode_rsa_aud_iss_jwk_success(self): def test_decode_when_algorithm_not_available(self): token = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") + if IS_OLD_JWT: + token = token.decode("utf-8") pyjwt_without_rsa = PyJWS() pyjwt_without_rsa.unregister_algorithm("RS256") @@ -276,6 +302,8 @@ def _decode(jwt, key, algorithms, options, audience, issuer, leeway): def test_decode_when_token_algorithm_does_not_match(self): token = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") + if IS_OLD_JWT: + token = token.decode("utf-8") with self.assertRaisesRegex(TokenBackendError, "Invalid algorithm specified"): self.hmac_token_backend.decode(token) diff --git a/tox.ini b/tox.ini index bcd2cd76c..757a9c84b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] envlist= - py{37,38,39}-dj22-drf310-tests - py{37,38,39,310}-dj{22,32}-drf{311,312,313}-tests - py{38,39,310}-dj{40,main}-drf313-tests + py{37,38,39}-dj22-drf310-pyjwt{171,2}-tests + py{37,38,39,310}-dj{22,32}-drf{311,312,313}-pyjwt{171,2}-tests + py{38,39,310}-dj{40,main}-drf313-pyjwt{171,2}-tests docs [gh-actions] @@ -25,7 +25,6 @@ DRF= 3.13: drf313 [testenv] -usedevelop=True commands = pytest {posargs:tests} --cov-append --cov-report=xml --cov=rest_framework_simplejwt extras= test @@ -40,6 +39,8 @@ deps= drf311: djangorestframework>=3.11,<3.12 drf312: djangorestframework>=3.12,<3.13 drf313: djangorestframework>=3.13,<3.14 + pyjwt171: pyjwt>=1.7.1,<1.8 + pyjwt2: pyjwt>=2,<3 djmain: https://github.com/django/django/archive/main.tar.gz allowlist_externals=make From 06a55ce5f8571151e5d9e3f757d8e55ee45c288d Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Tue, 1 Mar 2022 15:24:33 -0500 Subject: [PATCH 020/171] Fix release locale checker (#541) --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index caf375ffd..53f056262 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,6 +28,7 @@ jobs: pip install -e .[dev] - name: Check locale + working-directory: rest_framework_simplejwt run: | echo "Checking if locale files need updating. If they do, cd rest_framework_simplejwt && run python ../scripts/i18n_updater.py" python ../scripts/i18n_updater.py From 72000af935da559e6d7a82ce634c454426ee4730 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Tue, 1 Mar 2022 15:37:17 -0500 Subject: [PATCH 021/171] Update locale files (#542) --- .../locale/cs/LC_MESSAGES/django.po | 12 ++++++------ .../locale/de_CH/LC_MESSAGES/django.po | 12 ++++++------ .../locale/es/LC_MESSAGES/django.po | 12 ++++++------ .../locale/es_AR/LC_MESSAGES/django.po | 12 ++++++------ .../locale/es_CL/LC_MESSAGES/django.po | 12 ++++++------ .../locale/fa_IR/LC_MESSAGES/django.po | 12 ++++++------ .../locale/fr/LC_MESSAGES/django.po | 12 ++++++------ .../locale/id_ID/LC_MESSAGES/django.po | 12 ++++++------ .../locale/it_IT/LC_MESSAGES/django.po | 12 ++++++------ .../locale/ko_KR/LC_MESSAGES/django.po | 12 ++++++------ .../locale/nl_NL/LC_MESSAGES/django.po | 12 ++++++------ .../locale/pl_PL/LC_MESSAGES/django.po | 12 ++++++------ .../locale/pt_BR/LC_MESSAGES/django.po | 12 ++++++------ .../locale/ru_RU/LC_MESSAGES/django.po | 12 ++++++------ .../locale/tr/LC_MESSAGES/django.po | 12 ++++++------ .../locale/uk_UA/LC_MESSAGES/django.po | 12 ++++++------ .../locale/zh_Hans/LC_MESSAGES/django.po | 12 ++++++------ 17 files changed, 102 insertions(+), 102 deletions(-) diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index 022575397..3b7a31a27 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -31,19 +31,19 @@ msgstr "Uživatel nenalezen" msgid "User is inactive" msgstr "Uživatel není aktivní" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Nerozpoznaný typ algoritmu '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" @@ -97,10 +97,10 @@ msgstr "Token má špatný typ" msgid "Token has no '{}' claim" msgstr "Token nemá žádnou hodnotu '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Hodnota tokenu '{}' vypršela" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po index 7970628af..66923f9f7 100644 --- a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po @@ -33,19 +33,19 @@ msgstr "Benutzer nicht gefunden" msgid "User is inactive" msgstr "Inaktiver Benutzer" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Unerkannter Algorithmustyp '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" @@ -101,10 +101,10 @@ msgstr "Token hat den falschen Typ" msgid "Token has no '{}' claim" msgstr "Token hat kein '{}' Recht" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Das Tokenrecht '{}' ist abgelaufen" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 694972af9..3df80e995 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -33,19 +33,19 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "Debe tener criptografía instalada para usar {}." -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "Algoritmo especificado no válido" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" @@ -101,10 +101,10 @@ msgstr "El token tiene un tipo incorrecto" msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index a5365b6c7..6c08f8641 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -38,19 +38,19 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" @@ -107,10 +107,10 @@ msgstr "El token tiene un tipo incorrecto" msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "El token está en la lista negra" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index 229c8ab21..af3bfd32d 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -33,19 +33,19 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token inválido o expirado" @@ -102,10 +102,10 @@ msgstr "Token tiene tipo erróneo" msgid "Token has no '{}' claim" msgstr "Token no tiene privilegio '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "El provilegio '{}' del token está expirado" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index 8a81f3b22..d18adb308 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -31,19 +31,19 @@ msgstr "کاربر یافت نشد" msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" @@ -97,10 +97,10 @@ msgstr "توکن نوع اشتباهی دارد" msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index 9f6dcbcfd..a37e09dae 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -33,19 +33,19 @@ msgstr "L'utilisateur n'a pas été trouvé" msgid "User is inactive" msgstr "L'utilisateur est désactivé" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Type d'algorithme non reconnu '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "Vous devez installer cryptography afin d'utiliser {}." -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "L'algorithme spécifié est invalide" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" @@ -101,10 +101,10 @@ msgstr "Le jeton a un type erroné" msgid "Token has no '{}' claim" msgstr "Le jeton n'a pas le privilège '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Le privilège '{}' du jeton a expiré" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index f0e338ede..249407108 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -32,19 +32,19 @@ msgstr "Pengguna tidak ditemukan" msgid "User is inactive" msgstr "Pengguna tidak aktif" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Jenis algoritma tidak dikenal '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "Anda harus memasang kriptografi untuk menggunakan {}." -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "Algoritma yang ditentukan tidak valid" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" @@ -100,10 +100,10 @@ msgstr "Jenis token salah" msgid "Token has no '{}' claim" msgstr "Token tidak memiliki klaim '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Klaim token '{}' telah kedaluwarsa" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index 18ecc95f9..daf576fa6 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -36,19 +36,19 @@ msgstr "Utente non trovato" msgid "User is inactive" msgstr "Utente non attivo" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Algoritmo di tipo '{}' non riconosciuto" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "Devi avere installato cryptography per usare '{}'." -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "L'algoritmo specificato non è valido" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" @@ -104,10 +104,10 @@ msgstr "Il token ha un tipo sbagliato" msgid "Token has no '{}' claim" msgstr "Il token non contiene il parametro '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Il parametro '{}' del token è scaduto" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index 230d00b38..0ed43825b 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -32,19 +32,19 @@ msgstr "찾을 수 없는 사용자" msgid "User is inactive" msgstr "비활성화된 사용자" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "알 수 없는 알고리즘 유형 '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "{}를 사용하려면 암호화가 설치되어 있어야 합니다." -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "잘못된 알고리즘이 지정되었습니다" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "유효하지 않거나 만료된 토큰" @@ -98,10 +98,10 @@ msgstr "잘못된 토큰 타입" msgid "Token has no '{}' claim" msgstr "토큰에 '{}' 클레임이 없음" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "토큰 '{}' 클레임이 만료되었습니다" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "블랙리스트에 추가된 토큰" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index 404077417..4098298be 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -32,19 +32,19 @@ msgstr "Gebruiker niet gevonden" msgid "User is inactive" msgstr "Gebruiker is inactief" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Niet herkend algoritme type '{}" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token is niet geldig of verlopen" @@ -99,10 +99,10 @@ msgstr "Token heeft het verkeerde type" msgid "Token has no '{}' claim" msgstr "Token heeft geen '{}' recht" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Token '{}' recht is verlopen" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index ab85a4c7e..c1939f3a1 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -31,19 +31,19 @@ msgstr "Użytkownik nie znaleziony" msgid "User is inactive" msgstr "Użytkownik jest nieaktywny" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Nierozpoznany typ algorytmu '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token jest niepoprawny lub wygasł" @@ -98,10 +98,10 @@ msgstr "Token posiada zły typ" msgid "Token has no '{}' claim" msgstr "Token nie posiada upoważnienia '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Upoważnienie tokena '{}' wygasło" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index 0cae6abc2..648a08055 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -33,19 +33,19 @@ msgstr "Usuário não encontrado" msgid "User is inactive" msgstr "Usuário está inativo" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo '{}' não reconhecido" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "Você deve ter criptografia instalada para usar {}." -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "Algoritmo inválido especificado" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "O token é inválido ou expirado" @@ -101,10 +101,10 @@ msgstr "Token tem tipo errado" msgid "Token has no '{}' claim" msgstr "Token não tem '{}' privilégio" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "O privilégio '{}' do token expirou" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index 7c6801bcb..74528ef32 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -37,19 +37,19 @@ msgstr "Пользователь не найден" msgid "User is inactive" msgstr "Пользователь неактивен" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Нераспознанный тип алгоритма '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Токен недействителен или просрочен" @@ -105,10 +105,10 @@ msgstr "Токен имеет неправильный тип" msgid "Token has no '{}' claim" msgstr "Токен не содержит '{}'" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Токен имеет просроченное значение '{}'" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 4496ee4bd..7597f42ee 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -34,19 +34,19 @@ msgstr "Kullanıcı bulunamadı" msgid "User is inactive" msgstr "Kullanıcı etkin değil" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Tanınmayan algortima tipi '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "{} kullanmak için cryptography yüklemeniz gerekiyor." -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "Geçersiz algoritma belirtildi" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token geçersiz veya süresi geçmiş" @@ -100,10 +100,10 @@ msgstr "Token'in tipi yanlış" msgid "Token has no '{}' claim" msgstr "Token'in '{}' claim'i yok" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Token'in '{}' claim'i sona erdi" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Token kara listeye alınmış" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index cd5d4392e..afb9aae7c 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -35,19 +35,19 @@ msgstr "Користувач не знайдений" msgid "User is inactive" msgstr "Користувач неактивний" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "Тип алгоритму '{}' не розпізнаний" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "Встановіть модуль cryptography щоб використовувати {}" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "Вказаний невірний алгоритм" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Токен некоректний або термін його дії вичерпаний" @@ -101,10 +101,10 @@ msgstr "токен позначений невірним типом" msgid "Token has no '{}' claim" msgstr "У токені не міститься '{}' заголовку" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "Заголовок '{}' токена не дійсний" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index f435a7769..7e8cda246 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -35,19 +35,19 @@ msgstr "未找到该用户" msgid "User is inactive" msgstr "该用户已禁用" -#: backends.py:50 +#: backends.py:60 msgid "Unrecognized algorithm type '{}'" msgstr "未知算法类型 '{}'" -#: backends.py:56 +#: backends.py:66 msgid "You must have cryptography installed to use {}." msgstr "你必须安装 cryptography 才能使用 {}。" -#: backends.py:108 +#: backends.py:118 msgid "Invalid algorithm specified" msgstr "指定的算法无效" -#: backends.py:110 exceptions.py:38 tokens.py:44 +#: backends.py:120 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "令牌无效或已过期" @@ -101,10 +101,10 @@ msgstr "令牌类型错误" msgid "Token has no '{}' claim" msgstr "令牌没有 '{}' 声明" -#: tokens.py:167 +#: tokens.py:168 msgid "Token '{}' claim has expired" msgstr "令牌 '{}' 声明已过期" -#: tokens.py:217 +#: tokens.py:223 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" From 80848c846a6a18a2aa6770f17831ce6e0bd5391f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 14 Mar 2022 15:30:17 -0400 Subject: [PATCH 022/171] [pre-commit.ci] pre-commit autoupdate (#545) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.31.0 → v2.31.1](https://github.com/asottile/pyupgrade/compare/v2.31.0...v2.31.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 861b9281a..73b4f04f6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.31.0' + rev: 'v2.31.1' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From 3fc9110c7d0e5641b6eccb6dca321f44189bba01 Mon Sep 17 00:00:00 2001 From: Byron Motoche <37427699+byrpatrick@users.noreply.github.com> Date: Fri, 18 Mar 2022 18:55:57 -0500 Subject: [PATCH 023/171] Remove the JWTTokenUserAuthentication from the Experimental Features #546 (#547) --- docs/index.rst | 2 +- docs/settings.rst | 2 +- ...eatures.rst => stateless_user_authentication.rst} | 12 ++++++------ rest_framework_simplejwt/authentication.py | 10 +++++++++- rest_framework_simplejwt/models.py | 4 ++-- tests/test_authentication.py | 4 ++-- 6 files changed, 21 insertions(+), 13 deletions(-) rename docs/{experimental_features.rst => stateless_user_authentication.rst} (67%) diff --git a/docs/index.rst b/docs/index.rst index 1aefc1a7e..fbf54629e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -51,7 +51,7 @@ Contents creating_tokens_manually token_types blacklist_app - experimental_features + stateless_user_authentication development_and_contributing drf_yasg_integration rest_framework_simplejwt diff --git a/docs/settings.rst b/docs/settings.rst index 1e065b0ab..3f89c21c9 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -239,7 +239,7 @@ store such a value. -------------------- A stateless user object which is backed by a validated token. Used only for -the experimental JWTTokenUserAuthentication authentication backend. The value +the JWTStatelessUserAuthentication authentication backend. The value is a dotted path to your subclass of ``rest_framework_simplejwt.models.TokenUser``, which also is the default. diff --git a/docs/experimental_features.rst b/docs/stateless_user_authentication.rst similarity index 67% rename from docs/experimental_features.rst rename to docs/stateless_user_authentication.rst index 13adca706..a0dfb7705 100644 --- a/docs/experimental_features.rst +++ b/docs/stateless_user_authentication.rst @@ -1,19 +1,19 @@ -.. _experimental_features: +.. _stateless_user_authentication: -Experimental features +Stateless User Authentication ===================== -JWTTokenUserAuthentication backend +JWTStatelessUserAuthentication backend ---------------------------------- -The ``JWTTokenUserAuthentication`` backend's ``authenticate`` method does not +The ``JWTStatelessUserAuthentication`` backend's ``authenticate`` method does not perform a database lookup to obtain a user instance. Instead, it returns a ``rest_framework_simplejwt.models.TokenUser`` instance which acts as a stateless user object backed only by a validated token instead of a record in a database. This can facilitate developing single sign-on functionality between separately hosted Django apps which all share the same token secret key. To use this feature, add the -``rest_framework_simplejwt.authentication.JWTTokenUserAuthentication`` backend +``rest_framework_simplejwt.authentication.JWTStatelessUserAuthentication`` backend (instead of the default ``JWTAuthentication`` backend) to the Django REST Framework's ``DEFAULT_AUTHENTICATION_CLASSES`` config setting: @@ -23,7 +23,7 @@ Framework's ``DEFAULT_AUTHENTICATION_CLASSES`` config setting: ... 'DEFAULT_AUTHENTICATION_CLASSES': ( ... - 'rest_framework_simplejwt.authentication.JWTTokenUserAuthentication', + 'rest_framework_simplejwt.authentication.JWTStatelessUserAuthentication', ) ... } diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index f7ad03537..15767cddd 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -126,7 +126,12 @@ def get_user(self, validated_token): return user -class JWTTokenUserAuthentication(JWTAuthentication): +class JWTStatelessUserAuthentication(JWTAuthentication): + """ + An authentication plugin that authenticates requests through a JSON web + token provided in a request header without performing a database lookup to obtain a user instance. + """ + def get_user(self, validated_token): """ Returns a stateless user object which is backed by the given validated @@ -140,6 +145,9 @@ def get_user(self, validated_token): return api_settings.TOKEN_USER_CLASS(validated_token) +JWTTokenUserAuthentication = JWTStatelessUserAuthentication + + def default_user_authentication_rule(user): # Prior to Django 1.10, inactive users could be authenticated with the # default `ModelBackend`. As of Django 1.10, the `ModelBackend` diff --git a/rest_framework_simplejwt/models.py b/rest_framework_simplejwt/models.py index 959b7f597..234de73e3 100644 --- a/rest_framework_simplejwt/models.py +++ b/rest_framework_simplejwt/models.py @@ -9,9 +9,9 @@ class TokenUser: """ A dummy user class modeled after django.contrib.auth.models.AnonymousUser. - Used in conjunction with the `JWTTokenUserAuthentication` backend to + Used in conjunction with the `JWTStatelessUserAuthentication` backend to implement single sign-on functionality across services which share the same - secret key. `JWTTokenUserAuthentication` will return an instance of this + secret key. `JWTStatelessUserAuthentication` will return an instance of this class instead of a `User` model instance. Instances of this class act as stateless user objects which are backed by validated tokens. """ diff --git a/tests/test_authentication.py b/tests/test_authentication.py index a8f4ff4b8..917f3993d 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -157,9 +157,9 @@ def test_get_user(self): self.assertEqual(self.backend.get_user(payload).id, u.id) -class TestJWTTokenUserAuthentication(TestCase): +class TestJWTStatelessUserAuthentication(TestCase): def setUp(self): - self.backend = authentication.JWTTokenUserAuthentication() + self.backend = authentication.JWTStatelessUserAuthentication() def test_get_user(self): payload = {"some_other_id": "foo"} From ddd05cab9bd77980b9d098e58ebaed23bdfd9a0a Mon Sep 17 00:00:00 2001 From: yeongkwang Date: Sun, 10 Apr 2022 12:27:30 +0900 Subject: [PATCH 024/171] Change from git protocol to https protocol (#555) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 73b4f04f6..2f8f596e9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -53,7 +53,7 @@ repos: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] -- repo: git://github.com/Lucas-C/pre-commit-hooks-markup +- repo: https://github.com/Lucas-C/pre-commit-hooks-markup rev: v1.0.1 hooks: - id: rst-linter From 4f223fefe074a44ee751aadec40d484c37d7f7f4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 10 Apr 2022 12:31:16 +0900 Subject: [PATCH 025/171] [pre-commit.ci] pre-commit autoupdate (#551) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 22.1.0 → 22.3.0](https://github.com/psf/black/compare/22.1.0...22.3.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2f8f596e9..30f8b835f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '22.1.0' + rev: '22.3.0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ From 28f5087b4639133bea4c1428d4d7c640a290c923 Mon Sep 17 00:00:00 2001 From: yeongkwang Date: Sun, 10 Apr 2022 15:28:37 +0900 Subject: [PATCH 026/171] Fix leeway type error (#554) * Fix lewway type error * Add test case * Update Korean translation * Add type hints * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix translation revert POT-Creation-Date * update translation Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/backends.py | 25 ++++++++++++++++-- .../locale/cs/LC_MESSAGES/django.po | 15 +++++++---- .../locale/de_CH/LC_MESSAGES/django.po | 15 +++++++---- .../locale/es/LC_MESSAGES/django.po | 15 +++++++---- .../locale/es_AR/LC_MESSAGES/django.po | 15 +++++++---- .../locale/es_CL/LC_MESSAGES/django.po | 15 +++++++---- .../locale/fa_IR/LC_MESSAGES/django.po | 15 +++++++---- .../locale/fr/LC_MESSAGES/django.po | 15 +++++++---- .../locale/id_ID/LC_MESSAGES/django.po | 15 +++++++---- .../locale/it_IT/LC_MESSAGES/django.po | 15 +++++++---- .../locale/ko_KR/LC_MESSAGES/django.mo | Bin 2521 -> 2720 bytes .../locale/ko_KR/LC_MESSAGES/django.po | 17 ++++++++---- .../locale/nl_NL/LC_MESSAGES/django.po | 15 +++++++---- .../locale/pl_PL/LC_MESSAGES/django.po | 15 +++++++---- .../locale/pt_BR/LC_MESSAGES/django.po | 15 +++++++---- .../locale/ru_RU/LC_MESSAGES/django.po | 15 +++++++---- .../locale/tr/LC_MESSAGES/django.po | 15 +++++++---- .../locale/uk_UA/LC_MESSAGES/django.po | 15 +++++++---- .../locale/zh_Hans/LC_MESSAGES/django.po | 15 +++++++---- rest_framework_simplejwt/tokens.py | 4 +-- tests/test_tokens.py | 23 +++++++++++++++- 21 files changed, 219 insertions(+), 90 deletions(-) diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index 6bc2fafb0..2fda76c44 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -1,3 +1,6 @@ +from datetime import timedelta +from typing import Union + import jwt from django.utils.translation import gettext_lazy as _ from jwt import InvalidAlgorithmError, InvalidTokenError, algorithms @@ -34,7 +37,7 @@ def __init__( audience=None, issuer=None, jwk_url: str = None, - leeway=0, + leeway: Union[float, int, timedelta] = None, ): self._validate_algorithm(algorithm) @@ -48,6 +51,7 @@ def __init__( self.jwks_client = PyJWKClient(jwk_url) if jwk_url else None else: self.jwks_client = None + self.leeway = leeway def _validate_algorithm(self, algorithm): @@ -67,6 +71,23 @@ def _validate_algorithm(self, algorithm): ) ) + def get_leeway(self) -> timedelta: + if self.leeway is None: + return timedelta(seconds=0) + elif isinstance(self.leeway, (int, float)): + return timedelta(seconds=self.leeway) + elif isinstance(self.leeway, timedelta): + return self.leeway + else: + raise TokenBackendError( + format_lazy( + _( + "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." + ), + type(self.leeway), + ) + ) + def get_verifying_key(self, token): if self.algorithm.startswith("HS"): return self.signing_key @@ -108,7 +129,7 @@ def decode(self, token, verify=True): algorithms=[self.algorithm], audience=self.audience, issuer=self.issuer, - leeway=self.leeway, + leeway=self.get_leeway(), options={ "verify_aud": self.audience is not None, "verify_signature": verify, diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index 3b7a31a27..3504d6a90 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -19,7 +19,7 @@ msgstr "Autorizační hlavička musí obsahovat dvě hodnoty oddělené mezerou" msgid "Given token not valid for any token type" msgstr "Daný token není validní pro žádný typ tokenu" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "Token neobsahoval žádnou rozpoznatelnou identifikaci uživatele" @@ -31,19 +31,24 @@ msgstr "Uživatel nenalezen" msgid "User is inactive" msgstr "Uživatel není aktivní" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "Nerozpoznaný typ algoritmu '{}'" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" diff --git a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po index 66923f9f7..75ff8e618 100644 --- a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Der Token ist für keinen Tokentyp gültig" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "Token enthält keine erkennbare Benutzeridentifikation" @@ -33,19 +33,24 @@ msgstr "Benutzer nicht gefunden" msgid "User is inactive" msgstr "Inaktiver Benutzer" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "Unerkannter Algorithmustyp '{}'" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 3df80e995..88f530531 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "El token dado no es valido para ningun tipo de token" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "El token no contenía identificación de usuario reconocible" @@ -33,19 +33,24 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "Debe tener criptografía instalada para usar {}." -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "Algoritmo especificado no válido" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index 6c08f8641..d68d84c82 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -26,7 +26,7 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "El token dado no es válido para ningún tipo de token" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "El token no contiene ninguna identificación de usuario" @@ -38,19 +38,24 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index af3bfd32d..e520756c2 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -21,7 +21,7 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "El token provisto no es válido para ningún tipo de token" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "El token no contiene identificación de usuario reconocible" @@ -33,19 +33,24 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token inválido o expirado" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index d18adb308..786d19205 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -19,7 +19,7 @@ msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا ش msgid "Given token not valid for any token type" msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" @@ -31,19 +31,24 @@ msgstr "کاربر یافت نشد" msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index a37e09dae..ec8d8a860 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -20,7 +20,7 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Le type de jeton fourni n'est pas valide" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "" "Le jeton ne contient aucune information permettant d'identifier l'utilisateur" @@ -33,19 +33,24 @@ msgstr "L'utilisateur n'a pas été trouvé" msgid "User is inactive" msgstr "L'utilisateur est désactivé" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "Type d'algorithme non reconnu '{}'" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "Vous devez installer cryptography afin d'utiliser {}." -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "L'algorithme spécifié est invalide" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index 249407108..a3bf6dad1 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -20,7 +20,7 @@ msgstr "Header otorisasi harus berisi dua nilai yang dipisahkan spasi" msgid "Given token not valid for any token type" msgstr "Token yang diberikan tidak valid untuk semua jenis token" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "Token tidak mengandung identifikasi pengguna yang dapat dikenali" @@ -32,19 +32,24 @@ msgstr "Pengguna tidak ditemukan" msgid "User is inactive" msgstr "Pengguna tidak aktif" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "Jenis algoritma tidak dikenal '{}'" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "Anda harus memasang kriptografi untuk menggunakan {}." -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "Algoritma yang ditentukan tidak valid" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index daf576fa6..a12647273 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -24,7 +24,7 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Il token dato non è valido per qualsiasi tipo di token" -#: authentication.py:116 authentication.py:138 +#: authentication.py:116 authentication.py:143 msgid "Token contained no recognizable user identification" msgstr "Il token non conteneva nessuna informazione riconoscibile dell'utente" @@ -36,19 +36,24 @@ msgstr "Utente non trovato" msgid "User is inactive" msgstr "Utente non attivo" -#: backends.py:60 +#: backends.py:64 msgid "Unrecognized algorithm type '{}'" msgstr "Algoritmo di tipo '{}' non riconosciuto" -#: backends.py:66 +#: backends.py:70 msgid "You must have cryptography installed to use {}." msgstr "Devi avere installato cryptography per usare '{}'." -#: backends.py:118 +#: backends.py:85 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:139 msgid "Invalid algorithm specified" msgstr "L'algoritmo specificato non è valido" -#: backends.py:120 exceptions.py:38 tokens.py:44 +#: backends.py:141 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.mo index efc22ceb76631609ba9a98fb0e24247133ffb0cd..2be0e27d5fe32fd74bbac28f6da6365e265f942a 100644 GIT binary patch delta 732 zcmZ9}&ubGw6u|LGjK=z-)z(zoSa=%Cs>Fyt5D^iJ9?YTWK@h=9G#d$|iL_g#il%6k zVv2@rQ&UK#f){@rs_jJ({1{7&|hZv!;M>7Y_4aRB3Z5BK65jN&pL#-Df|V{2Mvdy73qe;2`eCr??;A;~rc=v%_E;r+~d^;VIt? z<`_RgbK1W!dX!Ft-#?3oa5LWYEuq;-6?s-oqq&uC_eCJO%bb}B^M;8ok~>(99ke~} zN+8zP>Cdp2)t@uNO{6)Q$U*o*u zFZpA>s%OW=o3DFrLzf%!Pff30F)#kD>zB~8i+Xxd*FH+K_R1?yc;%M~<$WkMXBxWn Ut~oR1RT`r2y9dHycd%{p4?M_@Jpcdz delta 511 zcmXZZJxIeq7{>7@F@99*SJP^x3ThRLsPz*ZT*NM2)J+99ap~abBvcT0Avo#aBDjc1 zaTGEX7r`zrLXZxQItea<_`ftS_ulXBO}NWlu2OGq`90yBi%64$WI&FSmlho{YfCFQ zhf{cfIlRCOR&gHdxPfj{W1T(hW`2wdc!vF0jp_mRN@aaANb=w>(sddO=Wv*M0ef&C zyYLY6c#7@#5a}aJ=ox9M(RFZ$SKMM=Zs93fR7lS0BNexnZJ Date: Tue, 12 Apr 2022 21:02:31 +0900 Subject: [PATCH 027/171] [pre-commit.ci] pre-commit autoupdate (#557) --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 30f8b835f..1ef86d604 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.1.0' + rev: 'v4.2.0' hooks: - id: check-merge-conflict - repo: https://github.com/asottile/yesqa @@ -18,7 +18,7 @@ repos: - id: black language_version: python3 # Should be a command that runs python3.6+ - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.1.0' + rev: 'v4.2.0' hooks: - id: end-of-file-fixer exclude: >- @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.31.1' + rev: 'v2.32.0' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From c6e659803307c00da62de9769abac13879dc0eb4 Mon Sep 17 00:00:00 2001 From: Vladimir <44180334+inti7ary@users.noreply.github.com> Date: Mon, 18 Apr 2022 18:13:55 +0300 Subject: [PATCH 028/171] Add info on TokenBlacklistView to the docs (#558) --- docs/blacklist_app.rst | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/blacklist_app.rst b/docs/blacklist_app.rst index 709c9ceb9..f6c6ba2f1 100644 --- a/docs/blacklist_app.rst +++ b/docs/blacklist_app.rst @@ -46,6 +46,28 @@ subclass instance and calling the instance's ``blacklist`` method: This will create unique outstanding token and blacklist records for the token's "jti" claim or whichever claim is specified by the ``JTI_CLAIM`` setting. +In a ``urls.py`` file, you can also include a route for ``TokenBlackListView``: + +.. code-block:: python + + from rest_framework_simplejwt.views import TokenBlacklistView + + urlpatterns = [ + ... + path('api/token/blacklist/', TokenBlacklistView.as_view(), name='token_blacklist'), + ... + ] + +It allows API users to blacklist tokens sending them to ``/api/token/blacklist/``, for example using curl: + +.. code-block:: bash + + curl \ + -X POST \ + -H "Content-Type: application/json" \ + -d '{"refresh":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImV4cCI6MTY1MDI5NTEwOCwiaWF0IjoxNjUwMjA4NzA4LCJqdGkiOiJhYTY3ZDUxNzkwMGY0MTEyYTY5NTE0MTNmNWQ4NDk4NCIsInVzZXJfaWQiOjF9.tcj1_OcO1BRDfFyw4miHD7mqFdWKxmP7BJDRmxwCzrg"}' \ + http://localhost:8000/api/token/blacklist/ + The blacklist app also provides a management command, ``flushexpiredtokens``, which will delete any tokens from the outstanding list and blacklist that have expired. You should set up a cron job on your server or hosting platform which From 820a576bf58715a10ec77177243ac914b70c517e Mon Sep 17 00:00:00 2001 From: Tom Hu <88201630+thomasrockhu-codecov@users.noreply.github.com> Date: Sat, 23 Apr 2022 05:45:37 -0700 Subject: [PATCH 029/171] chore(ci): add informational Codecov status checks (#559) --- codecov.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/codecov.yml b/codecov.yml index d7436ab05..cca09ecbe 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,7 +1,11 @@ coverage: status: - project: false - patch: false + project: + default: + informational: true + patch: + default: + informational: true changes: false comment: off From 8e8a08a5611020aa86fb088edb3ccd64f3d0912f Mon Sep 17 00:00:00 2001 From: yeongkwang Date: Sat, 23 Apr 2022 21:47:06 +0900 Subject: [PATCH 030/171] Update JWTStatelessUserAuthentication docs (#561) --- docs/stateless_user_authentication.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/stateless_user_authentication.rst b/docs/stateless_user_authentication.rst index a0dfb7705..dcb1aea83 100644 --- a/docs/stateless_user_authentication.rst +++ b/docs/stateless_user_authentication.rst @@ -27,3 +27,6 @@ Framework's ``DEFAULT_AUTHENTICATION_CLASSES`` config setting: ) ... } + +v5.1.0 has renamed ``JWTTokenUserAuthentication`` to ``JWTStatelessUserAuthentication``, +but both names are supported for backwards compatibility From 70b8f842fae867e9aaf89d6d8ef0044e5c2517ae Mon Sep 17 00:00:00 2001 From: Dennis Dinwiddie <51653728+denniskeends@users.noreply.github.com> Date: Tue, 3 May 2022 18:20:20 -0400 Subject: [PATCH 031/171] Allow none jti claim token type claim (#567) --- rest_framework_simplejwt/tokens.py | 13 ++++++++++--- tests/test_tokens.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index f7bb269a1..69dbc52e3 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -92,11 +92,18 @@ def verify(self): # claim. We don't want any zombie tokens walking around. self.check_exp() - # Ensure token id is present - if api_settings.JTI_CLAIM not in self.payload: + # If the defaults are not None then we should enforce the + # requirement of these settings.As above, the spec labels + # these as optional. + if ( + api_settings.JTI_CLAIM is not None + and api_settings.JTI_CLAIM not in self.payload + ): raise TokenError(_("Token has no id")) - self.verify_token_type() + if api_settings.TOKEN_TYPE_CLAIM is not None: + + self.verify_token_type() def verify_token_type(self): """ diff --git a/tests/test_tokens.py b/tests/test_tokens.py index 43b912db4..bc06997d9 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -225,6 +225,16 @@ def test_set_jti(self): self.assertIn("jti", token) self.assertNotEqual(old_jti, token["jti"]) + def test_optional_jti(self): + with override_api_settings(JTI_CLAIM=None): + token = MyToken() + self.assertNotIn("jti", token) + + def test_optional_type_token(self): + with override_api_settings(TOKEN_TYPE_CLAIM=None): + token = MyToken() + self.assertNotIn("type", token) + def test_set_exp(self): now = make_utc(datetime(year=2000, month=1, day=1)) From 58b187400c036fd23cda53ab35b2f957d86c08af Mon Sep 17 00:00:00 2001 From: vainu-arto <70135394+vainu-arto@users.noreply.github.com> Date: Wed, 4 May 2022 16:28:00 +0300 Subject: [PATCH 032/171] Allow customizing token JSON encoding (#568) * Allow specifying custom JSONEncoder for TokenBackend * Make TokenBackend JSONEncoder configurable --- rest_framework_simplejwt/backends.py | 12 ++++++++++-- rest_framework_simplejwt/settings.py | 2 ++ rest_framework_simplejwt/state.py | 1 + tests/test_backends.py | 17 +++++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index 2fda76c44..420b5d8cc 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -1,5 +1,6 @@ +import json from datetime import timedelta -from typing import Union +from typing import Optional, Type, Union import jwt from django.utils.translation import gettext_lazy as _ @@ -38,6 +39,7 @@ def __init__( issuer=None, jwk_url: str = None, leeway: Union[float, int, timedelta] = None, + json_encoder: Optional[Type[json.JSONEncoder]] = None, ): self._validate_algorithm(algorithm) @@ -53,6 +55,7 @@ def __init__( self.jwks_client = None self.leeway = leeway + self.json_encoder = json_encoder def _validate_algorithm(self, algorithm): """ @@ -107,7 +110,12 @@ def encode(self, payload): if self.issuer is not None: jwt_payload["iss"] = self.issuer - token = jwt.encode(jwt_payload, self.signing_key, algorithm=self.algorithm) + token = jwt.encode( + jwt_payload, + self.signing_key, + algorithm=self.algorithm, + json_encoder=self.json_encoder, + ) if isinstance(token, bytes): # For PyJWT <= 1.7.1 return token.decode("utf-8") diff --git a/rest_framework_simplejwt/settings.py b/rest_framework_simplejwt/settings.py index b4bac42ff..1aeb48c47 100644 --- a/rest_framework_simplejwt/settings.py +++ b/rest_framework_simplejwt/settings.py @@ -20,6 +20,7 @@ "VERIFYING_KEY": "", "AUDIENCE": None, "ISSUER": None, + "JSON_ENCODER": None, "JWK_URL": None, "LEEWAY": 0, "AUTH_HEADER_TYPES": ("Bearer",), @@ -44,6 +45,7 @@ IMPORT_STRINGS = ( "AUTH_TOKEN_CLASSES", + "JSON_ENCODER", "TOKEN_USER_CLASS", "USER_AUTHENTICATION_RULE", ) diff --git a/rest_framework_simplejwt/state.py b/rest_framework_simplejwt/state.py index 4fe94faef..2637df233 100644 --- a/rest_framework_simplejwt/state.py +++ b/rest_framework_simplejwt/state.py @@ -9,4 +9,5 @@ api_settings.ISSUER, api_settings.JWK_URL, api_settings.LEEWAY, + api_settings.JSON_ENCODER, ) diff --git a/tests/test_backends.py b/tests/test_backends.py index 14bb6b9ad..cd3a6fc04 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -1,4 +1,6 @@ +import uuid from datetime import datetime, timedelta +from json import JSONEncoder from unittest import mock from unittest.mock import patch @@ -34,6 +36,13 @@ IS_OLD_JWT = jwt_version == "1.7.1" +class UUIDJSONEncoder(JSONEncoder): + def default(self, obj): + if isinstance(obj, uuid.UUID): + return str(obj) + return super().default(obj) + + class TestTokenBackend(TestCase): def setUp(self): self.hmac_token_backend = TokenBackend("HS256", SECRET) @@ -329,3 +338,11 @@ def test_decode_leeway_hmac_success(self): self.hmac_leeway_token_backend.decode(expired_token), self.payload, ) + + def test_custom_JSONEncoder(self): + backend = TokenBackend("HS256", SECRET, json_encoder=UUIDJSONEncoder) + unique = uuid.uuid4() + self.payload["uuid"] = unique + token = backend.encode(self.payload) + decoded = backend.decode(token) + self.assertEqual(decoded["uuid"], str(unique)) From 5060858e4ac2fe00fc0fc0472183cd30c63f8bcd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 May 2022 17:02:32 -0400 Subject: [PATCH 033/171] [pre-commit.ci] pre-commit autoupdate (#571) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.32.0 → v2.32.1](https://github.com/asottile/pyupgrade/compare/v2.32.0...v2.32.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1ef86d604..dbac7a118 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.32.0' + rev: 'v2.32.1' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From 1e20e3f811436eb8edbba038b10318eec0ff3709 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Sat, 21 May 2022 10:39:10 -0400 Subject: [PATCH 034/171] Update CHANGELOG to 5.2.0 (#573) --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c38d69200..a7fbb7f66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ ## Unreleased +## Version 5.2.0 + +* Remove the JWTTokenUserAuthentication from the Experimental Features #546 by @byrpatrick in https://github.com/jazzband/djangorestframework-simplejwt/pull/547 +* Fix leeway type error by @2ykwang in https://github.com/jazzband/djangorestframework-simplejwt/pull/554 +* Add info on TokenBlacklistView to the docs by @inti7ary in https://github.com/jazzband/djangorestframework-simplejwt/pull/558 +* Update JWTStatelessUserAuthentication docs by @2ykwang in https://github.com/jazzband/djangorestframework-simplejwt/pull/561 +* Allow none jti claim token type claim by @denniskeends in https://github.com/jazzband/djangorestframework-simplejwt/pull/567 +* Allow customizing token JSON encoding by @vainu-arto in https://github.com/jazzband/djangorestframework-simplejwt/pull/568 + ## Version 5.1.0 * Add back support for PyJWT 1.7.1 ([#536](https://github.com/jazzband/djangorestframework-simplejwt/pull/536)) From dfc954c3ef6de313056100dc31cf5fac37bd7c0f Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Tue, 24 May 2022 15:20:23 -0400 Subject: [PATCH 035/171] Locale update (#574) --- .../locale/cs/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/de_CH/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/es/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/es_AR/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/es_CL/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/fa_IR/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/fr/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/id_ID/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/it_IT/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/ko_KR/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/nl_NL/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/pl_PL/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/pt_BR/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/ru_RU/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/tr/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/uk_UA/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/zh_Hans/LC_MESSAGES/django.po | 24 +++++++++---------- 17 files changed, 204 insertions(+), 204 deletions(-) diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index 3504d6a90..820694192 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -31,24 +31,24 @@ msgstr "Uživatel nenalezen" msgid "User is inactive" msgstr "Uživatel není aktivní" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Nerozpoznaný typ algoritmu '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" @@ -56,7 +56,7 @@ msgstr "Token není validní nebo vypršela jeho platnost" msgid "No active account found with the given credentials" msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -86,26 +86,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Nelze vytvořit token bez zadaného typu nebo životnosti" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Token nemá žádný identifikátor" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Token nemá žádný typ" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Token má špatný typ" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Token nemá žádnou hodnotu '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Hodnota tokenu '{}' vypršela" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po index 75ff8e618..467b1737e 100644 --- a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po @@ -33,24 +33,24 @@ msgstr "Benutzer nicht gefunden" msgid "User is inactive" msgstr "Inaktiver Benutzer" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Unerkannter Algorithmustyp '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" @@ -58,7 +58,7 @@ msgstr "Ungültiger oder abgelaufener Token" msgid "No active account found with the given credentials" msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,26 +90,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Ein Token ohne Typ oder Lebensdauer kann nicht erstellt werden" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Token hat keine Id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Token hat keinen Typ" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Token hat den falschen Typ" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Token hat kein '{}' Recht" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Das Tokenrecht '{}' ist abgelaufen" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 88f530531..e582b9387 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -33,24 +33,24 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "Debe tener criptografía instalada para usar {}." -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "Algoritmo especificado no válido" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" @@ -58,7 +58,7 @@ msgstr "El token es inválido o ha expirado" msgid "No active account found with the given credentials" msgstr "La combinación de credenciales no tiene una cuenta activa" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,26 +90,26 @@ msgstr "Lista negra de Tokens" msgid "Cannot create token with no type or lifetime" msgstr "No se puede crear un token sin tipo o de tan larga vida" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index d68d84c82..a121209ca 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -38,24 +38,24 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" @@ -64,7 +64,7 @@ msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales dadas" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -96,26 +96,26 @@ msgstr "Lista negra de Tokens" msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "El token está en la lista negra" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index e520756c2..c833109b0 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -33,24 +33,24 @@ msgstr "Usuario no encontrado" msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token inválido o expirado" @@ -59,7 +59,7 @@ msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -91,26 +91,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Token no tiene id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Token no tiene tipo" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Token tiene tipo erróneo" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Token no tiene privilegio '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "El provilegio '{}' del token está expirado" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index 786d19205..324990d52 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -31,24 +31,24 @@ msgstr "کاربر یافت نشد" msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" @@ -56,7 +56,7 @@ msgstr "توکن نامعتبر است یا منقضی شده است" msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -86,26 +86,26 @@ msgstr "لیست سیاه توکن" msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index ec8d8a860..0318e19bf 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -33,24 +33,24 @@ msgstr "L'utilisateur n'a pas été trouvé" msgid "User is inactive" msgstr "L'utilisateur est désactivé" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Type d'algorithme non reconnu '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "Vous devez installer cryptography afin d'utiliser {}." -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "L'algorithme spécifié est invalide" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" @@ -58,7 +58,7 @@ msgstr "Le jeton est invalide ou expiré" msgid "No active account found with the given credentials" msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,26 +90,26 @@ msgstr "Liste des jetons bannis" msgid "Cannot create token with no type or lifetime" msgstr "Ne peut pas créer de jeton sans type ni durée de vie" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Le jeton n'a pas d'id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Le jeton n'a pas de type" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Le jeton a un type erroné" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Le jeton n'a pas le privilège '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Le privilège '{}' du jeton a expiré" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index a3bf6dad1..a470b1556 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -32,24 +32,24 @@ msgstr "Pengguna tidak ditemukan" msgid "User is inactive" msgstr "Pengguna tidak aktif" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Jenis algoritma tidak dikenal '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "Anda harus memasang kriptografi untuk menggunakan {}." -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "Algoritma yang ditentukan tidak valid" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" @@ -57,7 +57,7 @@ msgstr "Token tidak valid atau kedaluwarsa" msgid "No active account found with the given credentials" msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -89,26 +89,26 @@ msgstr "Daftar Hitam Token" msgid "Cannot create token with no type or lifetime" msgstr "Tidak dapat membuat token tanpa tipe atau masa pakai" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Token tidak memiliki id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Token tidak memiliki tipe" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Jenis token salah" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Token tidak memiliki klaim '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Klaim token '{}' telah kedaluwarsa" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index a12647273..3ac1418b1 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -36,24 +36,24 @@ msgstr "Utente non trovato" msgid "User is inactive" msgstr "Utente non attivo" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Algoritmo di tipo '{}' non riconosciuto" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "Devi avere installato cryptography per usare '{}'." -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "L'algoritmo specificato non è valido" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" @@ -61,7 +61,7 @@ msgstr "Il token non è valido o è scaduto" msgid "No active account found with the given credentials" msgstr "Nessun account attivo trovato con queste credenziali" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -93,26 +93,26 @@ msgstr "Blacklist dei token" msgid "Cannot create token with no type or lifetime" msgstr "Impossibile creare un token senza tipo o durata" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Il token non ha un id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Il token non ha un tipo" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Il token ha un tipo sbagliato" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Il token non contiene il parametro '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Il parametro '{}' del token è scaduto" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index d1fcf28bf..49704c66a 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -32,26 +32,26 @@ msgstr "찾을 수 없는 사용자" msgid "User is inactive" msgstr "비활성화된 사용자" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "알 수 없는 알고리즘 유형 '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "{}를 사용하려면 암호화가 설치되어 있어야 합니다." -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "알 수 없는 타입 '{}', 'leeway' 값은 반드시 int, float 또는 timedelta 타입이어" "야 합니다." -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "잘못된 알고리즘이 지정되었습니다" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "유효하지 않거나 만료된 토큰" @@ -59,7 +59,7 @@ msgstr "유효하지 않거나 만료된 토큰" msgid "No active account found with the given credentials" msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -89,26 +89,26 @@ msgstr "토큰 블랙리스트" msgid "Cannot create token with no type or lifetime" msgstr "타입 또는 수명이 없는 토큰을 생성할 수 없습니다" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "토큰에 식별자가 주어지지 않음" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "토큰 타입이 주어지지 않음" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "잘못된 토큰 타입" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "토큰에 '{}' 클레임이 없음" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "토큰 '{}' 클레임이 만료되었습니다" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "블랙리스트에 추가된 토큰" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index 88a347b1c..1d0598b14 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -32,24 +32,24 @@ msgstr "Gebruiker niet gevonden" msgid "User is inactive" msgstr "Gebruiker is inactief" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Niet herkend algoritme type '{}" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token is niet geldig of verlopen" @@ -57,7 +57,7 @@ msgstr "Token is niet geldig of verlopen" msgid "No active account found with the given credentials" msgstr "Geen actief account gevonden voor deze gegevens" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -88,26 +88,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Kan geen token maken zonder type of levensduur" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Token heeft geen id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Token heeft geen type" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Token heeft het verkeerde type" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Token heeft geen '{}' recht" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Token '{}' recht is verlopen" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index c665300c3..84b499a79 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -31,24 +31,24 @@ msgstr "Użytkownik nie znaleziony" msgid "User is inactive" msgstr "Użytkownik jest nieaktywny" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Nierozpoznany typ algorytmu '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token jest niepoprawny lub wygasł" @@ -56,7 +56,7 @@ msgstr "Token jest niepoprawny lub wygasł" msgid "No active account found with the given credentials" msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -87,26 +87,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Nie można utworzyć tokena bez podanego typu lub żywotności" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Token nie posiada numeru identyfikacyjnego" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Token nie posiada typu" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Token posiada zły typ" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Token nie posiada upoważnienia '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Upoważnienie tokena '{}' wygasło" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index 8d06ba630..88d1a71d3 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -33,24 +33,24 @@ msgstr "Usuário não encontrado" msgid "User is inactive" msgstr "Usuário está inativo" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo '{}' não reconhecido" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "Você deve ter criptografia instalada para usar {}." -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "Algoritmo inválido especificado" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "O token é inválido ou expirado" @@ -58,7 +58,7 @@ msgstr "O token é inválido ou expirado" msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,26 +90,26 @@ msgstr "Lista negra de Tokens" msgid "Cannot create token with no type or lifetime" msgstr "Não é possível criar token sem tipo ou tempo de vida" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Token não tem id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Token não tem nenhum tipo" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Token tem tipo errado" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Token não tem '{}' privilégio" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "O privilégio '{}' do token expirou" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index e1bf83e23..18f60a8b2 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -37,24 +37,24 @@ msgstr "Пользователь не найден" msgid "User is inactive" msgstr "Пользователь неактивен" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Нераспознанный тип алгоритма '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Токен недействителен или просрочен" @@ -62,7 +62,7 @@ msgstr "Токен недействителен или просрочен" msgid "No active account found with the given credentials" msgstr "Не найдено активной учетной записи с указанными данными" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -94,26 +94,26 @@ msgstr "Token Blacklist" msgid "Cannot create token with no type or lifetime" msgstr "Невозможно создать токен без типа или времени жизни" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "У токена нет идентификатора" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Токен не имеет типа" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Токен имеет неправильный тип" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Токен не содержит '{}'" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Токен имеет просроченное значение '{}'" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 8a2ade17e..4407447d4 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -34,24 +34,24 @@ msgstr "Kullanıcı bulunamadı" msgid "User is inactive" msgstr "Kullanıcı etkin değil" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Tanınmayan algortima tipi '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "{} kullanmak için cryptography yüklemeniz gerekiyor." -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "Geçersiz algoritma belirtildi" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token geçersiz veya süresi geçmiş" @@ -59,7 +59,7 @@ msgstr "Token geçersiz veya süresi geçmiş" msgid "No active account found with the given credentials" msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -89,26 +89,26 @@ msgstr "Token Kara Listesi" msgid "Cannot create token with no type or lifetime" msgstr "Tipi veya geçerlilik süresi olmayan token oluşturulamaz" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "Token'in id'si yok" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "Token'in tipi yok" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "Token'in tipi yanlış" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "Token'in '{}' claim'i yok" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Token'in '{}' claim'i sona erdi" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Token kara listeye alınmış" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index bcd3038b0..f23d49e79 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -35,24 +35,24 @@ msgstr "Користувач не знайдений" msgid "User is inactive" msgstr "Користувач неактивний" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "Тип алгоритму '{}' не розпізнаний" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "Встановіть модуль cryptography щоб використовувати {}" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "Вказаний невірний алгоритм" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Токен некоректний або термін його дії вичерпаний" @@ -60,7 +60,7 @@ msgstr "Токен некоректний або термін його дії в msgid "No active account found with the given credentials" msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,26 +90,26 @@ msgstr "Чорний список токенів" msgid "Cannot create token with no type or lifetime" msgstr "Неможливо створити токен без типу або строку дії" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "У ключі доступу не міститься id" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "У ключі доступу не міститься тип" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "токен позначений невірним типом" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "У токені не міститься '{}' заголовку" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "Заголовок '{}' токена не дійсний" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index 3768807ae..fbfa3b842 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -35,24 +35,24 @@ msgstr "未找到该用户" msgid "User is inactive" msgstr "该用户已禁用" -#: backends.py:64 +#: backends.py:67 msgid "Unrecognized algorithm type '{}'" msgstr "未知算法类型 '{}'" -#: backends.py:70 +#: backends.py:73 msgid "You must have cryptography installed to use {}." msgstr "你必须安装 cryptography 才能使用 {}。" -#: backends.py:85 +#: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:139 +#: backends.py:147 msgid "Invalid algorithm specified" msgstr "指定的算法无效" -#: backends.py:141 exceptions.py:38 tokens.py:44 +#: backends.py:149 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "令牌无效或已过期" @@ -60,7 +60,7 @@ msgstr "令牌无效或已过期" msgid "No active account found with the given credentials" msgstr "找不到指定凭据对应的有效用户" -#: settings.py:68 +#: settings.py:70 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,26 +90,26 @@ msgstr "令牌黑名单" msgid "Cannot create token with no type or lifetime" msgstr "无法创建没有类型或生存期的令牌" -#: tokens.py:97 +#: tokens.py:102 msgid "Token has no id" msgstr "令牌没有标识符" -#: tokens.py:108 +#: tokens.py:115 msgid "Token has no type" msgstr "令牌没有类型" -#: tokens.py:111 +#: tokens.py:118 msgid "Token has wrong type" msgstr "令牌类型错误" -#: tokens.py:163 +#: tokens.py:170 msgid "Token has no '{}' claim" msgstr "令牌没有 '{}' 声明" -#: tokens.py:168 +#: tokens.py:175 msgid "Token '{}' claim has expired" msgstr "令牌 '{}' 声明已过期" -#: tokens.py:223 +#: tokens.py:230 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" From 085a3bd9346b5b92ef1e543c8986d49db1096aa6 Mon Sep 17 00:00:00 2001 From: abdurrahman <32853027+asaah18@users.noreply.github.com> Date: Tue, 24 May 2022 22:22:11 +0300 Subject: [PATCH 036/171] update & correct supported versions in docs (#576) * update & correct supported versions in docs * Add DRF supported version Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- docs/getting_started.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 6c87b9c92..8e961d34d 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -7,8 +7,8 @@ Requirements ------------ * Python (3.7, 3.8, 3.9, 3.10) -* Django (2.2, 3.1, 3.2) -* Django REST Framework (3.10, 3.11, 3.12) +* Django (2.2, 3.1, 3.2, 4.0) +* Django REST Framework (3.10, 3.11, 3.12, 3.13) These are the officially supported python and package versions. Other versions will probably work. You're free to modify the tox config and see what is From 2cf3269664719ad7e554f4c010b5cfeaddb065f9 Mon Sep 17 00:00:00 2001 From: Pasindu Prabhashitha <63661350+PasinduPrabhashitha@users.noreply.github.com> Date: Sat, 4 Jun 2022 01:03:49 +0530 Subject: [PATCH 037/171] Add Swedish translations (#579) --- .../locale/sv/LC_MESSAGES/django.mo | Bin 0 -> 2281 bytes .../locale/sv/LC_MESSAGES/django.po | 115 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.mo create mode 100644 rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..5370a8829e94f24ea2060ed3e2746f06d8d1336b GIT binary patch literal 2281 zcmZXV%WoVt9LEim*Ya-4OMqk$s6k@4P2o^B4K#hBs-y{!AaO#@jCaOak3F(~Gij(Q zAtCNudV*tC+>yu`X~T&_FB}l6DvlgD@ds3V?U_k7!piJt?D6mC-_yBw{Mc=V@e-a_ z@!ZAp7M>p-zz@dh2N^pDE`aZV2Al`K2VVjA!871r;3_!xP@^XSpTYcV@Lljb@I`RH zUB3%HhxtF?3GjZ)xnqsqd5~lM68J1A!Kc9*JOzFW_Q0Q8{sKY;`whe&yMv!O`0zV; z4fDSrW^4ey_XvCe6EOID8~hOb3A_&e3%&s^Kib%zg26umUju&xkAuI0bKoCf^aFez z^ZVeN;EBf?f8THU3HUPB6?h)}1`PJ^x4Z)e`~Pg`_rQ>XptBo~cQ0T#Gn^mBQw^eB zNJAVU)*+`Mc5prFhRQgez;B2pTs;^to4wG^o&-Y-LterNc7|NWv0PDZo%%|UvWDkU zq|))C^28HsNGQW;+j3uuMD|muRiQ|xycW8Wo?R5iSnPCCkmO{?((r9XIX9NmPAR!{ zT&s~JRY>-cs`0tm6r`X-rF?`f!tAu`L5N*7%_pHVSVnn)<7J{oN~Y|(s2>dBk8PI51al*xE5Jl~YC#mU0fG9Bw(6;YqOQ7W9-e!QSXGS^?l_=(_68YWKy+HKv7?ZD-->%%XzNomB^RVo|lhMjARFHcV$C z3_eUkOlUBNZA7DkY?F&-A>=eBgMDGEri5~VL?v#gB%3)=<~tDaB(#QNgc;8Bo3{q6 zsUMt0tg*p|*DX>kgomv;yCoCqUrqa;OXpFiL!NF4gX)l;MotuR+q&_WUKOR5Tiew8 zRF>9Jf5m4i?O&)e-(R;w-uqa1>aROtycT5Lkgo}^Oj_}CW%E)xu_=6xniJ=<0;wM) zw)g;YCaXjyhg|yJ%GH(2hjuIsPWLXNQBZ9CbrkQAle|HvN)(1!QyT+rGd5 zk3|WQSl<<46)ESCMTu%vdkw)XjeSh*E@)^(Go?voD1hmn<7PU^aG69!P{CH4uU##L zjtNblp&vcE9pqw+rY1f{C@n_<2nKo>o^lw9t*SNxgvllqt}4q+jYv8pAn$3qtF=KO z(9^MBf_@U2A{0FeVZc9YuYhPCDXp{Mi&mM471_xP*EU(u(nrWjH=T@OUQno~dnNIz z>uFyLM>9R%1bt6yXbgsQO&v4DMSW;JLf$oMh+c62$a(+!I@9ZoK+Md{wvp5!SM5qj z%7JyFyC=e`Z4=St^oUcd;}F_|6ot&kUSIBF4wss2$5gS|^@DtcDq@$={7oI^f{(lA tAE_AW(ECo{+7ERi2pO-;OlISC5X%t%W8ii+oj8P?k9E8b4hlfB{{YT8sM!Dj literal 0 HcmV?d00001 diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po new file mode 100644 index 000000000..d9e754e92 --- /dev/null +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -0,0 +1,115 @@ +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR Pasindu , 2022. +msgid "" +msgstr "" +"Project-Id-Version: djangorestframework_simplejwt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-05-29 17:30+0100\n" +"Last-Translator: Pasindu \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:78 +msgid "Authorization header must contain two space-delimited values" +msgstr "" +"Auktoriseringshuvudet måste innehålla två mellanslagsavgränsade värden" + +#: authentication.py:104 +msgid "Given token not valid for any token type" +msgstr "Givet token är inte giltigt för någon tokentyp" + +#: authentication.py:116 authentication.py:143 +msgid "Token contained no recognizable user identification" +msgstr "Token innehöll ingen identifiering av användaren" + +#: authentication.py:121 +msgid "User not found" +msgstr "Användaren hittades inte" + +#: authentication.py:124 +msgid "User is inactive" +msgstr "Användaren är inaktiv" + +#: backends.py:67 +msgid "Unrecognized algorithm type '{}'" +msgstr "Okänd algoritmtyp '{}'" + +#: backends.py:73 +msgid "You must have cryptography installed to use {}." +msgstr "Du måste ha kryptografi installerad för att kunna använda {}." + +#: backends.py:88 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:147 +msgid "Invalid algorithm specified" +msgstr "Ogiltig algoritm har angetts" + +#: backends.py:149 exceptions.py:38 tokens.py:44 +msgid "Token is invalid or expired" +msgstr "Token är ogiltig eller har löpt ut" + +#: serializers.py:30 +msgid "No active account found with the given credentials" +msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" + +#: settings.py:70 +msgid "" +"The '{}' setting has been removed. Please refer to '{}' for available " +"settings." +msgstr "" +"Inställningen '{}' har tagits bort. Se '{}' för tillgängliga " +"inställningar" + +#: token_blacklist/admin.py:68 +msgid "jti" +msgstr "jti" + +#: token_blacklist/admin.py:74 +msgid "user" +msgstr "användare" + +#: token_blacklist/admin.py:80 +msgid "created at" +msgstr "skapad vid" + +#: token_blacklist/admin.py:86 +msgid "expires at" +msgstr "går ut kl" + +#: token_blacklist/apps.py:7 +msgid "Token Blacklist" +msgstr "Token svartlist" + +#: tokens.py:30 +msgid "Cannot create token with no type or lifetime" +msgstr "Kan inte skapa token utan typ eller livslängd" + +#: tokens.py:102 +msgid "Token has no id" +msgstr "Token har inget id" + +#: tokens.py:115 +msgid "Token has no type" +msgstr "Token har ingen typ" + +#: tokens.py:118 +msgid "Token has wrong type" +msgstr "Token har fel typ" + +#: tokens.py:170 +msgid "Token has no '{}' claim" +msgstr "Token har inget '{}'-anspråk" + +#: tokens.py:175 +msgid "Token '{}' claim has expired" +msgstr "Token '{}'-anspråket har löpt ut" + +#: tokens.py:230 +msgid "Token is blacklisted" +msgstr "Token är svartlistad" From 4b65afb44390f56ff2dad29ca292135d51cb0964 Mon Sep 17 00:00:00 2001 From: Armenak Baburyan <1723973+armenak-baburyan@users.noreply.github.com> Date: Mon, 6 Jun 2022 22:59:04 +0400 Subject: [PATCH 038/171] Fixed issue #543 (#586) * Allow optional installation of the 'cryptography' package (#543) * Update docs (#543) * Update docs (#543) * Update docs/getting_started.rst Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> * fix for code-block (#543) * another fix for code-block (#543) * fix: removed extra line (#543) Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- docs/getting_started.rst | 32 ++++++++++++++++++++++++++++---- setup.py | 3 +++ 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 8e961d34d..c07382414 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -17,10 +17,34 @@ possible. Installation ------------ -Simple JWT can be installed with pip:: +Simple JWT can be installed with pip: + +.. code-block:: console pip install djangorestframework-simplejwt + +Cryptographic Dependencies (Optional) +------------------------------------- + +If you are planning on encoding or decoding tokens using certain digital +signature algorithms (i.e. RSA and ECDSA; visit PyJWT for other algorithms), you will need to install the +cryptography_ library. This can be installed explicitly, or as a required +extra in the ``djangorestframework-simplejwt`` requirement: + +.. code-block:: console + + pip install djangorestframework-simplejwt[crypto] + +The ``djangorestframework-simplejwt[crypto]`` format is recommended in requirements +files in projects using ``Simple JWT``, as a separate ``cryptography`` requirement +line may later be mistaken for an unused requirement and removed. + +.. _`cryptography`: https://cryptography.io + +Project Configuration +--------------------- + Then, your django project must be configured to use the library. In ``settings.py``, add ``rest_framework_simplejwt.authentication.JWTAuthentication`` to the list of @@ -59,16 +83,16 @@ allow API users to verify HMAC-signed tokens without having access to your signing key: .. code-block:: python - + from rest_framework_simplejwt.views import TokenVerifyView - + urlpatterns = [ ... path('api/token/verify/', TokenVerifyView.as_view(), name='token_verify'), ... ] -If you wish to use localizations/translations, simply add +If you wish to use localizations/translations, simply add ``rest_framework_simplejwt`` to ``INSTALLED_APPS``. .. code-block:: python diff --git a/setup.py b/setup.py index 5687b6604..b99a707c7 100755 --- a/setup.py +++ b/setup.py @@ -30,6 +30,9 @@ "python-jose": [ "python-jose==3.3.0", ], + "crypto": [ + "cryptography>=3.3.1", + ], } extras_require["dev"] = ( From aa21b20b0d53071a6357417e8d02b434e63a50f6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jun 2022 07:50:40 +0900 Subject: [PATCH 039/171] [pre-commit.ci] pre-commit autoupdate (#587) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.2.0 → v4.3.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.2.0...v4.3.0) - [github.com/pre-commit/pre-commit-hooks: v4.2.0 → v4.3.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.2.0...v4.3.0) - [github.com/asottile/pyupgrade: v2.32.1 → v2.34.0](https://github.com/asottile/pyupgrade/compare/v2.32.1...v2.34.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dbac7a118..560225c11 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.2.0' + rev: 'v4.3.0' hooks: - id: check-merge-conflict - repo: https://github.com/asottile/yesqa @@ -18,7 +18,7 @@ repos: - id: black language_version: python3 # Should be a command that runs python3.6+ - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.2.0' + rev: 'v4.3.0' hooks: - id: end-of-file-fixer exclude: >- @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.32.1' + rev: 'v2.34.0' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From c707cf8bb096c9531f3c21ab2dea4d0efb80f291 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Jul 2022 10:42:56 +0900 Subject: [PATCH 040/171] [pre-commit.ci] pre-commit autoupdate (#589) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/psf/black: 22.3.0 → 22.6.0](https://github.com/psf/black/compare/22.3.0...22.6.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 560225c11..80f901864 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '22.3.0' + rev: '22.6.0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ From cd4ea99424ec7256291253a87f3435fec01ecf0e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 12 Jul 2022 08:08:39 +0900 Subject: [PATCH 041/171] [pre-commit.ci] pre-commit autoupdate (#590) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 80f901864..5675c2637 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.34.0' + rev: 'v2.37.1' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From 8da04ded7d98df589aa4192ae0ea690e7bed33ae Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 09:14:48 +0900 Subject: [PATCH 042/171] [pre-commit.ci] pre-commit autoupdate (#594) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.37.1 → v2.37.2](https://github.com/asottile/pyupgrade/compare/v2.37.1...v2.37.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5675c2637..a6721b908 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.37.1' + rev: 'v2.37.2' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From 2511712611b1707e2cd04c9a4d6082ae9c61a061 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 2 Aug 2022 07:48:15 +0900 Subject: [PATCH 043/171] [pre-commit.ci] pre-commit autoupdate (#597) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v2.37.2 → v2.37.3](https://github.com/asottile/pyupgrade/compare/v2.37.2...v2.37.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a6721b908..cbb8e8d1f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.37.2' + rev: 'v2.37.3' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From 9b6f1de3c99553b7d7ce7422d68ec3648b36eb44 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 9 Aug 2022 11:03:08 +0900 Subject: [PATCH 044/171] [pre-commit.ci] pre-commit autoupdate (#601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/yesqa: v1.3.0 → v1.4.0](https://github.com/asottile/yesqa/compare/v1.3.0...v1.4.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cbb8e8d1f..706ad4840 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-merge-conflict - repo: https://github.com/asottile/yesqa - rev: v1.3.0 + rev: v1.4.0 hooks: - id: yesqa - repo: https://github.com/pycqa/isort From 17ef9f8bee66b55bf580db8cbcdabdc8caa3c519 Mon Sep 17 00:00:00 2001 From: Jeremy Mayeres <1524722+jerr0328@users.noreply.github.com> Date: Mon, 15 Aug 2022 20:34:45 +0300 Subject: [PATCH 045/171] Fix uncaught exception with JWK (#600) * Fix uncaught exception with JWK * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Allow tests to run on older JWT versions Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/backends.py | 11 +++++---- tests/test_backends.py | 36 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index 420b5d8cc..da41528c3 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -10,7 +10,7 @@ from .utils import format_lazy try: - from jwt import PyJWKClient + from jwt import PyJWKClient, PyJWKClientError JWK_CLIENT_AVAILABLE = True except ImportError: @@ -96,7 +96,10 @@ def get_verifying_key(self, token): return self.signing_key if self.jwks_client: - return self.jwks_client.get_signing_key_from_jwt(token).key + try: + return self.jwks_client.get_signing_key_from_jwt(token).key + except PyJWKClientError as ex: + raise TokenBackendError(_("Token is invalid or expired")) from ex return self.verifying_key @@ -145,5 +148,5 @@ def decode(self, token, verify=True): ) except InvalidAlgorithmError as ex: raise TokenBackendError(_("Invalid algorithm specified")) from ex - except InvalidTokenError: - raise TokenBackendError(_("Token is invalid or expired")) + except InvalidTokenError as ex: + raise TokenBackendError(_("Token is invalid or expired")) from ex diff --git a/tests/test_backends.py b/tests/test_backends.py index cd3a6fc04..0314ba671 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -292,6 +292,42 @@ def test_decode_rsa_aud_iss_jwk_success(self): self.assertEqual(jwk_token_backend.decode(token), self.payload) + @pytest.mark.skipif( + not JWK_CLIENT_AVAILABLE, + reason="PyJWT 1.7.1 doesn't have JWK client", + ) + def test_decode_jwk_missing_key_raises_tokenbackenderror(self): + self.payload["exp"] = aware_utcnow() + timedelta(days=1) + self.payload["foo"] = "baz" + self.payload["aud"] = AUDIENCE + self.payload["iss"] = ISSUER + + token = jwt.encode( + self.payload, + PRIVATE_KEY_2, + algorithm="RS256", + headers={"kid": "230498151c214b788dd97f22b85410a5"}, + ) + + mock_jwk_module = mock.MagicMock() + with patch("rest_framework_simplejwt.backends.PyJWKClient") as mock_jwk_module: + mock_jwk_client = mock.MagicMock() + + mock_jwk_module.return_value = mock_jwk_client + mock_jwk_client.get_signing_key_from_jwt.side_effect = jwt.PyJWKClientError( + "Unable to find a signing key that matches" + ) + + # Note the PRIV,PUB care is intentially the original pairing + jwk_token_backend = TokenBackend( + "RS256", PRIVATE_KEY, PUBLIC_KEY, AUDIENCE, ISSUER, JWK_URL + ) + + with self.assertRaisesRegex( + TokenBackendError, "Token is invalid or expired" + ): + jwk_token_backend.decode(token) + def test_decode_when_algorithm_not_available(self): token = jwt.encode(self.payload, PRIVATE_KEY, algorithm="RS256") if IS_OLD_JWT: From 9b6e3b7845addd67d4dc714ee39dde870b164ba5 Mon Sep 17 00:00:00 2001 From: Youngkwang Yang Date: Tue, 16 Aug 2022 06:36:54 +0900 Subject: [PATCH 046/171] Test on Django 4.1 (#604) --- .github/workflows/test.yml | 2 +- setup.py | 1 + tox.ini | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a344ba8f3..6bbf2928d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: max-parallel: 5 matrix: python-version: ['3.7', '3.8', '3.9', '3.10'] - django-version: ['2.2', '3.2', '4.0', 'main'] + django-version: ['2.2', '3.2', '4.0', '4.1', 'main'] drf-version: ['3.10', '3.11', '3.12', '3.13'] exclude: - python-version: '3.7' diff --git a/setup.py b/setup.py index b99a707c7..3314e4bc2 100755 --- a/setup.py +++ b/setup.py @@ -71,6 +71,7 @@ "Framework :: Django :: 2.2", "Framework :: Django :: 3.2", "Framework :: Django :: 4.0", + "Framework :: Django :: 4.1", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", diff --git a/tox.ini b/tox.ini index 757a9c84b..3a074d43d 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist= py{37,38,39}-dj22-drf310-pyjwt{171,2}-tests py{37,38,39,310}-dj{22,32}-drf{311,312,313}-pyjwt{171,2}-tests - py{38,39,310}-dj{40,main}-drf313-pyjwt{171,2}-tests + py{38,39,310}-dj{40,41,main}-drf313-pyjwt{171,2}-tests docs [gh-actions] @@ -17,6 +17,7 @@ DJANGO= 2.2: dj22 3.2: dj32 4.0: dj40 + 4.1: dj41 main: djmain DRF= 3.10: drf310 @@ -35,6 +36,7 @@ deps= dj22: Django>=2.2,<2.3 dj32: Django>=3.2,<3.3 dj40: Django>=4.0,<4.1 + dj41: Django>=4.1,<4.2 drf310: djangorestframework>=3.10,<3.11 drf311: djangorestframework>=3.11,<3.12 drf312: djangorestframework>=3.12,<3.13 From d49b4665481e8d48716e39a103d61db6a596b61c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 6 Sep 2022 07:26:34 +0900 Subject: [PATCH 047/171] [pre-commit.ci] pre-commit autoupdate (#609) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 706ad4840..87f78c915 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '22.6.0' + rev: '22.8.0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ From e96fd731c51c60b56afa08ebd4c5514764ff562b Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Tue, 13 Sep 2022 19:04:15 -0400 Subject: [PATCH 048/171] Add v5.2.1 changes (#611) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7fbb7f66..9b13e8884 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## Unreleased +## Version 5.2.1 + +* Add Swedish translations by @PasinduPrabhashitha in https://github.com/jazzband/djangorestframework-simplejwt/pull/579 +* Fixed issue #543 by @armenak-baburyan in https://github.com/jazzband/djangorestframework-simplejwt/pull/586 +* Fix uncaught exception with JWK by @jerr0328 in https://github.com/jazzband/djangorestframework-simplejwt/pull/600 +* Test on Django 4.1 by @2ykwang in https://github.com/jazzband/djangorestframework-simplejwt/pull/604 + ## Version 5.2.0 * Remove the JWTTokenUserAuthentication from the Experimental Features #546 by @byrpatrick in https://github.com/jazzband/djangorestframework-simplejwt/pull/547 From d1c2c7c3038ed9599815098b05909fc7b0b9f702 Mon Sep 17 00:00:00 2001 From: "Benedikt S. Vogler" Date: Fri, 16 Sep 2022 07:35:50 +0200 Subject: [PATCH 049/171] use non-deprecated UTC timezone (#606) RemovedInDjango50Warning --- rest_framework_simplejwt/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rest_framework_simplejwt/utils.py b/rest_framework_simplejwt/utils.py index 48e950ad6..f1c4d3ae3 100644 --- a/rest_framework_simplejwt/utils.py +++ b/rest_framework_simplejwt/utils.py @@ -1,14 +1,14 @@ from calendar import timegm -from datetime import datetime +from datetime import datetime, timezone from django.conf import settings from django.utils.functional import lazy -from django.utils.timezone import is_naive, make_aware, utc +from django.utils.timezone import is_naive, make_aware def make_utc(dt): if settings.USE_TZ and is_naive(dt): - return make_aware(dt, timezone=utc) + return make_aware(dt, timezone=timezone.utc) return dt From 8d0a8065d083c300a26c094c0364d9898f3e439c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Cuzne=C5=A3ov?= Date: Fri, 16 Sep 2022 08:54:07 +0300 Subject: [PATCH 050/171] Added Romanian translations (#591) * Added Romanian translations * Changed some translations according to the grammatical rules of the Romanian language * Changed some translations according to the advices of: https://github.com/marcellefter https://github.com/uoxiu Co-authored-by: Daniel Cuznetov --- .../locale/ro/LC_MESSAGES/django.mo | Bin 0 -> 2548 bytes .../locale/ro/LC_MESSAGES/django.po | 113 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.mo create mode 100644 rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..d87cddd1107d20cbbe80c221d8da0991d01ab1ca GIT binary patch literal 2548 zcmZ{lyN?_-9LEiWM;1sRykEj7M3)npO#&&xUIKZLz)4An!X6@`K;9Yet}h;Y0>1_q!5_g7K(;;0T?Aji(1UM+pMelz--G1OPayg6TRZ+8q?9~~ zck*Cr`cNz>j`Td7!5#yVmh?Q0U$T#4h)^WmbRInq;-#1(6v-EW!OfH}`hEy6#qtRn z;7Re$p9p9SW9!rv5tKE2EJY<9ucHsVv?d5;cv!dGH=>k9CAF$mkQHAOI!ez@3S%rJ zofJXxU@u9-*HsvEV|mzUB)5)hHIzZslD)0gu$+Zx7j&qK4LXTis z7}q#nmTIVE#m-qS$^cD3X`=~H5KWa&4P(hi=@eL0NfVUNp7k-iaP`^(_c8=!Mtm$h zA4u5ZWNp`E)#c~46kcLHg!92>@nqSWP+APMoNV@8)=zFGjinZPTs27j4YS#sVoX-9{7a$cbjWfh|4=tzjY(hA{H0 z*SaiMBCHN9d*kVIH7G`bX6KzJSx7&t5so8XVQnE6SZ8o?$SqI)s2>` z>!EW&Hr9pWtRJbWI1xv_=-VFeoDn`0eJ709B3ResZwaHM<|pG7BZFPzN2)YYw&Meb zj*V)RQn$4A8`y0|QH*4dJKH(CeD>7LnuFZ~os+nDDBhxv%h2ONUJm;k6q;G$EiHAj_g3?7N<;UD^z%oA0DXCIj^G=x;SlJ?R(rbY3Pq0T;loj=z*mUdneua zBI>;Yr-rB(d4 z(w$DN13`yoTA#F+*$kpRRYDRNV{zod==x5B-IVdXRa}k1@oP0E_~Umwnwp*`4tM+ ud}*=%+;u_EqRPmfDph&uRPJCyR6tuP(^Snm7>X(PFVq1(Q~#Qt%KibnKly?H literal 0 HcmV?d00001 diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po new file mode 100644 index 000000000..4b6a1bf6b --- /dev/null +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -0,0 +1,113 @@ +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR Daniel Cuznetov , 2022. +msgid "" +msgstr "" +"Project-Id-Version: djangorestframework_simplejwt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-07-13 10:45+0100\n" +"Last-Translator: Daniel Cuznetov \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: authentication.py:78 +msgid "Authorization header must contain two space-delimited values" +msgstr "Header-ul(antetul) de autorizare trebuie să conțină două valori separate prin spațiu" + +#: authentication.py:104 +msgid "Given token not valid for any token type" +msgstr "Tokenul dat nu este valid pentru niciun tip de token" + +#: authentication.py:116 authentication.py:143 +msgid "Token contained no recognizable user identification" +msgstr "Tokenul nu conține date de identificare a utilizatorului" + +#: authentication.py:121 +msgid "User not found" +msgstr "Utilizatorul nu a fost găsit" + +#: authentication.py:124 +msgid "User is inactive" +msgstr "Utilizatorul este inactiv" + +#: backends.py:67 +msgid "Unrecognized algorithm type '{}'" +msgstr "Tipul de algoritm '{}' nu este recunoscut" + +#: backends.py:73 +msgid "You must have cryptography installed to use {}." +msgstr "Trebuie să aveți instalată criptografia pentru a utiliza {}." + +#: backends.py:88 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" +"Tipul '{}' nu este recunoscut, 'leeway' trebuie să fie de tip int, float sau timedelta." + +#: backends.py:147 +msgid "Invalid algorithm specified" +msgstr "Algoritm nevalid specificat" + +#: backends.py:149 exceptions.py:38 tokens.py:44 +msgid "Token is invalid or expired" +msgstr "Token nu este valid sau a expirat" + +#: serializers.py:30 +msgid "No active account found with the given credentials" +msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" + +#: settings.py:70 +msgid "" +"The '{}' setting has been removed. Please refer to '{}' for available " +"settings." +msgstr "Setarea '{}' a fost ștearsă. Referați la '{}' pentru setări disponibile." + +#: token_blacklist/admin.py:68 +msgid "jti" +msgstr "jti" + +#: token_blacklist/admin.py:74 +msgid "user" +msgstr "utilizator" + +#: token_blacklist/admin.py:80 +msgid "created at" +msgstr "creat la" + +#: token_blacklist/admin.py:86 +msgid "expires at" +msgstr "expiră la" + +#: token_blacklist/apps.py:7 +msgid "Token Blacklist" +msgstr "Listă de token-uri blocate" + +#: tokens.py:30 +msgid "Cannot create token with no type or lifetime" +msgstr "Nu se poate crea token fără tip sau durată de viață" + +#: tokens.py:102 +msgid "Token has no id" +msgstr "Tokenul nu are id" + +#: tokens.py:115 +msgid "Token has no type" +msgstr "Tokenul nu are tip" + +#: tokens.py:118 +msgid "Token has wrong type" +msgstr "Tokenul are tipul greșit" + +#: tokens.py:170 +msgid "Token has no '{}' claim" +msgstr "Tokenul nu are reclamația '{}'" + +#: tokens.py:175 +msgid "Token '{}' claim has expired" +msgstr "Reclamația tokenului '{}' a expirat" + +#: tokens.py:230 +msgid "Token is blacklisted" +msgstr "Tokenul este în listă de tokenuri blocate" From 8236a13916fe410161033f44b53b920be86b89f7 Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 16 Sep 2022 00:55:45 -0500 Subject: [PATCH 051/171] allow verification skipping (#605) * allow verify skip verification if VERIFYING_KEY is not set * Update settings.py * Update authentication.py * Update settings.py * Update authentication.py --- rest_framework_simplejwt/authentication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index 15767cddd..fd26bdb06 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -89,7 +89,7 @@ def get_validated_token(self, raw_token): messages = [] for AuthToken in api_settings.AUTH_TOKEN_CLASSES: try: - return AuthToken(raw_token) + return AuthToken(raw_token, api_settings.VERIFYING_KEY is not None) except TokenError as e: messages.append( { From bdfe841a0b1155cf67752efe40532a2102b1c3c1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Sep 2022 09:12:00 +0900 Subject: [PATCH 052/171] [pre-commit.ci] pre-commit autoupdate (#619) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 87f78c915..2c4cff4a1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.37.3' + rev: 'v2.38.0' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From d6b334a7eec4e81d95ad64a182f5751098b0efdd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 27 Sep 2022 07:03:07 +0900 Subject: [PATCH 053/171] [pre-commit.ci] pre-commit autoupdate (#620) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2c4cff4a1..c4df7495d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.38.0' + rev: 'v2.38.2' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From 7740384168d41736044562c9bf1749b3bf8cd941 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Wed, 28 Sep 2022 00:30:58 -0400 Subject: [PATCH 054/171] Update locale files (#624) --- .../locale/cs/LC_MESSAGES/django.po | 10 ++++----- .../locale/de_CH/LC_MESSAGES/django.po | 10 ++++----- .../locale/es/LC_MESSAGES/django.po | 10 ++++----- .../locale/es_AR/LC_MESSAGES/django.po | 10 ++++----- .../locale/es_CL/LC_MESSAGES/django.po | 10 ++++----- .../locale/fa_IR/LC_MESSAGES/django.po | 10 ++++----- .../locale/fr/LC_MESSAGES/django.po | 10 ++++----- .../locale/id_ID/LC_MESSAGES/django.po | 10 ++++----- .../locale/it_IT/LC_MESSAGES/django.po | 10 ++++----- .../locale/ko_KR/LC_MESSAGES/django.po | 10 ++++----- .../locale/nl_NL/LC_MESSAGES/django.po | 10 ++++----- .../locale/pl_PL/LC_MESSAGES/django.po | 10 ++++----- .../locale/pt_BR/LC_MESSAGES/django.po | 10 ++++----- .../locale/ro/LC_MESSAGES/django.po | 20 +++++++++++------- .../locale/ru_RU/LC_MESSAGES/django.po | 10 ++++----- .../locale/sv/LC_MESSAGES/django.mo | Bin 2281 -> 2281 bytes .../locale/sv/LC_MESSAGES/django.po | 16 ++++++-------- .../locale/tr/LC_MESSAGES/django.po | 10 ++++----- .../locale/uk_UA/LC_MESSAGES/django.po | 10 ++++----- .../locale/zh_Hans/LC_MESSAGES/django.po | 10 ++++----- 20 files changed, 104 insertions(+), 102 deletions(-) diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index 820694192..5f827c050 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -44,14 +44,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" diff --git a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po index 467b1737e..39954f752 100644 --- a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po @@ -46,14 +46,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index e582b9387..f0b787506 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -46,14 +46,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "Algoritmo especificado no válido" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "Algoritmo especificado no válido" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "La combinación de credenciales no tiene una cuenta activa" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index a121209ca..7a290a5d2 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -51,14 +51,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index c833109b0..bf67fed49 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -46,14 +46,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token inválido o expirado" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index 324990d52..f03fd4235 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -44,14 +44,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index 0318e19bf..021b39f57 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -46,14 +46,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "L'algorithme spécifié est invalide" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "L'algorithme spécifié est invalide" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index a470b1556..4cc7f58b9 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -45,14 +45,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "Algoritma yang ditentukan tidak valid" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "Algoritma yang ditentukan tidak valid" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index 3ac1418b1..48837431c 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -49,14 +49,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "L'algoritmo specificato non è valido" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "L'algoritmo specificato non è valido" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Nessun account attivo trovato con queste credenziali" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index 49704c66a..0b6df170c 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -47,14 +47,14 @@ msgstr "" "알 수 없는 타입 '{}', 'leeway' 값은 반드시 int, float 또는 timedelta 타입이어" "야 합니다." -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "잘못된 알고리즘이 지정되었습니다" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "유효하지 않거나 만료된 토큰" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "잘못된 알고리즘이 지정되었습니다" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index 1d0598b14..f24fc31e7 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -45,14 +45,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token is niet geldig of verlopen" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Geen actief account gevonden voor deze gegevens" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index 84b499a79..89212095c 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -44,14 +44,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token jest niepoprawny lub wygasł" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index 88d1a71d3..36e2e1da3 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -46,14 +46,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "Algoritmo inválido especificado" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "O token é inválido ou expirado" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "Algoritmo inválido especificado" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po index 4b6a1bf6b..3a8d5d036 100644 --- a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -14,7 +14,9 @@ msgstr "" #: authentication.py:78 msgid "Authorization header must contain two space-delimited values" -msgstr "Header-ul(antetul) de autorizare trebuie să conțină două valori separate prin spațiu" +msgstr "" +"Header-ul(antetul) de autorizare trebuie să conțină două valori separate " +"prin spațiu" #: authentication.py:104 msgid "Given token not valid for any token type" @@ -44,16 +46,17 @@ msgstr "Trebuie să aveți instalată criptografia pentru a utiliza {}." msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -"Tipul '{}' nu este recunoscut, 'leeway' trebuie să fie de tip int, float sau timedelta." - -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "Algoritm nevalid specificat" +"Tipul '{}' nu este recunoscut, 'leeway' trebuie să fie de tip int, float sau " +"timedelta." -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token nu este valid sau a expirat" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "Algoritm nevalid specificat" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" @@ -62,7 +65,8 @@ msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." -msgstr "Setarea '{}' a fost ștearsă. Referați la '{}' pentru setări disponibile." +msgstr "" +"Setarea '{}' a fost ștearsă. Referați la '{}' pentru setări disponibile." #: token_blacklist/admin.py:68 msgid "jti" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index 18f60a8b2..02da98bfd 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -50,14 +50,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Токен недействителен или просрочен" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Не найдено активной учетной записи с указанными данными" diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.mo index 5370a8829e94f24ea2060ed3e2746f06d8d1336b..5c75a354dc1c100459f1402076e23b3178887f86 100644 GIT binary patch delta 15 WcmaDU_)>5~JS$Ui+2%yn4rTx{)&-aV delta 15 WcmaDU_)>5~JS$Ub@#aL<4rTx{Vg-i) diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po index d9e754e92..6e12ed405 100644 --- a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -14,8 +14,7 @@ msgstr "" #: authentication.py:78 msgid "Authorization header must contain two space-delimited values" -msgstr "" -"Auktoriseringshuvudet måste innehålla två mellanslagsavgränsade värden" +msgstr "Auktoriseringshuvudet måste innehålla två mellanslagsavgränsade värden" #: authentication.py:104 msgid "Given token not valid for any token type" @@ -46,14 +45,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "Ogiltig algoritm har angetts" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token är ogiltig eller har löpt ut" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "Ogiltig algoritm har angetts" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" @@ -63,8 +62,7 @@ msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "" -"Inställningen '{}' har tagits bort. Se '{}' för tillgängliga " -"inställningar" +"Inställningen '{}' har tagits bort. Se '{}' för tillgängliga inställningar" #: token_blacklist/admin.py:68 msgid "jti" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 4407447d4..751e0312b 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -47,14 +47,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "Geçersiz algoritma belirtildi" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Token geçersiz veya süresi geçmiş" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "Geçersiz algoritma belirtildi" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index f23d49e79..838654c06 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -48,14 +48,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "Вказаний невірний алгоритм" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "Токен некоректний або термін його дії вичерпаний" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "Вказаний невірний алгоритм" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "Не знайдено жодного облікового запису по наданих облікових даних" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index fbfa3b842..443106e1d 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -48,14 +48,14 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:147 -msgid "Invalid algorithm specified" -msgstr "指定的算法无效" - -#: backends.py:149 exceptions.py:38 tokens.py:44 +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" msgstr "令牌无效或已过期" +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "指定的算法无效" + #: serializers.py:30 msgid "No active account found with the given credentials" msgstr "找不到指定凭据对应的有效用户" From 6c03c4ea547ce973b16614247cc46cb41bb7223b Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Mon, 10 Oct 2022 11:18:45 -0400 Subject: [PATCH 055/171] Revert 605 (#629) --- rest_framework_simplejwt/authentication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index fd26bdb06..15767cddd 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -89,7 +89,7 @@ def get_validated_token(self, raw_token): messages = [] for AuthToken in api_settings.AUTH_TOKEN_CLASSES: try: - return AuthToken(raw_token, api_settings.VERIFYING_KEY is not None) + return AuthToken(raw_token) except TokenError as e: messages.append( { From b11e1d0a358d523956613c3b732aa3bf28b80b4d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 03:35:58 +0900 Subject: [PATCH 056/171] [pre-commit.ci] pre-commit autoupdate (#630) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c4df7495d..0e51e0cef 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '22.8.0' + rev: '22.10.0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v2.38.2' + rev: 'v3.1.0' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From bd4c6ce7e9cd884d13dd477bf5c16e21a4031873 Mon Sep 17 00:00:00 2001 From: Boseong Choi <31615733+cbscsm@users.noreply.github.com> Date: Fri, 21 Oct 2022 01:54:31 +0900 Subject: [PATCH 057/171] [Docs] Fix typo in blacklist_app.rst (#593) * Fix typo in blacklist_app.rst `TokenBlackListView` -> `TokenBlacklistView` * Append CHANGELOG Co-authored-by: Andrew-Chen-Wang --- CHANGELOG.md | 7 +++++++ docs/blacklist_app.rst | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b13e8884..5a04a8f8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ ## Unreleased +## Version 5.2.2 + +Major security release + +* Revert #605 in https://github.com/jazzband/djangorestframework-simplejwt/pull/629 +* Fix typo in blacklist_app.rst by @cbscsm in https://github.com/jazzband/djangorestframework-simplejwt/pull/593 + ## Version 5.2.1 * Add Swedish translations by @PasinduPrabhashitha in https://github.com/jazzband/djangorestframework-simplejwt/pull/579 diff --git a/docs/blacklist_app.rst b/docs/blacklist_app.rst index f6c6ba2f1..5b65a7ba0 100644 --- a/docs/blacklist_app.rst +++ b/docs/blacklist_app.rst @@ -46,7 +46,7 @@ subclass instance and calling the instance's ``blacklist`` method: This will create unique outstanding token and blacklist records for the token's "jti" claim or whichever claim is specified by the ``JTI_CLAIM`` setting. -In a ``urls.py`` file, you can also include a route for ``TokenBlackListView``: +In a ``urls.py`` file, you can also include a route for ``TokenBlacklistView``: .. code-block:: python From cc96fd6d347c799f9ce324ba2b4975e4e9a1ddf9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 15 Nov 2022 10:37:38 +0900 Subject: [PATCH 058/171] [pre-commit.ci] pre-commit autoupdate (#641) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.1.0 → v3.2.2](https://github.com/asottile/pyupgrade/compare/v3.1.0...v3.2.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0e51e0cef..d61acf083 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v3.1.0' + rev: 'v3.2.2' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From f94e409d4d686cc8f8a7acdaa70f5d73cb803ec1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 4 Dec 2022 13:55:43 +0900 Subject: [PATCH 059/171] [pre-commit.ci] pre-commit autoupdate (#648) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.3.0 → v4.4.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.4.0) - [github.com/pre-commit/pre-commit-hooks: v4.3.0 → v4.4.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.4.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d61acf083..ebba358bb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.3.0' + rev: 'v4.4.0' hooks: - id: check-merge-conflict - repo: https://github.com/asottile/yesqa @@ -18,7 +18,7 @@ repos: - id: black language_version: python3 # Should be a command that runs python3.6+ - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.3.0' + rev: 'v4.4.0' hooks: - id: end-of-file-fixer exclude: >- From 51253820692e82437fff7721d2082801a47b99f0 Mon Sep 17 00:00:00 2001 From: UP Date: Sun, 4 Dec 2022 05:56:17 +0100 Subject: [PATCH 060/171] Added Slovenian translations (#645) * Slovenian translations * Updated year --- .../locale/sl/LC_MESSAGES/django.mo | Bin 0 -> 2525 bytes .../locale/sl/LC_MESSAGES/django.po | 117 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.mo create mode 100644 rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..a5c125a2d8052dd5efdc29a7a186989910c3de9b GIT binary patch literal 2525 zcmZvc$&Va06vj;mOBzTZY+;cwilRxRsm>-v(IkVikc1J*qzOHU<$&B(ue;stvRk&R zCNohG7j8sCNZh%HJ14?rB90)DGYE+T2M+uJ9QbTk^-Ls6UHvO>&(H6De!uPC{SCwO z3f|Z8{)zVx-tQj4AD(l&7&{A|2N%K5z{B8O@HOxOcmn(fybd0GG}&?BKD56APlDfq zFM|)7{=dQJ(Eb;E0o=Pg@gNxNo(4JC2Uoxfd=~r>+zb8!9tD2~JK(;@5?=*jk{tpu z#EyVhah5Ll4%)XKXKWeV0*`^ao?z?^@FaK~d>{M-`~u|QAK;7Nt|#FWcmNEsdJhc# zPr=~-ZSVm2H5mNA3v%$MhJS(YqP=GiV=sYg;PapYPl2C#Lrf78wmc5}vp>Q__50`Z3pr`;8fKW4V$;^0Fj$Mb;Qjlfo+4kOd!NiqIQPe^|s;bQ%(B z1ke1q#P*cSp`?PX8ZL4VOF(Wa?O~wOMcUPmiI3tg@Tef|rBIIb(YtW#_5ye0z0@N< z7LE@HzE~;J()8$AEu<0yMeSnOW&L=}XfanpmeC&FoJs823|>$o zpDO8m({4hEz#%Y}ax>D1craTz>?otJLz%}UG;4yFn7zHv!~L?|tC<%gms|@y>(=0; zJ31xK+aNHqy|ZVNJI#!r|>C#DoTS*h3TM-HUud5v_}jg`}SW(mzZxklHWu zp)$e;MFcfKN?vr?T0DO6B4sso1a-u;vX4xajEx0Sp4*L?HzO-%;|(lvUMK|@kuZdj z-@4spNr~{AR0=!~2nT2a!vvC~hTEN6-) z>%Mb?X2$yLnj6U?yHJf>);CMM)4QJCpjrkC+1t=Qx~>Z6v%VGDDdCM>;%jywH1Aoe zbAEOfP=%gzqY|3x=B9iLYxJlRBg*H&*c4(ZJMD zGcS;~8W%$w=j9?-X6p`V$sI>P9FjLRC0mtPH3}ohqpt<-yyW-qkvCfKfu&7YaHub+ z7wDF?nvkBjDe=M#i1kc?FsJDprfX6Yh(+^Ff%`Kc+@Y}Cv=-SaMseXrSPEt6>KeK77<lXkjlcCa?sHkYbI(Sf}d>djpgWZVKm-0=O$s zW2}L!%px}BKO_?6w4*2mW$mm=Z8(xLL=psBn|E)g{$tSuuc_22F_s2!6A3|8 eNwU~kx)!>qMnUHg1~&s1&KSgx&seG2ZPF*x^ literal 0 HcmV?d00001 diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po new file mode 100644 index 000000000..b71388344 --- /dev/null +++ b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po @@ -0,0 +1,117 @@ +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , 2022. +msgid "" +msgstr "" +"Project-Id-Version: djangorestframework_simplejwt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-11-19 20:46+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: Urban Prevc \n" +"Language-Team: \n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: authentication.py:78 +msgid "Authorization header must contain two space-delimited values" +msgstr "Glava 'Authorization' mora vsebovati dve vrednosti, ločeni s presledkom" + +#: authentication.py:104 +msgid "Given token not valid for any token type" +msgstr "Podan žeton ni veljaven za nobeno vrsto žetona" + +#: authentication.py:116 authentication.py:143 +msgid "Token contained no recognizable user identification" +msgstr "Žeton ni vseboval prepoznavne identifikacije uporabnika" + +#: authentication.py:121 +msgid "User not found" +msgstr "Uporabnik ni najden" + +#: authentication.py:124 +msgid "User is inactive" +msgstr "Uporabnik je neaktiven" + +#: backends.py:67 +msgid "Unrecognized algorithm type '{}'" +msgstr "Neprepoznana vrsta algoritma'{}'" + +#: backends.py:73 +msgid "You must have cryptography installed to use {}." +msgstr "Za uporabo '{}' je potrebna namestitev 'cryptography'." + +#: backends.py:88 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" +"Neprepoznana vrsta '{}', 'leeway' mora biti vrste int, float ali timedelta." + +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +msgid "Token is invalid or expired" +msgstr "Žeton je neveljaven ali potekel" + +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "Naveden algoritem je neveljaven" + +#: serializers.py:30 +msgid "No active account found with the given credentials" +msgstr "Aktiven račun s podanimi poverilnicami ni najden" + +#: settings.py:70 +msgid "" +"The '{}' setting has been removed. Please refer to '{}' for available " +"settings." +msgstr "" +"Nastavitev '{}' je bila odstranjena. Prosimo, oglejte si '{}' za razpoložljive nastavitve." + +#: token_blacklist/admin.py:68 +msgid "jti" +msgstr "jti" + +#: token_blacklist/admin.py:74 +msgid "user" +msgstr "uporabnik" + +#: token_blacklist/admin.py:80 +msgid "created at" +msgstr "ustvarjen ob" + +#: token_blacklist/admin.py:86 +msgid "expires at" +msgstr "poteče ob" + +#: token_blacklist/apps.py:7 +msgid "Token Blacklist" +msgstr "Črni seznam žetonov" + +#: tokens.py:30 +msgid "Cannot create token with no type or lifetime" +msgstr "Ni mogoče ustvariti žetona brez vrste ali življenjske dobe" + +#: tokens.py:102 +msgid "Token has no id" +msgstr "Žetonu manjka id" + +#: tokens.py:115 +msgid "Token has no type" +msgstr "Žetonu manjka vrsta" + +#: tokens.py:118 +msgid "Token has wrong type" +msgstr "Žeton je napačne vrste" + +#: tokens.py:170 +msgid "Token has no '{}' claim" +msgstr "Žeton nima '{}' zahtevka" + +#: tokens.py:175 +msgid "Token '{}' claim has expired" +msgstr "'{}' zahtevek žetona je potekel" + +#: tokens.py:230 +msgid "Token is blacklisted" +msgstr "Žeton je na črnem seznamu" From 317ee9a40c9d8237d11edd90bca8067cdada0a89 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 04:09:58 +0900 Subject: [PATCH 061/171] [pre-commit.ci] pre-commit autoupdate (#652) --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ebba358bb..1c4e34506 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '22.10.0' + rev: '22.12.0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v3.2.2' + rev: 'v3.3.1' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] From 9fc9b158444c588923b0c3f3798ba9a766ab6cf1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 20 Dec 2022 16:24:26 +0900 Subject: [PATCH 062/171] [pre-commit.ci] pre-commit autoupdate (#655) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pycqa/isort: 5.10.1 → v5.11.3](https://github.com/pycqa/isort/compare/5.10.1...v5.11.3) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1c4e34506..df732705e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,7 +8,7 @@ repos: hooks: - id: yesqa - repo: https://github.com/pycqa/isort - rev: '5.10.1' + rev: 'v5.11.3' hooks: - id: isort args: ["--profile", "black"] From 668f47e5f19433cb8f29bb03bfa0ba0e8a8aaccf Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Tue, 20 Dec 2022 02:24:40 -0500 Subject: [PATCH 063/171] Rename de_CH to DE (Fixes #614) (#653) --- .../locale/{de_CH => de}/LC_MESSAGES/django.mo | Bin .../locale/{de_CH => de}/LC_MESSAGES/django.po | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename rest_framework_simplejwt/locale/{de_CH => de}/LC_MESSAGES/django.mo (100%) rename rest_framework_simplejwt/locale/{de_CH => de}/LC_MESSAGES/django.po (100%) diff --git a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.mo similarity index 100% rename from rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.mo rename to rest_framework_simplejwt/locale/de/LC_MESSAGES/django.mo diff --git a/rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po similarity index 100% rename from rest_framework_simplejwt/locale/de_CH/LC_MESSAGES/django.po rename to rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po From 9adb156977d27af95356ee8321bed9b8003a6fcb Mon Sep 17 00:00:00 2001 From: Josh Thomas Date: Tue, 17 Jan 2023 09:33:40 -0600 Subject: [PATCH 064/171] Add Python 3.11 to CI, tox, and trove classifiers (#636) * add python 3.11 to CI, tox, and trove classifiers * update CHANGELOG * python 3.11 only officially supported by Django 4.1+ --- .github/workflows/test.yml | 2 +- CHANGELOG.md | 2 ++ setup.py | 1 + tox.ini | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6bbf2928d..44726a3b0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: fail-fast: false max-parallel: 5 matrix: - python-version: ['3.7', '3.8', '3.9', '3.10'] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] django-version: ['2.2', '3.2', '4.0', '4.1', 'main'] drf-version: ['3.10', '3.11', '3.12', '3.13'] exclude: diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a04a8f8b..196f48d1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Unreleased +* Added support for Python 3.11 by @joshuadavidthomas in https://github.com/jazzband/djangorestframework-simplejwt/pull/636. + ## Version 5.2.2 Major security release diff --git a/setup.py b/setup.py index 3314e4bc2..bf9a2370e 100755 --- a/setup.py +++ b/setup.py @@ -81,6 +81,7 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Internet :: WWW/HTTP", ], ) diff --git a/tox.ini b/tox.ini index 3a074d43d..1b1a6baaf 100644 --- a/tox.ini +++ b/tox.ini @@ -3,6 +3,7 @@ envlist= py{37,38,39}-dj22-drf310-pyjwt{171,2}-tests py{37,38,39,310}-dj{22,32}-drf{311,312,313}-pyjwt{171,2}-tests py{38,39,310}-dj{40,41,main}-drf313-pyjwt{171,2}-tests + py311-dj{41,main}-drf313-pyjwt{171,2}-tests docs [gh-actions] @@ -11,6 +12,7 @@ python= 3.8: py38, docs 3.9: py39 3.10: py310 + 3.11: py311 [gh-actions:env] DJANGO= From b959771be0028180411b5a9234e57d850cd5751f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 24 Jan 2023 02:33:17 +0900 Subject: [PATCH 065/171] [pre-commit.ci] pre-commit autoupdate (#657) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pycqa/isort: v5.11.3 → 5.11.4](https://github.com/pycqa/isort/compare/v5.11.3...5.11.4) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index df732705e..6b9b0cc54 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,7 +8,7 @@ repos: hooks: - id: yesqa - repo: https://github.com/pycqa/isort - rev: 'v5.11.3' + rev: '5.11.4' hooks: - id: isort args: ["--profile", "black"] From e67944ad8199ae02515dd46a2ba7700890ee1d31 Mon Sep 17 00:00:00 2001 From: Jannes Blobel <72493222+jannesblobel@users.noreply.github.com> Date: Sat, 28 Jan 2023 20:03:20 +0100 Subject: [PATCH 066/171] Add Inlang to enable community translations / make the contribution of translations easier (#662) * init inlang.config.js The inlang config has to exist at the root of the repository. See inlang/inlang#258. * init th en. pot file * Create po file as reference language. Add instead of a pot file * remove whitespace right after LC_MESSAGES. * update config and remove en files * update inlang config * Update README.rst * fix title underline * Update README.rst --------- Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- README.rst | 6 ++++++ inlang.config.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 inlang.config.js diff --git a/README.rst b/README.rst index 4df9d74c7..733f5e97b 100644 --- a/README.rst +++ b/README.rst @@ -26,3 +26,9 @@ Framework `__. For full documentation, visit `django-rest-framework-simplejwt.readthedocs.io `__. + + +Translations +------------ + +Contribute translations directly with PRs or via inlang https://inlang.com/editor/github.com/jazzband/djangorestframework-simplejwt diff --git a/inlang.config.js b/inlang.config.js new file mode 100644 index 000000000..c1de9f6bf --- /dev/null +++ b/inlang.config.js @@ -0,0 +1,47 @@ +// filename: inlang.config.js + +export async function defineConfig(env) { + // importing a plugin + const plugin = await env.$import( + "https://cdn.jsdelivr.net/gh/jannesblobel/inlang-plugin-po@1/dist/index.js" + ); + + // most plugins require additional config, read the plugins documentation + // for the required config and correct usage. + const pluginConfig = { + pathPattern: + "./rest_framework_simplejwt/locale/{language}/LC_MESSAGES/django.po", + referenceResourcePath: null, + }; + + return { + referenceLanguage: "en", + languages: [ + "en", + "cs", + "de", + "es", + "es_AR", + "es_CL", + "fa_IR", + "fr", + "id_ID", + "it_IT", + "ko_KR", + "nl_NL", + "pl_PL", + "pt_BR", + "ro", + "ru_RU", + "sl", + "sv", + "tr", + "uk_UA", + "zh_Hans", + ], + readResources: (args) => + plugin.readResources({ ...args, ...env, pluginConfig }), + writeResources: (args) => + plugin.writeResources({ ...args, ...env, pluginConfig }), + }; +} From 063e5a2ce16a3a632a17cdf05e7b3af03f331e34 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 5 Feb 2023 01:35:59 +0900 Subject: [PATCH 067/171] [pre-commit.ci] pre-commit autoupdate (#666) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pycqa/isort: 5.11.4 → 5.12.0](https://github.com/pycqa/isort/compare/5.11.4...5.12.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6b9b0cc54..9363708a8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,7 +8,7 @@ repos: hooks: - id: yesqa - repo: https://github.com/pycqa/isort - rev: '5.11.4' + rev: '5.12.0' hooks: - id: isort args: ["--profile", "black"] From b0b8d1eefeeb35a3d05709f4d88b69cf01614338 Mon Sep 17 00:00:00 2001 From: Youngkwang Yang Date: Tue, 14 Feb 2023 10:24:44 +0900 Subject: [PATCH 068/171] Update docs on serializer customization (#668) * Update simplejwt settings in * Update documentation on customizing token claims. --- docs/customizing_token_claims.rst | 12 +++++- docs/settings.rst | 66 +++++++++++++++++-------------- 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/docs/customizing_token_claims.rst b/docs/customizing_token_claims.rst index a763f0f4b..e59156903 100644 --- a/docs/customizing_token_claims.rst +++ b/docs/customizing_token_claims.rst @@ -25,8 +25,16 @@ generated by the ``TokenObtainPairView``: return token - class MyTokenObtainPairView(TokenObtainPairView): - serializer_class = MyTokenObtainPairSerializer +.. code-block:: python + + # Django project settings.py + ... + + SIMPLE_JWT = { + # It will work instead of the default serializer(TokenObtainPairSerializer). + "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.MyTokenObtainPairSerializer", + # ... + } Note that the example above will cause the customized claims to be present in both refresh *and* access tokens which are generated by the view. This follows diff --git a/docs/settings.rst b/docs/settings.rst index 3f89c21c9..f892ea63d 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -14,35 +14,43 @@ Some of Simple JWT's behavior can be customized through settings variables in ... SIMPLE_JWT = { - 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5), - 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), - 'ROTATE_REFRESH_TOKENS': False, - 'BLACKLIST_AFTER_ROTATION': False, - 'UPDATE_LAST_LOGIN': False, - - 'ALGORITHM': 'HS256', - 'SIGNING_KEY': SECRET_KEY, - 'VERIFYING_KEY': None, - 'AUDIENCE': None, - 'ISSUER': None, - 'JWK_URL': None, - 'LEEWAY': 0, - - 'AUTH_HEADER_TYPES': ('Bearer',), - 'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION', - 'USER_ID_FIELD': 'id', - 'USER_ID_CLAIM': 'user_id', - 'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule', - - 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), - 'TOKEN_TYPE_CLAIM': 'token_type', - 'TOKEN_USER_CLASS': 'rest_framework_simplejwt.models.TokenUser', - - 'JTI_CLAIM': 'jti', - - 'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp', - 'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5), - 'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1), + "ACCESS_TOKEN_LIFETIME": timedelta(minutes=5), + "REFRESH_TOKEN_LIFETIME": timedelta(days=1), + "ROTATE_REFRESH_TOKENS": False, + "BLACKLIST_AFTER_ROTATION": False, + "UPDATE_LAST_LOGIN": False, + + "ALGORITHM": "HS256", + "SIGNING_KEY": settings.SECRET_KEY, + "VERIFYING_KEY": "", + "AUDIENCE": None, + "ISSUER": None, + "JSON_ENCODER": None, + "JWK_URL": None, + "LEEWAY": 0, + + "AUTH_HEADER_TYPES": ("Bearer",), + "AUTH_HEADER_NAME": "HTTP_AUTHORIZATION", + "USER_ID_FIELD": "id", + "USER_ID_CLAIM": "user_id", + "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule", + + "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), + "TOKEN_TYPE_CLAIM": "token_type", + "TOKEN_USER_CLASS": "rest_framework_simplejwt.models.TokenUser", + + "JTI_CLAIM": "jti", + + "SLIDING_TOKEN_REFRESH_EXP_CLAIM": "refresh_exp", + "SLIDING_TOKEN_LIFETIME": timedelta(minutes=5), + "SLIDING_TOKEN_REFRESH_LIFETIME": timedelta(days=1), + + "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainPairSerializer", + "TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSerializer", + "TOKEN_VERIFY_SERIALIZER": "rest_framework_simplejwt.serializers.TokenVerifySerializer", + "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer", + "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer", + "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer", } Above, the default values for these settings are shown. From 60ab226db399b32d248d0b7e763560f30aa40c47 Mon Sep 17 00:00:00 2001 From: Matt Seymour Date: Sun, 26 Feb 2023 16:14:18 +0000 Subject: [PATCH 069/171] Fixes #676 - Remove reference to django2.2 (#677) * Fixes #676 - Remove reference to django2.2 Support for django 2.2 has come and gone. Let's move forwards. Commit removes references of django 2.2 as well as removing compatibility code found in compat.py. * Remove reference to django.core.urlresolvers (depricated django 1.10) * Remove CallableBool Tests have been update to reflect code changes. * Remove Django 2.2 from CI --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- .github/workflows/test.yml | 7 +--- Makefile | 1 - rest_framework_simplejwt/compat.py | 55 ------------------------------ rest_framework_simplejwt/models.py | 5 ++- setup.py | 1 - tests/test_integration.py | 2 +- tests/utils.py | 2 +- tox.ini | 2 -- 8 files changed, 5 insertions(+), 70 deletions(-) delete mode 100644 rest_framework_simplejwt/compat.py diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 44726a3b0..eaa9315e1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,13 +16,8 @@ jobs: max-parallel: 5 matrix: python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] - django-version: ['2.2', '3.2', '4.0', '4.1', 'main'] + django-version: ['3.2', '4.0', '4.1'] drf-version: ['3.10', '3.11', '3.12', '3.13'] - exclude: - - python-version: '3.7' - django-version: 'main' - - python-version: '3.10' - django-version: '2.2' steps: - uses: actions/checkout@v2 diff --git a/Makefile b/Makefile index b095e0e9c..83b7a02e5 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,6 @@ build-docs: tests/* \ rest_framework_simplejwt/token_blacklist/* \ rest_framework_simplejwt/backends.py \ - rest_framework_simplejwt/compat.py \ rest_framework_simplejwt/exceptions.py \ rest_framework_simplejwt/settings.py \ rest_framework_simplejwt/state.py diff --git a/rest_framework_simplejwt/compat.py b/rest_framework_simplejwt/compat.py deleted file mode 100644 index 463d472c5..000000000 --- a/rest_framework_simplejwt/compat.py +++ /dev/null @@ -1,55 +0,0 @@ -import warnings - -try: - from django.urls import reverse, reverse_lazy -except ImportError: - from django.core.urlresolvers import reverse, reverse_lazy # NOQA - - -class RemovedInDjango20Warning(DeprecationWarning): - pass - - -class CallableBool: # pragma: no cover - """ - An boolean-like object that is also callable for backwards compatibility. - """ - - do_not_call_in_templates = True - - def __init__(self, value): - self.value = value - - def __bool__(self): - return self.value - - def __call__(self): - warnings.warn( - "Using user.is_authenticated() and user.is_anonymous() as a method " - "is deprecated. Remove the parentheses to use it as an attribute.", - RemovedInDjango20Warning, - stacklevel=2, - ) - return self.value - - def __nonzero__(self): # Python 2 compatibility - return self.value - - def __repr__(self): - return "CallableBool(%r)" % self.value - - def __eq__(self, other): - return self.value == other - - def __ne__(self, other): - return self.value != other - - def __or__(self, other): - return bool(self.value or other) - - def __hash__(self): - return hash(self.value) - - -CallableFalse = CallableBool(False) -CallableTrue = CallableBool(True) diff --git a/rest_framework_simplejwt/models.py b/rest_framework_simplejwt/models.py index 234de73e3..a0a614efb 100644 --- a/rest_framework_simplejwt/models.py +++ b/rest_framework_simplejwt/models.py @@ -2,7 +2,6 @@ from django.db.models.manager import EmptyManager from django.utils.functional import cached_property -from .compat import CallableFalse, CallableTrue from .settings import api_settings @@ -95,11 +94,11 @@ def has_module_perms(self, module): @property def is_anonymous(self): - return CallableFalse + return False @property def is_authenticated(self): - return CallableTrue + return True def get_username(self): return self.username diff --git a/setup.py b/setup.py index bf9a2370e..7b34f4f36 100755 --- a/setup.py +++ b/setup.py @@ -68,7 +68,6 @@ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", - "Framework :: Django :: 2.2", "Framework :: Django :: 3.2", "Framework :: Django :: 4.0", "Framework :: Django :: 4.1", diff --git a/tests/test_integration.py b/tests/test_integration.py index 919a626dd..54786d87a 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1,8 +1,8 @@ from datetime import timedelta from django.contrib.auth import get_user_model +from django.urls import reverse -from rest_framework_simplejwt.compat import reverse from rest_framework_simplejwt.settings import api_settings from rest_framework_simplejwt.tokens import AccessToken diff --git a/tests/utils.py b/tests/utils.py index e0ffa58a1..c3d710a2e 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -3,9 +3,9 @@ from django.db import connection from django.db.migrations.executor import MigrationExecutor from django.test import TestCase, TransactionTestCase +from django.urls import reverse from rest_framework.test import APIClient -from rest_framework_simplejwt.compat import reverse from rest_framework_simplejwt.settings import api_settings diff --git a/tox.ini b/tox.ini index 1b1a6baaf..ce1b2eec4 100644 --- a/tox.ini +++ b/tox.ini @@ -16,7 +16,6 @@ python= [gh-actions:env] DJANGO= - 2.2: dj22 3.2: dj32 4.0: dj40 4.1: dj41 @@ -35,7 +34,6 @@ extras= setenv= PYTHONDONTWRITEBYTECODE=1 deps= - dj22: Django>=2.2,<2.3 dj32: Django>=3.2,<3.3 dj40: Django>=4.0,<4.1 dj41: Django>=4.1,<4.2 From 960ab2b49f70ea651bde326d599f888870f76292 Mon Sep 17 00:00:00 2001 From: HeejunShin <66953834+abel9851@users.noreply.github.com> Date: Tue, 7 Mar 2023 06:39:00 +0900 Subject: [PATCH 070/171] fix: rm unused serializers module in views.py (#681) Co-authored-by: heejunshin --- rest_framework_simplejwt/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/rest_framework_simplejwt/views.py b/rest_framework_simplejwt/views.py index fd5c66610..6232fc619 100644 --- a/rest_framework_simplejwt/views.py +++ b/rest_framework_simplejwt/views.py @@ -2,7 +2,6 @@ from rest_framework import generics, status from rest_framework.response import Response -from . import serializers from .authentication import AUTH_HEADER_TYPES from .exceptions import InvalidToken, TokenError from .settings import api_settings From 8258b5f1f8335c4c0db5891f96fdff930a9fd61a Mon Sep 17 00:00:00 2001 From: Thomas de Jong Date: Fri, 10 Mar 2023 11:38:58 +0100 Subject: [PATCH 071/171] feat: adding typehints (#683) Co-authored-by: Thomas de Jong --- rest_framework_simplejwt/authentication.py | 30 +++++--- rest_framework_simplejwt/backends.py | 28 +++---- rest_framework_simplejwt/exceptions.py | 13 +++- rest_framework_simplejwt/models.py | 57 ++++++++------ rest_framework_simplejwt/serializers.py | 33 ++++---- rest_framework_simplejwt/settings.py | 5 +- .../token_blacklist/admin.py | 47 ++++++----- .../management/commands/flushexpiredtokens.py | 2 +- .../token_blacklist/models.py | 4 +- rest_framework_simplejwt/tokens.py | 77 +++++++++++-------- rest_framework_simplejwt/utils.py | 13 ++-- rest_framework_simplejwt/views.py | 8 +- 12 files changed, 191 insertions(+), 126 deletions(-) diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index 15767cddd..715d42c17 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -1,16 +1,26 @@ +from typing import Optional, Set, Tuple, TypeVar + from django.contrib.auth import get_user_model +from django.contrib.auth.models import AbstractBaseUser from django.utils.translation import gettext_lazy as _ from rest_framework import HTTP_HEADER_ENCODING, authentication +from rest_framework.request import Request from .exceptions import AuthenticationFailed, InvalidToken, TokenError +from .models import TokenUser from .settings import api_settings +from .tokens import Token AUTH_HEADER_TYPES = api_settings.AUTH_HEADER_TYPES if not isinstance(api_settings.AUTH_HEADER_TYPES, (list, tuple)): AUTH_HEADER_TYPES = (AUTH_HEADER_TYPES,) -AUTH_HEADER_TYPE_BYTES = {h.encode(HTTP_HEADER_ENCODING) for h in AUTH_HEADER_TYPES} +AUTH_HEADER_TYPE_BYTES: Set[bytes] = { + h.encode(HTTP_HEADER_ENCODING) for h in AUTH_HEADER_TYPES +} + +AuthUser = TypeVar("AuthUser", AbstractBaseUser, TokenUser) class JWTAuthentication(authentication.BaseAuthentication): @@ -22,11 +32,11 @@ class JWTAuthentication(authentication.BaseAuthentication): www_authenticate_realm = "api" media_type = "application/json" - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.user_model = get_user_model() - def authenticate(self, request): + def authenticate(self, request: Request) -> Optional[Tuple[AuthUser, Token]]: header = self.get_header(request) if header is None: return None @@ -39,13 +49,13 @@ def authenticate(self, request): return self.get_user(validated_token), validated_token - def authenticate_header(self, request): + def authenticate_header(self, request: Request) -> str: return '{} realm="{}"'.format( AUTH_HEADER_TYPES[0], self.www_authenticate_realm, ) - def get_header(self, request): + def get_header(self, request: Request) -> bytes: """ Extracts the header containing the JSON web token from the given request. @@ -58,7 +68,7 @@ def get_header(self, request): return header - def get_raw_token(self, header): + def get_raw_token(self, header: bytes) -> Optional[bytes]: """ Extracts an unvalidated JSON web token from the given "Authorization" header value. @@ -81,7 +91,7 @@ def get_raw_token(self, header): return parts[1] - def get_validated_token(self, raw_token): + def get_validated_token(self, raw_token: bytes) -> Token: """ Validates an encoded JSON web token and returns a validated token wrapper object. @@ -106,7 +116,7 @@ def get_validated_token(self, raw_token): } ) - def get_user(self, validated_token): + def get_user(self, validated_token: Token) -> AuthUser: """ Attempts to find and return a user using the given validated token. """ @@ -132,7 +142,7 @@ class JWTStatelessUserAuthentication(JWTAuthentication): token provided in a request header without performing a database lookup to obtain a user instance. """ - def get_user(self, validated_token): + def get_user(self, validated_token: Token) -> AuthUser: """ Returns a stateless user object which is backed by the given validated token. @@ -148,7 +158,7 @@ def get_user(self, validated_token): JWTTokenUserAuthentication = JWTStatelessUserAuthentication -def default_user_authentication_rule(user): +def default_user_authentication_rule(user: AuthUser) -> bool: # Prior to Django 1.10, inactive users could be authenticated with the # default `ModelBackend`. As of Django 1.10, the `ModelBackend` # prevents inactive users from authenticating. App designers can still diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index da41528c3..fbe479982 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -1,12 +1,14 @@ import json +from collections.abc import Iterable from datetime import timedelta -from typing import Optional, Type, Union +from typing import Any, Dict, Optional, Type, Union import jwt from django.utils.translation import gettext_lazy as _ from jwt import InvalidAlgorithmError, InvalidTokenError, algorithms from .exceptions import TokenBackendError +from .tokens import Token from .utils import format_lazy try: @@ -32,15 +34,15 @@ class TokenBackend: def __init__( self, - algorithm, - signing_key=None, - verifying_key="", - audience=None, - issuer=None, - jwk_url: str = None, - leeway: Union[float, int, timedelta] = None, + algorithm: str, + signing_key: Optional[str] = None, + verifying_key: str = "", + audience: Union[str, Iterable, None] = None, + issuer: Optional[str] = None, + jwk_url: Optional[str] = None, + leeway: Union[float, int, timedelta, None] = None, json_encoder: Optional[Type[json.JSONEncoder]] = None, - ): + ) -> None: self._validate_algorithm(algorithm) self.algorithm = algorithm @@ -57,7 +59,7 @@ def __init__( self.leeway = leeway self.json_encoder = json_encoder - def _validate_algorithm(self, algorithm): + def _validate_algorithm(self, algorithm: str) -> None: """ Ensure that the nominated algorithm is recognized, and that cryptography is installed for those algorithms that require it @@ -91,7 +93,7 @@ def get_leeway(self) -> timedelta: ) ) - def get_verifying_key(self, token): + def get_verifying_key(self, token: Token) -> Optional[str]: if self.algorithm.startswith("HS"): return self.signing_key @@ -103,7 +105,7 @@ def get_verifying_key(self, token): return self.verifying_key - def encode(self, payload): + def encode(self, payload: Dict[str, Any]) -> str: """ Returns an encoded token for the given payload dictionary. """ @@ -125,7 +127,7 @@ def encode(self, payload): # For PyJWT >= 2.0.0a1 return token - def decode(self, token, verify=True): + def decode(self, token: Token, verify: bool = True) -> Dict[str, Any]: """ Performs a validation of the given token and returns its payload dictionary. diff --git a/rest_framework_simplejwt/exceptions.py b/rest_framework_simplejwt/exceptions.py index 47d03238c..882635215 100644 --- a/rest_framework_simplejwt/exceptions.py +++ b/rest_framework_simplejwt/exceptions.py @@ -1,3 +1,5 @@ +from typing import Any, Dict, Optional, Union + from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions, status @@ -11,7 +13,14 @@ class TokenBackendError(Exception): class DetailDictMixin: - def __init__(self, detail=None, code=None): + default_detail: str + default_code: str + + def __init__( + self, + detail: Union[Dict[str, Any], str, None] = None, + code: Optional[str] = None, + ) -> None: """ Builds a detail dictionary for the error to give more information to API users. @@ -26,7 +35,7 @@ def __init__(self, detail=None, code=None): if code is not None: detail_dict["code"] = code - super().__init__(detail_dict) + super().__init__(detail_dict) # type: ignore class AuthenticationFailed(DetailDictMixin, exceptions.AuthenticationFailed): diff --git a/rest_framework_simplejwt/models.py b/rest_framework_simplejwt/models.py index a0a614efb..437da1e47 100644 --- a/rest_framework_simplejwt/models.py +++ b/rest_framework_simplejwt/models.py @@ -1,9 +1,14 @@ +from typing import TYPE_CHECKING, Any, List, Optional, Union + from django.contrib.auth import models as auth_models from django.db.models.manager import EmptyManager from django.utils.functional import cached_property from .settings import api_settings +if TYPE_CHECKING: + from .tokens import Token + class TokenUser: """ @@ -22,87 +27,89 @@ class instead of a `User` model instance. Instances of this class act as _groups = EmptyManager(auth_models.Group) _user_permissions = EmptyManager(auth_models.Permission) - def __init__(self, token): + def __init__(self, token: "Token") -> None: self.token = token - def __str__(self): + def __str__(self) -> str: return f"TokenUser {self.id}" @cached_property - def id(self): + def id(self) -> Union[int, str]: return self.token[api_settings.USER_ID_CLAIM] @cached_property - def pk(self): + def pk(self) -> Union[int, str]: return self.id @cached_property - def username(self): + def username(self) -> str: return self.token.get("username", "") @cached_property - def is_staff(self): + def is_staff(self) -> bool: return self.token.get("is_staff", False) @cached_property - def is_superuser(self): + def is_superuser(self) -> bool: return self.token.get("is_superuser", False) - def __eq__(self, other): + def __eq__(self, other: object) -> bool: + if not isinstance(other, TokenUser): + return NotImplemented return self.id == other.id - def __ne__(self, other): + def __ne__(self, other: object) -> bool: return not self.__eq__(other) - def __hash__(self): + def __hash__(self) -> int: return hash(self.id) - def save(self): + def save(self) -> None: raise NotImplementedError("Token users have no DB representation") - def delete(self): + def delete(self) -> None: raise NotImplementedError("Token users have no DB representation") - def set_password(self, raw_password): + def set_password(self, raw_password: str) -> None: raise NotImplementedError("Token users have no DB representation") - def check_password(self, raw_password): + def check_password(self, raw_password: str) -> None: raise NotImplementedError("Token users have no DB representation") @property - def groups(self): + def groups(self) -> auth_models.Group: return self._groups @property - def user_permissions(self): + def user_permissions(self) -> auth_models.Permission: return self._user_permissions - def get_group_permissions(self, obj=None): + def get_group_permissions(self, obj: Optional[object] = None) -> set: return set() - def get_all_permissions(self, obj=None): + def get_all_permissions(self, obj: Optional[object] = None) -> set: return set() - def has_perm(self, perm, obj=None): + def has_perm(self, perm: str, obj: Optional[object] = None) -> bool: return False - def has_perms(self, perm_list, obj=None): + def has_perms(self, perm_list: List[str], obj: Optional[object] = None) -> bool: return False - def has_module_perms(self, module): + def has_module_perms(self, module: str) -> bool: return False @property - def is_anonymous(self): + def is_anonymous(self) -> bool: return False @property - def is_authenticated(self): + def is_authenticated(self) -> bool: return True - def get_username(self): + def get_username(self) -> str: return self.username - def __getattr__(self, attr): + def __getattr__(self, attr: str) -> Optional[Any]: """This acts as a backup attribute getter for custom claims defined in Token serializers.""" return self.token.get(attr, None) diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index 64213c722..e75e709c9 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -1,19 +1,24 @@ +from typing import Any, Dict, Optional, Type, TypeVar + from django.conf import settings from django.contrib.auth import authenticate, get_user_model -from django.contrib.auth.models import update_last_login +from django.contrib.auth.models import AbstractBaseUser, update_last_login from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions, serializers from rest_framework.exceptions import ValidationError +from .models import TokenUser from .settings import api_settings -from .tokens import RefreshToken, SlidingToken, UntypedToken +from .tokens import RefreshToken, SlidingToken, Token, UntypedToken + +AuthUser = TypeVar("AuthUser", AbstractBaseUser, TokenUser) if api_settings.BLACKLIST_AFTER_ROTATION: from .token_blacklist.models import BlacklistedToken class PasswordField(serializers.CharField): - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: kwargs.setdefault("style", {}) kwargs["style"]["input_type"] = "password" @@ -24,19 +29,19 @@ def __init__(self, *args, **kwargs): class TokenObtainSerializer(serializers.Serializer): username_field = get_user_model().USERNAME_FIELD - token_class = None + token_class: Optional[Type[Token]] = None default_error_messages = { "no_active_account": _("No active account found with the given credentials") } - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.fields[self.username_field] = serializers.CharField() self.fields["password"] = PasswordField() - def validate(self, attrs): + def validate(self, attrs: Dict[str, Any]) -> Dict[Any, Any]: authenticate_kwargs = { self.username_field: attrs[self.username_field], "password": attrs["password"], @@ -57,14 +62,14 @@ def validate(self, attrs): return {} @classmethod - def get_token(cls, user): - return cls.token_class.for_user(user) + def get_token(cls, user: AuthUser) -> Token: + return cls.token_class.for_user(user) # type: ignore class TokenObtainPairSerializer(TokenObtainSerializer): token_class = RefreshToken - def validate(self, attrs): + def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: data = super().validate(attrs) refresh = self.get_token(self.user) @@ -81,7 +86,7 @@ def validate(self, attrs): class TokenObtainSlidingSerializer(TokenObtainSerializer): token_class = SlidingToken - def validate(self, attrs): + def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: data = super().validate(attrs) token = self.get_token(self.user) @@ -99,7 +104,7 @@ class TokenRefreshSerializer(serializers.Serializer): access = serializers.CharField(read_only=True) token_class = RefreshToken - def validate(self, attrs): + def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: refresh = self.token_class(attrs["refresh"]) data = {"access": str(refresh.access_token)} @@ -127,7 +132,7 @@ class TokenRefreshSlidingSerializer(serializers.Serializer): token = serializers.CharField() token_class = SlidingToken - def validate(self, attrs): + def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: token = self.token_class(attrs["token"]) # Check that the timestamp in the "refresh_exp" claim has not @@ -144,7 +149,7 @@ def validate(self, attrs): class TokenVerifySerializer(serializers.Serializer): token = serializers.CharField() - def validate(self, attrs): + def validate(self, attrs: Dict[str, None]) -> Dict[Any, Any]: token = UntypedToken(attrs["token"]) if ( @@ -162,7 +167,7 @@ class TokenBlacklistSerializer(serializers.Serializer): refresh = serializers.CharField() token_class = RefreshToken - def validate(self, attrs): + def validate(self, attrs: Dict[str, Any]) -> Dict[Any, Any]: refresh = self.token_class(attrs["refresh"]) try: refresh.blacklist() diff --git a/rest_framework_simplejwt/settings.py b/rest_framework_simplejwt/settings.py index 1aeb48c47..55b300578 100644 --- a/rest_framework_simplejwt/settings.py +++ b/rest_framework_simplejwt/settings.py @@ -1,4 +1,5 @@ from datetime import timedelta +from typing import Any, Dict from django.conf import settings from django.test.signals import setting_changed @@ -59,7 +60,7 @@ class APISettings(_APISettings): # pragma: no cover - def __check_user_settings(self, user_settings): + def __check_user_settings(self, user_settings: Dict[str, Any]) -> Dict[str, Any]: SETTINGS_DOC = "https://django-rest-framework-simplejwt.readthedocs.io/en/latest/settings.html" for setting in REMOVED_SETTINGS: @@ -80,7 +81,7 @@ def __check_user_settings(self, user_settings): api_settings = APISettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS) -def reload_api_settings(*args, **kwargs): # pragma: no cover +def reload_api_settings(*args, **kwargs) -> None: # pragma: no cover global api_settings setting, value = kwargs["setting"], kwargs["value"] diff --git a/rest_framework_simplejwt/token_blacklist/admin.py b/rest_framework_simplejwt/token_blacklist/admin.py index b346ef5d9..a8b32ee11 100644 --- a/rest_framework_simplejwt/token_blacklist/admin.py +++ b/rest_framework_simplejwt/token_blacklist/admin.py @@ -1,8 +1,17 @@ +from datetime import datetime +from typing import Any, List, Optional, TypeVar + from django.contrib import admin +from django.contrib.auth.models import AbstractBaseUser +from django.db.models import QuerySet from django.utils.translation import gettext_lazy as _ +from rest_framework.request import Request +from ..models import TokenUser from .models import BlacklistedToken, OutstandingToken +AuthUser = TypeVar("AuthUser", AbstractBaseUser, TokenUser) + class OutstandingTokenAdmin(admin.ModelAdmin): list_display = ( @@ -17,7 +26,7 @@ class OutstandingTokenAdmin(admin.ModelAdmin): ) ordering = ("user",) - def get_queryset(self, *args, **kwargs): + def get_queryset(self, *args, **kwargs) -> QuerySet: qs = super().get_queryset(*args, **kwargs) return qs.select_related("user") @@ -25,16 +34,18 @@ def get_queryset(self, *args, **kwargs): # Read-only behavior defined below actions = None - def get_readonly_fields(self, *args, **kwargs): + def get_readonly_fields(self, *args, **kwargs) -> List[Any]: return [f.name for f in self.model._meta.fields] - def has_add_permission(self, *args, **kwargs): + def has_add_permission(self, *args, **kwargs) -> bool: return False - def has_delete_permission(self, *args, **kwargs): + def has_delete_permission(self, *args, **kwargs) -> bool: return False - def has_change_permission(self, request, obj=None): + def has_change_permission( + self, request: Request, obj: Optional[object] = None + ) -> bool: return request.method in ["GET", "HEAD"] and super().has_change_permission( request, obj ) @@ -57,34 +68,34 @@ class BlacklistedTokenAdmin(admin.ModelAdmin): ) ordering = ("token__user",) - def get_queryset(self, *args, **kwargs): + def get_queryset(self, *args, **kwargs) -> QuerySet: qs = super().get_queryset(*args, **kwargs) return qs.select_related("token__user") - def token_jti(self, obj): + def token_jti(self, obj: BlacklistedToken) -> str: return obj.token.jti - token_jti.short_description = _("jti") - token_jti.admin_order_field = "token__jti" + token_jti.short_description = _("jti") # type: ignore + token_jti.admin_order_field = "token__jti" # type: ignore - def token_user(self, obj): + def token_user(self, obj: BlacklistedToken) -> AuthUser: return obj.token.user - token_user.short_description = _("user") - token_user.admin_order_field = "token__user" + token_user.short_description = _("user") # type: ignore + token_user.admin_order_field = "token__user" # type: ignore - def token_created_at(self, obj): + def token_created_at(self, obj: BlacklistedToken) -> datetime: return obj.token.created_at - token_created_at.short_description = _("created at") - token_created_at.admin_order_field = "token__created_at" + token_created_at.short_description = _("created at") # type: ignore + token_created_at.admin_order_field = "token__created_at" # type: ignore - def token_expires_at(self, obj): + def token_expires_at(self, obj: BlacklistedToken) -> datetime: return obj.token.expires_at - token_expires_at.short_description = _("expires at") - token_expires_at.admin_order_field = "token__expires_at" + token_expires_at.short_description = _("expires at") # type: ignore + token_expires_at.admin_order_field = "token__expires_at" # type: ignore admin.site.register(BlacklistedToken, BlacklistedTokenAdmin) diff --git a/rest_framework_simplejwt/token_blacklist/management/commands/flushexpiredtokens.py b/rest_framework_simplejwt/token_blacklist/management/commands/flushexpiredtokens.py index 8340830a0..a268a422c 100644 --- a/rest_framework_simplejwt/token_blacklist/management/commands/flushexpiredtokens.py +++ b/rest_framework_simplejwt/token_blacklist/management/commands/flushexpiredtokens.py @@ -8,5 +8,5 @@ class Command(BaseCommand): help = "Flushes any expired tokens in the outstanding token list" - def handle(self, *args, **kwargs): + def handle(self, *args, **kwargs) -> None: OutstandingToken.objects.filter(expires_at__lte=aware_utcnow()).delete() diff --git a/rest_framework_simplejwt/token_blacklist/models.py b/rest_framework_simplejwt/token_blacklist/models.py index c84b8c4ae..e5058fd34 100644 --- a/rest_framework_simplejwt/token_blacklist/models.py +++ b/rest_framework_simplejwt/token_blacklist/models.py @@ -25,7 +25,7 @@ class Meta: ) ordering = ("user",) - def __str__(self): + def __str__(self) -> str: return "Token for {} ({})".format( self.user, self.jti, @@ -48,5 +48,5 @@ class Meta: "rest_framework_simplejwt.token_blacklist" not in settings.INSTALLED_APPS ) - def __str__(self): + def __str__(self) -> str: return f"Blacklisted token for {self.token.user}" diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 69dbc52e3..49eb48a5c 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -1,15 +1,23 @@ -from datetime import timedelta +from datetime import datetime, timedelta +from typing import TYPE_CHECKING, Any, Dict, Optional, TypeVar from uuid import uuid4 from django.conf import settings +from django.contrib.auth.models import AbstractBaseUser from django.utils.module_loading import import_string from django.utils.translation import gettext_lazy as _ from .exceptions import TokenBackendError, TokenError +from .models import TokenUser from .settings import api_settings from .token_blacklist.models import BlacklistedToken, OutstandingToken from .utils import aware_utcnow, datetime_from_epoch, datetime_to_epoch, format_lazy +if TYPE_CHECKING: + from .backends import TokenBackend + +AuthUser = TypeVar("AuthUser", AbstractBaseUser, TokenUser) + class Token: """ @@ -17,10 +25,10 @@ class Token: new JWT. """ - token_type = None - lifetime = None + token_type: Optional[str] = None + lifetime: Optional[timedelta] = None - def __init__(self, token=None, verify=True): + def __init__(self, token: Optional["Token"] = None, verify: bool = True) -> None: """ !!!! IMPORTANT !!!! MUST raise a TokenError with a user-facing error message if the given token is invalid, expired, or otherwise not safe @@ -56,31 +64,31 @@ def __init__(self, token=None, verify=True): # Set "jti" claim self.set_jti() - def __repr__(self): + def __repr__(self) -> str: return repr(self.payload) - def __getitem__(self, key): + def __getitem__(self, key: str): return self.payload[key] - def __setitem__(self, key, value): + def __setitem__(self, key: str, value: Any) -> None: self.payload[key] = value - def __delitem__(self, key): + def __delitem__(self, key: str) -> None: del self.payload[key] - def __contains__(self, key): + def __contains__(self, key: str) -> Any: return key in self.payload - def get(self, key, default=None): + def get(self, key: str, default: Optional[Any] = None) -> Any: return self.payload.get(key, default) - def __str__(self): + def __str__(self) -> str: """ Signs and returns a token as a base64 encoded string. """ return self.get_token_backend().encode(self.payload) - def verify(self): + def verify(self) -> None: """ Performs additional validation steps which were not performed when this token was decoded. This method is part of the "public" API to indicate @@ -105,7 +113,7 @@ def verify(self): self.verify_token_type() - def verify_token_type(self): + def verify_token_type(self) -> None: """ Ensures that the token type claim is present and has the correct value. """ @@ -117,7 +125,7 @@ def verify_token_type(self): if self.token_type != token_type: raise TokenError(_("Token has wrong type")) - def set_jti(self): + def set_jti(self) -> None: """ Populates the configured jti claim of a token with a string where there is a negligible probability that the same string will be chosen at a @@ -128,7 +136,12 @@ def set_jti(self): """ self.payload[api_settings.JTI_CLAIM] = uuid4().hex - def set_exp(self, claim="exp", from_time=None, lifetime=None): + def set_exp( + self, + claim: str = "exp", + from_time: Optional[datetime] = None, + lifetime: Optional[timedelta] = None, + ) -> None: """ Updates the expiration time of a token. @@ -143,7 +156,7 @@ def set_exp(self, claim="exp", from_time=None, lifetime=None): self.payload[claim] = datetime_to_epoch(from_time + lifetime) - def set_iat(self, claim="iat", at_time=None): + def set_iat(self, claim: str = "iat", at_time: Optional[datetime] = None) -> None: """ Updates the time at which the token was issued. @@ -155,7 +168,9 @@ def set_iat(self, claim="iat", at_time=None): self.payload[claim] = datetime_to_epoch(at_time) - def check_exp(self, claim="exp", current_time=None): + def check_exp( + self, claim: str = "exp", current_time: Optional[datetime] = None + ) -> None: """ Checks whether a timestamp value in the given claim has passed (since the given datetime value in `current_time`). Raises a TokenError with @@ -175,7 +190,7 @@ def check_exp(self, claim="exp", current_time=None): raise TokenError(format_lazy(_("Token '{}' claim has expired"), claim)) @classmethod - def for_user(cls, user): + def for_user(cls, user: AuthUser) -> "Token": """ Returns an authorization token for the given user that will be provided after authenticating the user's credentials. @@ -189,17 +204,17 @@ def for_user(cls, user): return token - _token_backend = None + _token_backend: Optional["TokenBackend"] = None @property - def token_backend(self): + def token_backend(self) -> "TokenBackend": if self._token_backend is None: self._token_backend = import_string( "rest_framework_simplejwt.state.token_backend" ) return self._token_backend - def get_token_backend(self): + def get_token_backend(self) -> "TokenBackend": # Backward compatibility. return self.token_backend @@ -212,14 +227,16 @@ class BlacklistMixin: membership in a token blacklist. """ + payload: Dict[str, Any] + if "rest_framework_simplejwt.token_blacklist" in settings.INSTALLED_APPS: - def verify(self, *args, **kwargs): + def verify(self, *args, **kwargs) -> None: self.check_blacklist() - super().verify(*args, **kwargs) + super().verify(*args, **kwargs) # type: ignore - def check_blacklist(self): + def check_blacklist(self) -> None: """ Checks if this token is present in the token blacklist. Raises `TokenError` if so. @@ -229,7 +246,7 @@ def check_blacklist(self): if BlacklistedToken.objects.filter(token__jti=jti).exists(): raise TokenError(_("Token is blacklisted")) - def blacklist(self): + def blacklist(self) -> BlacklistedToken: """ Ensures this token is included in the outstanding token list and adds it to the blacklist. @@ -249,11 +266,11 @@ def blacklist(self): return BlacklistedToken.objects.get_or_create(token=token) @classmethod - def for_user(cls, user): + def for_user(cls, user: AuthUser) -> Token: """ Adds this token to the outstanding token list. """ - token = super().for_user(user) + token = super().for_user(user) # type: ignore jti = token[api_settings.JTI_CLAIM] exp = token["exp"] @@ -273,7 +290,7 @@ class SlidingToken(BlacklistMixin, Token): token_type = "sliding" lifetime = api_settings.SLIDING_TOKEN_LIFETIME - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) if self.token is None: @@ -306,7 +323,7 @@ class RefreshToken(BlacklistMixin, Token): access_token_class = AccessToken @property - def access_token(self): + def access_token(self) -> AccessToken: """ Returns an access token created from this refresh token. Copies all claims present in this refresh token to the new access token except @@ -333,7 +350,7 @@ class UntypedToken(Token): token_type = "untyped" lifetime = timedelta(seconds=0) - def verify_token_type(self): + def verify_token_type(self) -> None: """ Untyped tokens do not verify the "token_type" claim. This is useful when performing general validation of a token's signature and other diff --git a/rest_framework_simplejwt/utils.py b/rest_framework_simplejwt/utils.py index f1c4d3ae3..f10b5e9f8 100644 --- a/rest_framework_simplejwt/utils.py +++ b/rest_framework_simplejwt/utils.py @@ -1,32 +1,33 @@ from calendar import timegm from datetime import datetime, timezone +from typing import Callable from django.conf import settings from django.utils.functional import lazy from django.utils.timezone import is_naive, make_aware -def make_utc(dt): +def make_utc(dt: datetime) -> datetime: if settings.USE_TZ and is_naive(dt): return make_aware(dt, timezone=timezone.utc) return dt -def aware_utcnow(): +def aware_utcnow() -> datetime: return make_utc(datetime.utcnow()) -def datetime_to_epoch(dt): +def datetime_to_epoch(dt: datetime) -> int: return timegm(dt.utctimetuple()) -def datetime_from_epoch(ts): +def datetime_from_epoch(ts: float) -> datetime: return make_utc(datetime.utcfromtimestamp(ts)) -def format_lazy(s, *args, **kwargs): +def format_lazy(s: str, *args, **kwargs) -> str: return s.format(*args, **kwargs) -format_lazy = lazy(format_lazy, str) +format_lazy: Callable = lazy(format_lazy, str) diff --git a/rest_framework_simplejwt/views.py b/rest_framework_simplejwt/views.py index 6232fc619..b250ff7a7 100644 --- a/rest_framework_simplejwt/views.py +++ b/rest_framework_simplejwt/views.py @@ -1,6 +1,8 @@ from django.utils.module_loading import import_string from rest_framework import generics, status +from rest_framework.request import Request from rest_framework.response import Response +from rest_framework.serializers import Serializer from .authentication import AUTH_HEADER_TYPES from .exceptions import InvalidToken, TokenError @@ -16,7 +18,7 @@ class TokenViewBase(generics.GenericAPIView): www_authenticate_realm = "api" - def get_serializer_class(self): + def get_serializer_class(self) -> Serializer: """ If serializer_class is set, use it directly. Otherwise get the class from settings. """ @@ -29,13 +31,13 @@ def get_serializer_class(self): msg = "Could not import serializer '%s'" % self._serializer_class raise ImportError(msg) - def get_authenticate_header(self, request): + def get_authenticate_header(self, request: Request) -> str: return '{} realm="{}"'.format( AUTH_HEADER_TYPES[0], self.www_authenticate_realm, ) - def post(self, request, *args, **kwargs): + def post(self, request: Request, *args, **kwargs) -> Response: serializer = self.get_serializer(data=request.data) try: From c88f46568c01f6ba87cf21acc8825353bfe25886 Mon Sep 17 00:00:00 2001 From: Thomas de Jong Date: Thu, 23 Mar 2023 16:17:53 +0100 Subject: [PATCH 072/171] Removing dj-22 and djmain from the tox config (#691) Co-authored-by: Thomas de Jong --- tox.ini | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tox.ini b/tox.ini index ce1b2eec4..83478cd38 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,8 @@ [tox] envlist= - py{37,38,39}-dj22-drf310-pyjwt{171,2}-tests - py{37,38,39,310}-dj{22,32}-drf{311,312,313}-pyjwt{171,2}-tests - py{38,39,310}-dj{40,41,main}-drf313-pyjwt{171,2}-tests - py311-dj{41,main}-drf313-pyjwt{171,2}-tests + py{37,38,39,310}-dj32-drf{311,312,313}-pyjwt{171,2}-tests + py{38,39,310}-dj{40,41}-drf313-pyjwt{171,2}-tests + py311-dj41-drf313-pyjwt{171,2}-tests docs [gh-actions] @@ -43,7 +42,6 @@ deps= drf313: djangorestframework>=3.13,<3.14 pyjwt171: pyjwt>=1.7.1,<1.8 pyjwt2: pyjwt>=2,<3 - djmain: https://github.com/django/django/archive/main.tar.gz allowlist_externals=make [testenv:docs] From f298efa860b4ef097d8448e1515c98d40e54a3e4 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Sun, 9 Apr 2023 02:51:18 -0400 Subject: [PATCH 073/171] Add DRF 3.14 Support (#623) * Add DRF 3.14 Support (fixes #622) * Remove Django main branch from test matrix * Add DRF 3.14 support to tox --------- Co-authored-by: Youngkwang Yang --- .github/workflows/test.yml | 2 +- tox.ini | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index eaa9315e1..41676e16c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,7 @@ jobs: matrix: python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] django-version: ['3.2', '4.0', '4.1'] - drf-version: ['3.10', '3.11', '3.12', '3.13'] + drf-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] steps: - uses: actions/checkout@v2 diff --git a/tox.ini b/tox.ini index 83478cd38..e5a276a40 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] envlist= - py{37,38,39,310}-dj32-drf{311,312,313}-pyjwt{171,2}-tests + py{37,38,39,310}-dj{32}-drf{311,312,313}-pyjwt{171,2}-tests py{38,39,310}-dj{40,41}-drf313-pyjwt{171,2}-tests - py311-dj41-drf313-pyjwt{171,2}-tests + py311-dj{41}-drf{313,314}-pyjwt{171,2}-tests docs [gh-actions] @@ -18,12 +18,12 @@ DJANGO= 3.2: dj32 4.0: dj40 4.1: dj41 - main: djmain DRF= 3.10: drf310 3.11: drf311 3.12: drf312 3.13: drf313 + 3.14: drf314 [testenv] commands = pytest {posargs:tests} --cov-append --cov-report=xml --cov=rest_framework_simplejwt @@ -40,6 +40,7 @@ deps= drf311: djangorestframework>=3.11,<3.12 drf312: djangorestframework>=3.12,<3.13 drf313: djangorestframework>=3.13,<3.14 + drf314: djangorestframework>=3.14,<3.15 pyjwt171: pyjwt>=1.7.1,<1.8 pyjwt2: pyjwt>=2,<3 allowlist_externals=make From ed7555189e1f4a3ecf80ec6df88ee282102d8334 Mon Sep 17 00:00:00 2001 From: kiraware <117554978+kiraware@users.noreply.github.com> Date: Thu, 18 May 2023 23:30:56 +0800 Subject: [PATCH 074/171] Update `django.po` for id translation (#685) * Update `django.po` for id translation * Update `django.mo` for Bahasa Indonesia (id) translations. --- .../locale/id_ID/LC_MESSAGES/django.mo | Bin 2333 -> 2374 bytes .../locale/id_ID/LC_MESSAGES/django.po | 11 ++++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.mo index 33f3f669f3431da664dc506d1a436c041642ec0d..c18aaf4a9bb1d90ad49228a3ec729eaa679c43b0 100644 GIT binary patch delta 248 zcmbO$bWCW%oqBsl28Jsv3=Fmm3=AS{3=AefItWNx0O@uhtqP{R~J418Hq` z1_mV{T@R#%fb=3D?Es{=0%>_5{S8Qq18Ff11_ntWtp}t9fwTvZmH^UGKpLdKn1jI% z%$Nog5CID8geo`(q)mbR=RleZNXv3EFbDu?4Is@7q%DCoP>R8J^GwDTW{m*<5MAe@ r)Wnj^{5)Nk#FA7i1tS9^LtO(ST_Ym}Lvt%*18oCC1B1;ntc)xGQ=TAC delta 206 zcmXZTtqQ_m7{&23w^yfWz6?LoKrk2u1&gvE3s%AC9e4pIi_x$q29tONW{ozR(K`^E zefv91zw;cAK1hX ww$b=f9V2XEAAkQdUy~xNC_;+#KRDx%`-V0AVt^UC7*r*q!pp(gx~If=If|eb6aWAK diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index 4cc7f58b9..f714d02b3 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -1,11 +1,15 @@ # This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , 2020. +# +# Translators: +# , 2020 +# Kira , 2023 msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-02-22 17:30+0100\n" -"Last-Translator: oon arfiandwi \n" +"PO-Revision-Date: 2023-03-09 08:14+0000\n" +"Last-Translator: Kira \n" "Language: id_ID\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -38,12 +42,13 @@ msgstr "Jenis algoritma tidak dikenal '{}'" #: backends.py:73 msgid "You must have cryptography installed to use {}." -msgstr "Anda harus memasang kriptografi untuk menggunakan {}." +msgstr "Anda harus memasang cryptography untuk menggunakan {}." #: backends.py:88 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" +"Tipe '{}' tidak dikenali, 'leeway' harus bertipe int, float, atau timedelta." #: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 msgid "Token is invalid or expired" From 523612e5a8093edad04a3faadedffdc6c49ff883 Mon Sep 17 00:00:00 2001 From: elam91 <59236577+elam91@users.noreply.github.com> Date: Thu, 18 May 2023 18:31:38 +0300 Subject: [PATCH 075/171] add he_IL to locale (#679) --- .../locale/he_IL/LC_MESSAGES/django.mo | Bin 0 -> 2768 bytes .../locale/he_IL/LC_MESSAGES/django.po | 118 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.mo create mode 100644 rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..ca0741422c67503b65133e1ac6dd2ca91688d132 GIT binary patch literal 2768 zcmZux&2Jk;6d#~`8EBz=l@C=Tl{Br?b@PEl;H+t2&fH;6SaE3#ry}^Ye2QJ(=@Ov}sjg8o3{oD8E&HMPhH}l)x zU2TTv6}+$G{R8h1-fthm51w})X6$X?3E&anr@%wNZ-B1>9{|UIe*w<}4?JT1#K1j} zo4|449pKBr2dVx~;B%1w0lom-z02YOAo-mDa$pHK32XqL1^x)!4g3{&6!<$Z2i)_h z#aDrF$%cSfVuyhrqLw`HBIM5=W9%$20UihLf1I&l;AP+h@N-}U`~gULj6Pxcm;#=L z90OkhewXTh0q%qRH}DPM?kBDNIFRbT1SHApY6U_@S22TJM3Y?4iBHBR$VpV9x{57V}Un>M?N$DvWQWY@Vm^OPqodw%2GF zL;0p(BtDIoxO|ZWJd_Xh);uQ~x*A666QNZY@TwG^jCidPYwm`D7AoL+G30SwxYF^Y zuWCw5k1q(nA!Bw*1VISPND3{v4(DaS7nQE^Amn$^CE-_)nXc9lUb?ERq{lu8xo|Z+0oGUVhOp7;&o`vO=b&1`C`_Wz0Gl+ zl}wq&qw5P*Gyde2xS-GYO=^n}w z);na{$xlZdP}v(?1(Ij0pPqS1JBo#Ybl z4yC6wAJ32F$8v1&`gqS?AIWOc!QXPy<;i-|O4cB(^JF`@lXQ4;H@R;#w|KIVw397} z*I@v08J}(ZtukzDaxzc4$!&7dNxsIyecEyZ9$Ta{Hk(kd@T8fv%?~_$$UUlwS*eufw2aPr6y(BsoufEW`gcReKLAQ{x)o zb|E!hHjxau>(+oM@40M~&_wuctRX7iF3Sip7Yi0a9?=3K7|ga|wm|{6Q3lm(KG8hO zBib}Ts-Yoka9@2JaL~o3?X>L>OdqLvCXMwh5u`{Qo0|o!WDT=w$eYAqAA7|2f33_I z3@mggb~+vDG_4`@?ScGh;op_JPw-*!4P zHn|P1_1&bsqeK(evMr=u*g$>Psu_;HixtLwEyxPk!bDakcFd1ufa;<6RZrP!Wn9dhY1KLJ2dN*mYezI`NdTP3xcd}vs E0#XrGuK)l5 literal 0 HcmV?d00001 diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po new file mode 100644 index 000000000..adf878bdf --- /dev/null +++ b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po @@ -0,0 +1,118 @@ +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , 2020. +msgid "" +msgstr "" +"Project-Id-Version: djangorestframework_simplejwt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n" +"%10==0 ? 2 : 3);\n" +"X-Generator: Poedit 3.2.2\n" + +#: authentication.py:78 +msgid "Authorization header must contain two space-delimited values" +msgstr "Authorization Header חייבת להכיל שני ערכים מופרדים ברווח" + +#: authentication.py:104 +msgid "Given token not valid for any token type" +msgstr "המזהה הנתון אינו תקף עבור אף סיווג" + +#: authentication.py:116 authentication.py:143 +msgid "Token contained no recognizable user identification" +msgstr "המזהה לא הכיל זיהוי משתמש שניתן לזהות" + +#: authentication.py:121 +msgid "User not found" +msgstr "משתמש לא נמצא" + +#: authentication.py:124 +msgid "User is inactive" +msgstr "המשתמש אינו פעיל" + +#: backends.py:67 +msgid "Unrecognized algorithm type '{}'" +msgstr "סוג אלגוריתם לא מזוהה '{}'" + +#: backends.py:73 +msgid "You must have cryptography installed to use {}." +msgstr "עליך להתקין קריפטוגרפיה כדי להשתמש ב-{}." + +#: backends.py:88 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" +"סוג לא מזוהה '{}', 'leeway' חייב להיות מסוג int, float או timedelta." + +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +msgid "Token is invalid or expired" +msgstr "המזהה אינו חוקי או שפג תוקפו" + +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "צוין אלגוריתם לא חוקי" + +#: serializers.py:30 +msgid "No active account found with the given credentials" +msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" + +#: settings.py:70 +msgid "" +"The '{}' setting has been removed. Please refer to '{}' for available " +"settings." +msgstr "" +"ההגדרה '{}' הוסרה. בבקשה קראו כאן: '{}' בשביל לראות הגדרות אפשרויות" + +#: token_blacklist/admin.py:68 +msgid "jti" +msgstr "jti" + +#: token_blacklist/admin.py:74 +msgid "user" +msgstr "משתמש" + +#: token_blacklist/admin.py:80 +msgid "created at" +msgstr "נוצר בשעה" + +#: token_blacklist/admin.py:86 +msgid "expires at" +msgstr "פג תוקף בשעה" + +#: token_blacklist/apps.py:7 +msgid "Token Blacklist" +msgstr "רשימה שחורה של מזהים" + +#: tokens.py:30 +msgid "Cannot create token with no type or lifetime" +msgstr "לא ניתן ליצור מזהה ללא סוג או אורך חיים" + +#: tokens.py:102 +msgid "Token has no id" +msgstr "למזהה אין מספר זיהוי" + +#: tokens.py:115 +msgid "Token has no type" +msgstr "למזהה אין סוג" + +#: tokens.py:118 +msgid "Token has wrong type" +msgstr "למזהה יש סוג לא נכון" + +#: tokens.py:170 +msgid "Token has no '{}' claim" +msgstr "למזהה אין '{}'" + +#: tokens.py:175 +msgid "Token '{}' claim has expired" +msgstr "מזהה '{}' פג תוקף" + +#: tokens.py:230 +msgid "Token is blacklisted" +msgstr "המזהה ברשימה השחורה." From aa077a4ca684005668d0f90df5fa5b332e8bb33d Mon Sep 17 00:00:00 2001 From: Mahdi Rahimi <31624047+mahdirahimi1999@users.noreply.github.com> Date: Thu, 18 May 2023 19:02:19 +0330 Subject: [PATCH 076/171] Updated translations for Persian (fa) language (#708) Co-authored-by: Mahdi --- .../locale/fa/LC_MESSAGES/django.mo | 0 .../locale/fa/LC_MESSAGES/django.po | 116 ++++++++++++++++++ .../locale/fa_IR/LC_MESSAGES/django.mo | Bin 2363 -> 2649 bytes .../locale/fa_IR/LC_MESSAGES/django.po | 4 +- 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo create mode 100644 rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo new file mode 100644 index 000000000..e69de29bb diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po new file mode 100644 index 000000000..513dc8ea7 --- /dev/null +++ b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po @@ -0,0 +1,116 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-05-07 21:35+0330\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Mahdi Rahimi \n" +"Language: fa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +#: authentication.py:88 +msgid "Authorization header must contain two space-delimited values" +msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا شده با فاصله باشد" + +#: authentication.py:114 +msgid "Given token not valid for any token type" +msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" + +#: authentication.py:126 authentication.py:153 +msgid "Token contained no recognizable user identification" +msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" + +#: authentication.py:131 +msgid "User not found" +msgstr "کاربر یافت نشد" + +#: authentication.py:134 +msgid "User is inactive" +msgstr "کاربر غیرفعال است" + +#: backends.py:69 +msgid "Unrecognized algorithm type '{}'" +msgstr "نوع الگوریتم ناشناخته '{}'" + +#: backends.py:75 +msgid "You must have cryptography installed to use {}." +msgstr "msgstr "نوع ناشناخته "{}"، leeway باید از نوع int، float یا timedelta باشد."" + +#: backends.py:90 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "" + +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:52 +msgid "Token is invalid or expired" +msgstr "توکن نامعتبر است یا منقضی شده است" + +#: backends.py:152 +msgid "Invalid algorithm specified" +msgstr "الگوریتم نامعتبر مشخص شده است" + +#: serializers.py:35 +msgid "No active account found with the given credentials" +msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" + +#: settings.py:71 +msgid "" +"The '{}' setting has been removed. Please refer to '{}' for available " +"settings." +msgstr "تنظیمات '{}' حذف شده است. لطفا به '{}' برای تنظیمات موجود مراجعه کنید." + +#: token_blacklist/admin.py:79 +msgid "jti" +msgstr "jti" + +#: token_blacklist/admin.py:85 +msgid "user" +msgstr "کاربر" + +#: token_blacklist/admin.py:91 +msgid "created at" +msgstr "زمان ایجاد" + +#: token_blacklist/admin.py:97 +msgid "expires at" +msgstr "زمان انقضا" + +#: token_blacklist/apps.py:7 +msgid "Token Blacklist" +msgstr "لیست سیاه توکن" + +#: tokens.py:38 +msgid "Cannot create token with no type or lifetime" +msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" + +#: tokens.py:110 +msgid "Token has no id" +msgstr "توکن id ندارد" + +#: tokens.py:123 +msgid "Token has no type" +msgstr "توکن نوع ندارد" + +#: tokens.py:126 +msgid "Token has wrong type" +msgstr "توکن نوع اشتباهی دارد" + +#: tokens.py:185 +msgid "Token has no '{}' claim" +msgstr "توکن دارای '{}' claim نمی‌باشد" + +#: tokens.py:190 +msgid "Token '{}' claim has expired" +msgstr "'{}' claim توکن منقضی شده" + +#: tokens.py:247 +msgid "Token is blacklisted" +msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.mo index 5af1970973fcbc9e108a82e3430326bc30369ceb..6731a91a948a2234262e714f4c1c4b2d9b348195 100644 GIT binary patch delta 793 zcmX}p&ubGw6u|LGn%36eCap^A;VFngw6zMwgBQVz3JM}f3m%qa+bpC>NH&2YQbk%1 zdJuwo(2EyaiyG222l3(|q97=OhuK=hKR}^3Z{qiD*FG}y*}VC&J8#}5gZ|kc$;3lL z?57=|t@@u%q zm|63ShkgeBMy3)Q8>dmopTphg;!dpL2+rYFY)8IBwlJTNpZP+!j^8kg@4Jn;h(~*j zxrQ|yDc)}maf}p>p`PFZ>d7wA=`9S<{s(I|gYt#zG_fPfCXt&6L(8q#s@3E0 z;of{(7~ANznxhIecMswHR;B4~()pg|`gtRVs$8X5zMprJwN zFF3-Xv8BPSsU;fA$^L`hkBSfXd|!9p@7+D$d+sy-8Y_Lp+h6((^K@7W6 z6elr)OKm;m7HuMjb{HDCi>J5|l=kom53!C1xZN#X-~-N6U(paRXTrmM%wifVXkGbe zuh(&b>tK(xf+@7l9AgR}F@f)B@B77Jbi*yj(Keh!`;asSsNal!#u&+_L>;jvHr$C3 z&S+P&6ZUX#XQj1CYq@p7!irM68P>r*(pqlC`AgE)c`;Ww%U_-p^W}_l>wi1X0sqCF OaQtBC%_+}D*8c(BHZG|E diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index f03fd4235..b66b58966 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -37,7 +37,7 @@ msgstr "نوع الگوریتم ناشناخته '{}'" #: backends.py:73 msgid "You must have cryptography installed to use {}." -msgstr "" +msgstr "برای استفاده از {} باید رمزنگاری را نصب کرده باشید." #: backends.py:88 msgid "" @@ -50,7 +50,7 @@ msgstr "توکن نامعتبر است یا منقضی شده است" #: backends.py:150 msgid "Invalid algorithm specified" -msgstr "" +msgstr "الگوریتم نامعتبر مشخص شده است" #: serializers.py:30 msgid "No active account found with the given credentials" From 605cec48b8d37b813e7f8a562c05c18067e5f664 Mon Sep 17 00:00:00 2001 From: Rodri <84244902+rodrq@users.noreply.github.com> Date: Wed, 21 Jun 2023 10:20:10 -0300 Subject: [PATCH 077/171] Update customizing_token_claims.rst (#714) In ""TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.MyTokenObtainPairSerializer"," replaced "rest_framework_simplejwt" to "my_app" to make it clearer that it should be a custom path, since the Django app folder having the same name as the library was confusing and hard to fix if copy and pasting in a hurry. --- docs/customizing_token_claims.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/customizing_token_claims.rst b/docs/customizing_token_claims.rst index e59156903..ad693386b 100644 --- a/docs/customizing_token_claims.rst +++ b/docs/customizing_token_claims.rst @@ -32,7 +32,7 @@ generated by the ``TokenObtainPairView``: SIMPLE_JWT = { # It will work instead of the default serializer(TokenObtainPairSerializer). - "TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.MyTokenObtainPairSerializer", + "TOKEN_OBTAIN_SERIALIZER": "my_app.serializers.MyTokenObtainPairSerializer", # ... } From 51d2b24caff7f503a3e270a4acaf47847a5e1429 Mon Sep 17 00:00:00 2001 From: Yaser Amiri Date: Wed, 21 Jun 2023 16:53:33 +0330 Subject: [PATCH 078/171] Added write_only=True for better doc generation (#699) * Added write_only=True for better doc generation Auto doc generators can perform better and generate more accurate docs by having this argument. Username field in TokenObtainSerializer and token in TokenVerifySerializer has been changed. * Added write_only=True to TokenBlacklistSerializer's refresh field --- rest_framework_simplejwt/serializers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index e75e709c9..3dc318687 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -38,7 +38,7 @@ class TokenObtainSerializer(serializers.Serializer): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) - self.fields[self.username_field] = serializers.CharField() + self.fields[self.username_field] = serializers.CharField(write_only=True) self.fields["password"] = PasswordField() def validate(self, attrs: Dict[str, Any]) -> Dict[Any, Any]: @@ -147,7 +147,7 @@ def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: class TokenVerifySerializer(serializers.Serializer): - token = serializers.CharField() + token = serializers.CharField(write_only=True) def validate(self, attrs: Dict[str, None]) -> Dict[Any, Any]: token = UntypedToken(attrs["token"]) @@ -164,7 +164,7 @@ def validate(self, attrs: Dict[str, None]) -> Dict[Any, Any]: class TokenBlacklistSerializer(serializers.Serializer): - refresh = serializers.CharField() + refresh = serializers.CharField(write_only=True) token_class = RefreshToken def validate(self, attrs: Dict[str, Any]) -> Dict[Any, Any]: From 9c8e70c5358e99cb9584bb340a3a20aac2bfa616 Mon Sep 17 00:00:00 2001 From: johnthagen Date: Wed, 21 Jun 2023 09:25:30 -0400 Subject: [PATCH 079/171] Add support for Django 4.2 (#711) * Add support for Django 4.2 * Exclude DRF 3.13 & Django 4.2 CI combination --- .github/workflows/test.yml | 6 +++++- docs/getting_started.rst | 6 +++--- setup.py | 5 +++-- tox.ini | 6 ++++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 41676e16c..b41516d59 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,8 +16,12 @@ jobs: max-parallel: 5 matrix: python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] - django-version: ['3.2', '4.0', '4.1'] + django-version: ['3.2', '4.0', '4.1', '4.2'] drf-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] + exclude: + # DRF 3.13 is not compatible with Django 4.2. + - django-version: '4.2' + drf-version: '3.13' steps: - uses: actions/checkout@v2 diff --git a/docs/getting_started.rst b/docs/getting_started.rst index c07382414..42e646187 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -6,9 +6,9 @@ Getting started Requirements ------------ -* Python (3.7, 3.8, 3.9, 3.10) -* Django (2.2, 3.1, 3.2, 4.0) -* Django REST Framework (3.10, 3.11, 3.12, 3.13) +* Python (3.8, 3.9, 3.10, 3.11) +* Django (3.2, 4.0, 4.1, 4.2) +* Django REST Framework (3.10, 3.11, 3.12, 3.13, 3.14) These are the officially supported python and package versions. Other versions will probably work. You're free to modify the tox config and see what is diff --git a/setup.py b/setup.py index 7b34f4f36..4fd09303f 100755 --- a/setup.py +++ b/setup.py @@ -55,8 +55,8 @@ author="David Sanders", author_email="davesque@gmail.com", install_requires=[ - "django", - "djangorestframework", + "django>=3.2", + "djangorestframework>=3.10", "pyjwt>=1.7.1,<3", ], python_requires=">=3.7", @@ -71,6 +71,7 @@ "Framework :: Django :: 3.2", "Framework :: Django :: 4.0", "Framework :: Django :: 4.1", + "Framework :: Django :: 4.2", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", diff --git a/tox.ini b/tox.ini index e5a276a40..8fb68941b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,8 @@ [tox] envlist= py{37,38,39,310}-dj{32}-drf{311,312,313}-pyjwt{171,2}-tests - py{38,39,310}-dj{40,41}-drf313-pyjwt{171,2}-tests - py311-dj{41}-drf{313,314}-pyjwt{171,2}-tests + py{38,39,310}-dj{40,41,42}-drf313-pyjwt{171,2}-tests + py311-dj{41,42}-drf{313,314}-pyjwt{171,2}-tests docs [gh-actions] @@ -18,6 +18,7 @@ DJANGO= 3.2: dj32 4.0: dj40 4.1: dj41 + 4.2: dj42 DRF= 3.10: drf310 3.11: drf311 @@ -36,6 +37,7 @@ deps= dj32: Django>=3.2,<3.3 dj40: Django>=4.0,<4.1 dj41: Django>=4.1,<4.2 + dj42: Django>=4.2,<4.3 drf310: djangorestframework>=3.10,<3.11 drf311: djangorestframework>=3.11,<3.12 drf312: djangorestframework>=3.12,<3.13 From 6e7c7523f9a41d571b47e02a29689c74b7eec01f Mon Sep 17 00:00:00 2001 From: Ahmed Jazzar <11036472+iamjazzar@users.noreply.github.com> Date: Wed, 21 Jun 2023 06:26:12 -0700 Subject: [PATCH 080/171] Add Arabic language translations (#690) --- .../locale/ar/LC_MESSAGES/django.mo | Bin 0 -> 3121 bytes .../locale/ar/LC_MESSAGES/django.po | 113 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.mo create mode 100644 rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..374342e2447de537b9606e6494b86904de5783c5 GIT binary patch literal 3121 zcmah~%WoS+7$2a#Odn9*(8EYo8jxx??gO=MT>4OpQqfW&7YPZeOzg3}>3Y}N9Vbnz zf|ABfFqd99AaS6oQm1Z{$W2RCF8l)=5URxN1%$+r1Kc?D!0($`+i}&xO3rU*=6n3U z-}lYt*NtnwVt8K1Zxeoh;5UHZjmPi@&;G|58wMT#ZUue@d<%FT_$Kfka69lX;0M6X zPuMsia0AwtfIEQS0$&B*i}(KozJT?8;7h>uYb}{YxEh*rqSYLXIv7^Ahfu8_}pSJwJ1`_`tfu936J;PWA z_ziFu@E2eSxb9iTb^>d_L0}6w0Q@;#{{!5IH3zBVz*9idX9-vb{thIaOV2Sj1e^gL z0p13ZUiV{MyVlmR2}pHwAhqNb{5lU(bsy4_bfjmU1@_^2PGJ;W^tgV%6{OS70U5FUY4RD174|xisyY#3CH7V z!slUCWTst;vub5}xP7GLS+^uKd%|;}ec5bI<2$vMRYBaMvkHa0H)J{N4xT$d$U~`=gnU$jOCT%$xGbdj30I0xVqHY>%D3i* z*|>0AG3v^WbC_Z|Q>KZScZE|i@#LARgPifgD`>2`y~&GQ`lOF zjE>=2bn>PNu@A9?buUl(?QK0R$ZRhbYij5hE5G9y$(eX z?lr+Ql<2TNgYNcLKIlq0Atndy{EVXgMLPzLr?&E<>kCB_LDPUyQX<7pn(~Q-?W*0N z=`d|&ANw^MtSr#-d@xy6ekl;u@+4eBC0rL2(J;u!&z(;(JBeVen5`zH*D>WV5}KU| z{4tqV$&o_xBN>F4_zW+M2@i87Lsbk!MNas^=~JOosk(A(LM1+wRXzw&o*gB}xF!#KdB1?M z&hXu%j!K+xYk_c+NBp1?X1G^1%P{-SUT$BrUN$?#-{nIbr`c>8uW9?b9k1Kzbs#-7 zv@g4ZZ`oqshqGz&*wH&nr&k^B*@MHKINY^2!J>w~p%=Km5?$nYU(~H=E^2Vy)>rfj z*Ue}KJ5#i$zvKFDG!uQnqv@y-)v@0or+PG{Z^M8LX+tmIYz3ZEx~W?X`%OfK*#$bB zk1pz4IJnGp3n^|PZd+eN6y1*IbQ|7!8Nm?uBGz|_*c|1>IqUNvYCW&-DGt}S4dF!! zI0Mf{CknD7H)=%8CPg)Mb@LNXu&)!RMdWYjWv-WuZCl@ja|03egE>$dTySPQDdJsy z9Zuk3bwVuY0Ci2xcfbiY3vg&+133*1M4v{=y1r&8(C)mxX$T@GMV&|7W!Nv9Z%c|Y zw)GA4!JN{o5o+G_#(aKEq88lR(NvdAU#L~-bqfnfmSToiE1IRyM)8=SzGE^ikO&Lr zb#?2^7X~#n^;N2ZH0<=XS7WEUL}CSesh-PrHelbKx}GcIz!m}Hv4|&c7PCRkz`+U} zmqP8_}$8Qem{;p+(byC@TPJHknYsUX`Y#M>};KjK2R7+}fEreyEkn z8;|*tZi2wohuGC27Me^&PtnaJSyrh{rS%l;tFm9g2glc5ExH*P;92NlCC6RHjn#{^ z!8(_al04!*KseH24wGglAuhF*s5MP^iG|driTDQz7&vdU}d~;Fi6x~dW-T&NMl6cjCG4SY;Mp8>U9-a#{ x@VBTnxcKn8jw{ll$!c~c6m6)Re|Gc%!pH9_ox`4?{#bjvrhj{J&$`3S{skE9Q&<21 literal 0 HcmV?d00001 diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po new file mode 100644 index 000000000..426e6d113 --- /dev/null +++ b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po @@ -0,0 +1,113 @@ +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , 2019. +msgid "" +msgstr "" +"Project-Id-Version: djangorestframework_simplejwt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-03-20 17:30+0100\n" +"Last-Translator: Ahmed Jazzar \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + + +#: authentication.py:78 +msgid "Authorization header must contain two space-delimited values" +msgstr "يجب أن يحتوي رأس التفويض على قيمتين مفصولتين بمسافات" + +#: authentication.py:104 +msgid "Given token not valid for any token type" +msgstr "تأشيرة المرور غير صالحة لأي نوع من أنواع التأشيرات" + +#: authentication.py:116 authentication.py:143 +msgid "Token contained no recognizable user identification" +msgstr "لا تحتوي تأشيرة المرور على هوية مستخدم يمكن التعرف عليها" + +#: authentication.py:121 +msgid "User not found" +msgstr "لم يتم العثور على المستخدم" + +#: authentication.py:124 +msgid "User is inactive" +msgstr "الحساب غير مفعل" + +#: backends.py:67 +msgid "Unrecognized algorithm type '{}'" +msgstr "نوع الخوارزمية غير معروف '{}'" + +#: backends.py:73 +msgid "You must have cryptography installed to use {}." +msgstr "يجب أن يكون لديك تشفير مثبت لاستخدام {}." + +#: backends.py:88 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "نوع غير معروف '{}'. يجب أن تكون 'leeway' عددًا صحيحًا أو عددًا نسبيًا أو فرق وقت." + +#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +msgid "Token is invalid or expired" +msgstr "تأشيرة المرور غير صالحة أو منتهية الصلاحية" + +#: backends.py:150 +msgid "Invalid algorithm specified" +msgstr "تم تحديد خوارزمية غير صالحة" + +#: serializers.py:30 +msgid "No active account found with the given credentials" +msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" + +#: settings.py:70 +msgid "" +"The '{}' setting has been removed. Please refer to '{}' for available " +"settings." +msgstr "تمت إزالة الإعداد '{}'. يرجى الرجوع إلى '{}' للتعرف على الإعدادات المتاحة." + +#: token_blacklist/admin.py:68 +msgid "jti" +msgstr "jti" + +#: token_blacklist/admin.py:74 +msgid "user" +msgstr "المستخدم" + +#: token_blacklist/admin.py:80 +msgid "created at" +msgstr "أنشئت في" + +#: token_blacklist/admin.py:86 +msgid "expires at" +msgstr "تنتهي في" + +#: token_blacklist/apps.py:7 +msgid "Token Blacklist" +msgstr "قائمة تأشيرات المرور السوداء" + +#: tokens.py:30 +msgid "Cannot create token with no type or lifetime" +msgstr "لا يمكن إنشاء تأشيرة مرور بدون نوع أو عمر" + +#: tokens.py:102 +msgid "Token has no id" +msgstr "التأشيرة ليس لها معرف" + +#: tokens.py:115 +msgid "Token has no type" +msgstr "التأشيرة ليس لها نوع" + +#: tokens.py:118 +msgid "Token has wrong type" +msgstr "التأشيرة لها نوع خاطئ" + +#: tokens.py:170 +msgid "Token has no '{}' claim" +msgstr "التأشيرة ليس لديها مطالبة '{}'" + +#: tokens.py:175 +msgid "Token '{}' claim has expired" +msgstr "انتهى عمر المطالبة بالتأشيرة '{}'" + +#: tokens.py:230 +msgid "Token is blacklisted" +msgstr "التأشيرة مدرجة في القائمة السوداء" From c65036c6d2a154eb9390eed1738358fed6ae699e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 21 Jun 2023 09:27:17 -0400 Subject: [PATCH 081/171] [pre-commit.ci] pre-commit autoupdate (#694) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/asottile/yesqa: v1.4.0 → v1.5.0](https://github.com/asottile/yesqa/compare/v1.4.0...v1.5.0) - [github.com/psf/black: 22.12.0 → 23.3.0](https://github.com/psf/black/compare/22.12.0...23.3.0) - [github.com/asottile/pyupgrade: v3.3.1 → v3.7.0](https://github.com/asottile/pyupgrade/compare/v3.3.1...v3.7.0) * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- .../token_blacklist/migrations/0001_initial.py | 1 - .../migrations/0002_outstandingtoken_jti_hex.py | 1 - .../token_blacklist/migrations/0003_auto_20171017_2007.py | 1 - .../token_blacklist/migrations/0004_auto_20171017_2013.py | 1 - .../migrations/0005_remove_outstandingtoken_jti.py | 1 - .../token_blacklist/migrations/0006_auto_20171017_2113.py | 1 - .../token_blacklist/migrations/0007_auto_20171017_2214.py | 1 - .../migrations/0008_migrate_to_bigautofield.py | 1 - .../migrations/0010_fix_migrate_to_bigautofield.py | 1 - .../migrations/0012_alter_outstandingtoken_user.py | 1 - rest_framework_simplejwt/tokens.py | 1 - tests/test_backends.py | 2 -- 13 files changed, 3 insertions(+), 16 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9363708a8..2a2894302 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-merge-conflict - repo: https://github.com/asottile/yesqa - rev: v1.4.0 + rev: v1.5.0 hooks: - id: yesqa - repo: https://github.com/pycqa/isort @@ -13,7 +13,7 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '22.12.0' + rev: '23.3.0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v3.3.1' + rev: 'v3.7.0' hooks: - id: pyupgrade args: ['--py37-plus', '--keep-mock'] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0001_initial.py b/rest_framework_simplejwt/token_blacklist/migrations/0001_initial.py index b80d9f0a7..88baa7d93 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0001_initial.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0001_initial.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - initial = True dependencies = [ diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0002_outstandingtoken_jti_hex.py b/rest_framework_simplejwt/token_blacklist/migrations/0002_outstandingtoken_jti_hex.py index 56df7d1a8..59af197e6 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0002_outstandingtoken_jti_hex.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0002_outstandingtoken_jti_hex.py @@ -2,7 +2,6 @@ class Migration(migrations.Migration): - dependencies = [ ("token_blacklist", "0001_initial"), ] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0003_auto_20171017_2007.py b/rest_framework_simplejwt/token_blacklist/migrations/0003_auto_20171017_2007.py index 336827ba4..1b753499a 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0003_auto_20171017_2007.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0003_auto_20171017_2007.py @@ -22,7 +22,6 @@ def reverse_populate_jti_hex(apps, schema_editor): # pragma: no cover class Migration(migrations.Migration): - dependencies = [ ("token_blacklist", "0002_outstandingtoken_jti_hex"), ] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0004_auto_20171017_2013.py b/rest_framework_simplejwt/token_blacklist/migrations/0004_auto_20171017_2013.py index b11bdc33d..f5ba7e9ff 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0004_auto_20171017_2013.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0004_auto_20171017_2013.py @@ -2,7 +2,6 @@ class Migration(migrations.Migration): - dependencies = [ ("token_blacklist", "0003_auto_20171017_2007"), ] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0005_remove_outstandingtoken_jti.py b/rest_framework_simplejwt/token_blacklist/migrations/0005_remove_outstandingtoken_jti.py index 14e6af147..2b140ed9f 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0005_remove_outstandingtoken_jti.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0005_remove_outstandingtoken_jti.py @@ -2,7 +2,6 @@ class Migration(migrations.Migration): - dependencies = [ ("token_blacklist", "0004_auto_20171017_2013"), ] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0006_auto_20171017_2113.py b/rest_framework_simplejwt/token_blacklist/migrations/0006_auto_20171017_2113.py index abaef538f..10f9f1e2a 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0006_auto_20171017_2113.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0006_auto_20171017_2113.py @@ -2,7 +2,6 @@ class Migration(migrations.Migration): - dependencies = [ ("token_blacklist", "0005_remove_outstandingtoken_jti"), ] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0007_auto_20171017_2214.py b/rest_framework_simplejwt/token_blacklist/migrations/0007_auto_20171017_2214.py index 87961ddb8..5fa602fd1 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0007_auto_20171017_2214.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0007_auto_20171017_2214.py @@ -4,7 +4,6 @@ class Migration(migrations.Migration): - dependencies = [ ("token_blacklist", "0006_auto_20171017_2113"), ] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0008_migrate_to_bigautofield.py b/rest_framework_simplejwt/token_blacklist/migrations/0008_migrate_to_bigautofield.py index 46f516e23..9a7735729 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0008_migrate_to_bigautofield.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0008_migrate_to_bigautofield.py @@ -2,7 +2,6 @@ class Migration(migrations.Migration): - dependencies = [ ("token_blacklist", "0007_auto_20171017_2214"), ] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0010_fix_migrate_to_bigautofield.py b/rest_framework_simplejwt/token_blacklist/migrations/0010_fix_migrate_to_bigautofield.py index 4046e8bf5..b6d595df9 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0010_fix_migrate_to_bigautofield.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0010_fix_migrate_to_bigautofield.py @@ -8,7 +8,6 @@ class Migration(migrations.Migration): - dependencies = [ ("token_blacklist", "0008_migrate_to_bigautofield"), ] diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0012_alter_outstandingtoken_user.py b/rest_framework_simplejwt/token_blacklist/migrations/0012_alter_outstandingtoken_user.py index 652f06b69..91d5e0645 100644 --- a/rest_framework_simplejwt/token_blacklist/migrations/0012_alter_outstandingtoken_user.py +++ b/rest_framework_simplejwt/token_blacklist/migrations/0012_alter_outstandingtoken_user.py @@ -6,7 +6,6 @@ class Migration(migrations.Migration): - dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ("token_blacklist", "0011_linearizes_history"), diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 49eb48a5c..bb2ee8780 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -110,7 +110,6 @@ def verify(self) -> None: raise TokenError(_("Token has no id")) if api_settings.TOKEN_TYPE_CLAIM is not None: - self.verify_token_type() def verify_token_type(self) -> None: diff --git a/tests/test_backends.py b/tests/test_backends.py index 0314ba671..540e01820 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -162,7 +162,6 @@ def test_decode_with_expiry(self): self.payload["exp"] = aware_utcnow() - timedelta(seconds=1) for backend in self.backends: with self.subTest("Test decode with expiry for f{backend.algorithm}"): - expired_token = jwt.encode( self.payload, backend.signing_key, algorithm=backend.algorithm ) @@ -228,7 +227,6 @@ def test_decode_success(self): self.payload["foo"] = "baz" for backend in self.backends: with self.subTest("Test decode success for f{backend.algorithm}"): - token = jwt.encode( self.payload, backend.signing_key, algorithm=backend.algorithm ) From d2cd59d0cc871a70b634db6825b8a9749d1fbe59 Mon Sep 17 00:00:00 2001 From: kiraware <117554978+kiraware@users.noreply.github.com> Date: Wed, 21 Jun 2023 21:30:13 +0800 Subject: [PATCH 082/171] Improve testing (#688) * Support `override_api_settings` as decorator * Update test_authentication * black formatting test_authentication * Use drf status instead of literal status * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update test_integration * Update test_serializers * Update test_integration * Update test_token_blacklist * Update test_tokens * Update test_views * add `setUpTestData` to `TestToken` * fix typo `self` should be `cls` --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- tests/test_authentication.py | 98 ++++++++++++++++++----------------- tests/test_integration.py | 42 +++++++-------- tests/test_serializers.py | 30 +++++------ tests/test_token_blacklist.py | 20 +++---- tests/test_tokens.py | 34 ++++++------ tests/test_views.py | 49 ++++++++---------- tests/utils.py | 36 +++++++------ 7 files changed, 154 insertions(+), 155 deletions(-) diff --git a/tests/test_authentication.py b/tests/test_authentication.py index 917f3993d..9fa645c2c 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -40,25 +40,19 @@ def test_get_header(self): ) self.assertEqual(self.backend.get_header(request), self.fake_header) - # Should work with the x_access_token - with override_api_settings(AUTH_HEADER_NAME="HTTP_X_ACCESS_TOKEN"): - # Should pull correct header off request when using X_ACCESS_TOKEN - request = self.factory.get( - "/test-url/", HTTP_X_ACCESS_TOKEN=self.fake_header - ) - self.assertEqual(self.backend.get_header(request), self.fake_header) - - # Should work for unicode headers when using - request = self.factory.get( - "/test-url/", HTTP_X_ACCESS_TOKEN=self.fake_header.decode("utf-8") - ) - self.assertEqual(self.backend.get_header(request), self.fake_header) + @override_api_settings(AUTH_HEADER_NAME="HTTP_X_ACCESS_TOKEN") + def test_get_header_x_access_token(self): + # Should pull correct header off request when using X_ACCESS_TOKEN + request = self.factory.get("/test-url/", HTTP_X_ACCESS_TOKEN=self.fake_header) + self.assertEqual(self.backend.get_header(request), self.fake_header) + + # Should work for unicode headers when using + request = self.factory.get( + "/test-url/", HTTP_X_ACCESS_TOKEN=self.fake_header.decode("utf-8") + ) + self.assertEqual(self.backend.get_header(request), self.fake_header) def test_get_raw_token(self): - # Should return None if header lacks correct type keyword - with override_api_settings(AUTH_HEADER_TYPES="JWT"): - reload(authentication) - self.assertIsNone(self.backend.get_raw_token(self.fake_header)) reload(authentication) # Should return None if an empty AUTHORIZATION header is sent @@ -74,14 +68,21 @@ def test_get_raw_token(self): # Otherwise, should return unvalidated token in header self.assertEqual(self.backend.get_raw_token(self.fake_header), self.fake_token) + @override_api_settings(AUTH_HEADER_TYPES="JWT") + def test_get_raw_token_incorrect_header_keyword(self): + # Should return None if header lacks correct type keyword + # AUTH_HEADER_TYPES is "JWT", but header is "Bearer" + reload(authentication) + self.assertIsNone(self.backend.get_raw_token(self.fake_header)) + + @override_api_settings(AUTH_HEADER_TYPES=("JWT", "Bearer")) + def test_get_raw_token_multi_header_keyword(self): # Should return token if header has one of many valid token types - with override_api_settings(AUTH_HEADER_TYPES=("JWT", "Bearer")): - reload(authentication) - self.assertEqual( - self.backend.get_raw_token(self.fake_header), - self.fake_token, - ) reload(authentication) + self.assertEqual( + self.backend.get_raw_token(self.fake_header), + self.fake_token, + ) def test_get_validated_token(self): # Should raise InvalidToken if token not valid @@ -96,36 +97,39 @@ def test_get_validated_token(self): self.backend.get_validated_token(str(token)).payload, token.payload ) + @override_api_settings( + AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.AccessToken",), + ) + def test_get_validated_token_reject_unknown_token(self): # Should not accept tokens not included in AUTH_TOKEN_CLASSES sliding_token = SlidingToken() - with override_api_settings( - AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.AccessToken",) - ): - with self.assertRaises(InvalidToken) as e: - self.backend.get_validated_token(str(sliding_token)) - - messages = e.exception.detail["messages"] - self.assertEqual(1, len(messages)) - self.assertEqual( - { - "token_class": "AccessToken", - "token_type": "access", - "message": "Token has wrong type", - }, - messages[0], - ) + with self.assertRaises(InvalidToken) as e: + self.backend.get_validated_token(str(sliding_token)) + + messages = e.exception.detail["messages"] + self.assertEqual(1, len(messages)) + self.assertEqual( + { + "token_class": "AccessToken", + "token_type": "access", + "message": "Token has wrong type", + }, + messages[0], + ) + @override_api_settings( + AUTH_TOKEN_CLASSES=( + "rest_framework_simplejwt.tokens.AccessToken", + "rest_framework_simplejwt.tokens.SlidingToken", + ), + ) + def test_get_validated_token_accept_known_token(self): # Should accept tokens included in AUTH_TOKEN_CLASSES access_token = AccessToken() sliding_token = SlidingToken() - with override_api_settings( - AUTH_TOKEN_CLASSES=( - "rest_framework_simplejwt.tokens.AccessToken", - "rest_framework_simplejwt.tokens.SlidingToken", - ) - ): - self.backend.get_validated_token(str(access_token)) - self.backend.get_validated_token(str(sliding_token)) + + self.backend.get_validated_token(str(access_token)) + self.backend.get_validated_token(str(sliding_token)) def test_get_user(self): payload = {"some_other_id": "foo"} diff --git a/tests/test_integration.py b/tests/test_integration.py index 54786d87a..beee3d552 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -2,6 +2,7 @@ from django.contrib.auth import get_user_model from django.urls import reverse +from rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED from rest_framework_simplejwt.settings import api_settings from rest_framework_simplejwt.tokens import AccessToken @@ -26,7 +27,7 @@ def setUp(self): def test_no_authorization(self): res = self.view_get() - self.assertEqual(res.status_code, 401) + self.assertEqual(res.status_code, HTTP_401_UNAUTHORIZED) self.assertIn("credentials were not provided", res.data["detail"]) def test_wrong_auth_type(self): @@ -43,9 +44,12 @@ def test_wrong_auth_type(self): res = self.view_get() - self.assertEqual(res.status_code, 401) + self.assertEqual(res.status_code, HTTP_401_UNAUTHORIZED) self.assertIn("credentials were not provided", res.data["detail"]) + @override_api_settings( + AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.AccessToken",), + ) def test_expired_token(self): old_lifetime = AccessToken.lifetime AccessToken.lifetime = timedelta(seconds=0) @@ -63,14 +67,14 @@ def test_expired_token(self): access = res.data["access"] self.authenticate_with_token(api_settings.AUTH_HEADER_TYPES[0], access) - with override_api_settings( - AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.AccessToken",) - ): - res = self.view_get() + res = self.view_get() - self.assertEqual(res.status_code, 401) + self.assertEqual(res.status_code, HTTP_401_UNAUTHORIZED) self.assertEqual("token_not_valid", res.data["code"]) + @override_api_settings( + AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.SlidingToken",), + ) def test_user_can_get_sliding_token_and_use_it(self): res = self.client.post( reverse("token_obtain_sliding"), @@ -83,14 +87,14 @@ def test_user_can_get_sliding_token_and_use_it(self): token = res.data["token"] self.authenticate_with_token(api_settings.AUTH_HEADER_TYPES[0], token) - with override_api_settings( - AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.SlidingToken",) - ): - res = self.view_get() + res = self.view_get() - self.assertEqual(res.status_code, 200) + self.assertEqual(res.status_code, HTTP_200_OK) self.assertEqual(res.data["foo"], "bar") + @override_api_settings( + AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.AccessToken",), + ) def test_user_can_get_access_and_refresh_tokens_and_use_them(self): res = self.client.post( reverse("token_obtain_pair"), @@ -105,12 +109,9 @@ def test_user_can_get_access_and_refresh_tokens_and_use_them(self): self.authenticate_with_token(api_settings.AUTH_HEADER_TYPES[0], access) - with override_api_settings( - AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.AccessToken",) - ): - res = self.view_get() + res = self.view_get() - self.assertEqual(res.status_code, 200) + self.assertEqual(res.status_code, HTTP_200_OK) self.assertEqual(res.data["foo"], "bar") res = self.client.post( @@ -122,10 +123,7 @@ def test_user_can_get_access_and_refresh_tokens_and_use_them(self): self.authenticate_with_token(api_settings.AUTH_HEADER_TYPES[0], access) - with override_api_settings( - AUTH_TOKEN_CLASSES=("rest_framework_simplejwt.tokens.AccessToken",) - ): - res = self.view_get() + res = self.view_get() - self.assertEqual(res.status_code, 200) + self.assertEqual(res.status_code, HTTP_200_OK) self.assertEqual(res.data["foo"], "bar") diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 530f689cd..6db0e3998 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -285,6 +285,10 @@ def test_it_should_return_access_token_if_everything_ok(self): access["exp"], datetime_to_epoch(now + api_settings.ACCESS_TOKEN_LIFETIME) ) + @override_api_settings( + ROTATE_REFRESH_TOKENS=True, + BLACKLIST_AFTER_ROTATION=False, + ) def test_it_should_return_refresh_token_if_tokens_should_be_rotated(self): refresh = RefreshToken() @@ -298,14 +302,9 @@ def test_it_should_return_refresh_token_if_tokens_should_be_rotated(self): now = aware_utcnow() - api_settings.ACCESS_TOKEN_LIFETIME / 2 - with override_api_settings( - ROTATE_REFRESH_TOKENS=True, BLACKLIST_AFTER_ROTATION=False - ): - with patch( - "rest_framework_simplejwt.tokens.aware_utcnow" - ) as fake_aware_utcnow: - fake_aware_utcnow.return_value = now - self.assertTrue(ser.is_valid()) + with patch("rest_framework_simplejwt.tokens.aware_utcnow") as fake_aware_utcnow: + fake_aware_utcnow.return_value = now + self.assertTrue(ser.is_valid()) access = AccessToken(ser.validated_data["access"]) new_refresh = RefreshToken(ser.validated_data["refresh"]) @@ -324,6 +323,10 @@ def test_it_should_return_refresh_token_if_tokens_should_be_rotated(self): datetime_to_epoch(now + api_settings.REFRESH_TOKEN_LIFETIME), ) + @override_api_settings( + ROTATE_REFRESH_TOKENS=True, + BLACKLIST_AFTER_ROTATION=True, + ) def test_it_should_blacklist_refresh_token_if_tokens_should_be_rotated_and_blacklisted( self, ): @@ -342,14 +345,9 @@ def test_it_should_blacklist_refresh_token_if_tokens_should_be_rotated_and_black now = aware_utcnow() - api_settings.ACCESS_TOKEN_LIFETIME / 2 - with override_api_settings( - ROTATE_REFRESH_TOKENS=True, BLACKLIST_AFTER_ROTATION=True - ): - with patch( - "rest_framework_simplejwt.tokens.aware_utcnow" - ) as fake_aware_utcnow: - fake_aware_utcnow.return_value = now - self.assertTrue(ser.is_valid()) + with patch("rest_framework_simplejwt.tokens.aware_utcnow") as fake_aware_utcnow: + fake_aware_utcnow.return_value = now + self.assertTrue(ser.is_valid()) access = AccessToken(ser.validated_data["access"]) new_refresh = RefreshToken(ser.validated_data["refresh"]) diff --git a/tests/test_token_blacklist.py b/tests/test_token_blacklist.py index 67ea7fada..824808145 100644 --- a/tests/test_token_blacklist.py +++ b/tests/test_token_blacklist.py @@ -237,25 +237,25 @@ def setUp(self): super().setUp() + @override_api_settings(BLACKLIST_AFTER_ROTATION=True) def test_token_verify_serializer_should_honour_blacklist_if_blacklisting_enabled( self, ): - with override_api_settings(BLACKLIST_AFTER_ROTATION=True): - refresh_token = RefreshToken.for_user(self.user) - refresh_token.blacklist() + refresh_token = RefreshToken.for_user(self.user) + refresh_token.blacklist() - serializer = TokenVerifySerializer(data={"token": str(refresh_token)}) - self.assertFalse(serializer.is_valid()) + serializer = TokenVerifySerializer(data={"token": str(refresh_token)}) + self.assertFalse(serializer.is_valid()) + @override_api_settings(BLACKLIST_AFTER_ROTATION=False) def test_token_verify_serializer_should_not_honour_blacklist_if_blacklisting_not_enabled( self, ): - with override_api_settings(BLACKLIST_AFTER_ROTATION=False): - refresh_token = RefreshToken.for_user(self.user) - refresh_token.blacklist() + refresh_token = RefreshToken.for_user(self.user) + refresh_token.blacklist() - serializer = TokenVerifySerializer(data={"token": str(refresh_token)}) - self.assertTrue(serializer.is_valid()) + serializer = TokenVerifySerializer(data={"token": str(refresh_token)}) + self.assertTrue(serializer.is_valid()) class TestBigAutoFieldIDMigration(MigrationTestCase): diff --git a/tests/test_tokens.py b/tests/test_tokens.py index bc06997d9..9f81a1a76 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -31,6 +31,14 @@ class TestToken(TestCase): def setUp(self): self.token = MyToken() + @classmethod + def setUpTestData(cls): + cls.username = "test_user" + cls.user = User.objects.create_user( + username=cls.username, + password="test_password", + ) + def test_init_no_token_type_or_lifetime(self): class MyTestToken(Token): pass @@ -225,14 +233,14 @@ def test_set_jti(self): self.assertIn("jti", token) self.assertNotEqual(old_jti, token["jti"]) + @override_api_settings(JTI_CLAIM=None) def test_optional_jti(self): - with override_api_settings(JTI_CLAIM=None): - token = MyToken() + token = MyToken() self.assertNotIn("jti", token) + @override_api_settings(TOKEN_TYPE_CLAIM=None) def test_optional_type_token(self): - with override_api_settings(TOKEN_TYPE_CLAIM=None): - token = MyToken() + token = MyToken() self.assertNotIn("type", token) def test_set_exp(self): @@ -355,25 +363,19 @@ def test_check_token_if_wrong_type_leeway(self): token.token_backend.leeway = 0 def test_for_user(self): - username = "test_user" - user = User.objects.create_user( - username=username, - password="test_password", - ) + token = MyToken.for_user(self.user) - token = MyToken.for_user(user) - - user_id = getattr(user, api_settings.USER_ID_FIELD) + user_id = getattr(self.user, api_settings.USER_ID_FIELD) if not isinstance(user_id, int): user_id = str(user_id) self.assertEqual(token[api_settings.USER_ID_CLAIM], user_id) + @override_api_settings(USER_ID_FIELD="username") + def test_for_user_with_username(self): # Test with non-int user id - with override_api_settings(USER_ID_FIELD="username"): - token = MyToken.for_user(user) - - self.assertEqual(token[api_settings.USER_ID_CLAIM], username) + token = MyToken.for_user(self.user) + self.assertEqual(token[api_settings.USER_ID_CLAIM], self.username) def test_get_token_backend(self): token = MyToken() diff --git a/tests/test_views.py b/tests/test_views.py index 8a9e16f26..b1fc80113 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -1,5 +1,4 @@ from datetime import timedelta -from importlib import reload from unittest.mock import patch from django.contrib.auth import get_user_model @@ -93,20 +92,18 @@ def test_update_last_login(self): user = User.objects.get(username=self.username) self.assertEqual(user.last_login, None) + @override_api_settings(UPDATE_LAST_LOGIN=True) + def test_update_last_login_updated(self): # verify last_login is updated - with override_api_settings(UPDATE_LAST_LOGIN=True): - reload(serializers) - self.view_post( - data={ - User.USERNAME_FIELD: self.username, - "password": self.password, - } - ) - user = User.objects.get(username=self.username) - self.assertIsNotNone(user.last_login) - self.assertGreaterEqual(timezone.now(), user.last_login) - - reload(serializers) + self.view_post( + data={ + User.USERNAME_FIELD: self.username, + "password": self.password, + } + ) + user = User.objects.get(username=self.username) + self.assertIsNotNone(user.last_login) + self.assertGreaterEqual(timezone.now(), user.last_login) class TestTokenRefreshView(APIViewTestCase): @@ -233,20 +230,18 @@ def test_update_last_login(self): user = User.objects.get(username=self.username) self.assertEqual(user.last_login, None) + @override_api_settings(UPDATE_LAST_LOGIN=True) + def test_update_last_login_updated(self): # verify last_login is updated - with override_api_settings(UPDATE_LAST_LOGIN=True): - reload(serializers) - self.view_post( - data={ - User.USERNAME_FIELD: self.username, - "password": self.password, - } - ) - user = User.objects.get(username=self.username) - self.assertIsNotNone(user.last_login) - self.assertGreaterEqual(timezone.now(), user.last_login) - - reload(serializers) + self.view_post( + data={ + User.USERNAME_FIELD: self.username, + "password": self.password, + } + ) + user = User.objects.get(username=self.username) + self.assertIsNotNone(user.last_login) + self.assertGreaterEqual(timezone.now(), user.last_login) class TestTokenRefreshSlidingView(APIViewTestCase): diff --git a/tests/utils.py b/tests/utils.py index c3d710a2e..9e4c2c4cb 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -62,23 +62,25 @@ def override_api_settings(**settings): except AttributeError: pass - yield - - for k in settings.keys(): - # Delete temporary settings - api_settings.user_settings.pop(k) - - # Restore saved settings - try: - api_settings.user_settings[k] = old_settings[k] - except KeyError: - pass - - # Delete any cached settings - try: - delattr(api_settings, k) - except AttributeError: - pass + try: + yield + + finally: + for k in settings.keys(): + # Delete temporary settings + api_settings.user_settings.pop(k) + + # Restore saved settings + try: + api_settings.user_settings[k] = old_settings[k] + except KeyError: + pass + + # Delete any cached settings + try: + delattr(api_settings, k) + except AttributeError: + pass class MigrationTestCase(TransactionTestCase): From a775004553031e10f2d97e9e80ae5ef72f5020f6 Mon Sep 17 00:00:00 2001 From: Mahdi Rahimi <31624047+mahdirahimi1999@users.noreply.github.com> Date: Tue, 27 Jun 2023 11:22:26 +0330 Subject: [PATCH 083/171] Revoke access token if user password is changed (#719) --- docs/settings.rst | 15 ++++++++ rest_framework_simplejwt/authentication.py | 9 +++++ rest_framework_simplejwt/settings.py | 2 ++ rest_framework_simplejwt/tokens.py | 13 ++++++- rest_framework_simplejwt/utils.py | 8 +++++ tests/test_authentication.py | 40 ++++++++++++++++++++++ 6 files changed, 86 insertions(+), 1 deletion(-) diff --git a/docs/settings.rst b/docs/settings.rst index f892ea63d..2b466623e 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -272,3 +272,18 @@ More about this in the "Sliding tokens" section below. The claim name that is used to store the expiration time of a sliding token's refresh period. More about this in the "Sliding tokens" section below. + +``CHECK_REVOKE_TOKEN`` +-------------------- + +If this field is set to ``True``, the system will verify whether the token +has been revoked or not by comparing the md5 hash of the user's current +password with the value stored in the REVOKE_TOKEN_CLAIM field within the +payload of the JWT token. + +``REVOKE_TOKEN_CLAIM`` +-------------------- + +The claim name that is used to store a user hash password. +If the value of this CHECK_REVOKE_TOKEN field is ``True``, this field will be +included in the JWT payload. diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index 715d42c17..13767e1ee 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -10,6 +10,7 @@ from .models import TokenUser from .settings import api_settings from .tokens import Token +from .utils import get_md5_hash_password AUTH_HEADER_TYPES = api_settings.AUTH_HEADER_TYPES @@ -133,6 +134,14 @@ def get_user(self, validated_token: Token) -> AuthUser: if not user.is_active: raise AuthenticationFailed(_("User is inactive"), code="user_inactive") + if api_settings.CHECK_REVOKE_TOKEN: + if validated_token.get( + api_settings.REVOKE_TOKEN_CLAIM + ) != get_md5_hash_password(user.password): + raise AuthenticationFailed( + _("The user's password has been changed."), code="password_changed" + ) + return user diff --git a/rest_framework_simplejwt/settings.py b/rest_framework_simplejwt/settings.py index 55b300578..7691bb863 100644 --- a/rest_framework_simplejwt/settings.py +++ b/rest_framework_simplejwt/settings.py @@ -42,6 +42,8 @@ "TOKEN_BLACKLIST_SERIALIZER": "rest_framework_simplejwt.serializers.TokenBlacklistSerializer", "SLIDING_TOKEN_OBTAIN_SERIALIZER": "rest_framework_simplejwt.serializers.TokenObtainSlidingSerializer", "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer", + "CHECK_REVOKE_TOKEN": False, + "REVOKE_TOKEN_CLAIM": "hash_password", } IMPORT_STRINGS = ( diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index bb2ee8780..b207ef27c 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -11,7 +11,13 @@ from .models import TokenUser from .settings import api_settings from .token_blacklist.models import BlacklistedToken, OutstandingToken -from .utils import aware_utcnow, datetime_from_epoch, datetime_to_epoch, format_lazy +from .utils import ( + aware_utcnow, + datetime_from_epoch, + datetime_to_epoch, + format_lazy, + get_md5_hash_password, +) if TYPE_CHECKING: from .backends import TokenBackend @@ -201,6 +207,11 @@ def for_user(cls, user: AuthUser) -> "Token": token = cls() token[api_settings.USER_ID_CLAIM] = user_id + if api_settings.CHECK_REVOKE_TOKEN: + token[api_settings.REVOKE_TOKEN_CLAIM] = get_md5_hash_password( + user.password + ) + return token _token_backend: Optional["TokenBackend"] = None diff --git a/rest_framework_simplejwt/utils.py b/rest_framework_simplejwt/utils.py index f10b5e9f8..4490fa23c 100644 --- a/rest_framework_simplejwt/utils.py +++ b/rest_framework_simplejwt/utils.py @@ -1,3 +1,4 @@ +import hashlib from calendar import timegm from datetime import datetime, timezone from typing import Callable @@ -7,6 +8,13 @@ from django.utils.timezone import is_naive, make_aware +def get_md5_hash_password(password: str) -> str: + """ + Returns MD5 hash of the given password + """ + return hashlib.md5(password.encode()).hexdigest().upper() + + def make_utc(dt: datetime) -> datetime: if settings.USE_TZ and is_naive(dt): return make_aware(dt, timezone=timezone.utc) diff --git a/tests/test_authentication.py b/tests/test_authentication.py index 9fa645c2c..99f0b5525 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -10,6 +10,7 @@ from rest_framework_simplejwt.models import TokenUser from rest_framework_simplejwt.settings import api_settings from rest_framework_simplejwt.tokens import AccessToken, SlidingToken +from rest_framework_simplejwt.utils import get_md5_hash_password from .utils import override_api_settings @@ -160,6 +161,45 @@ def test_get_user(self): # Otherwise, should return correct user self.assertEqual(self.backend.get_user(payload).id, u.id) + @override_api_settings( + CHECK_REVOKE_TOKEN=True, REVOKE_TOKEN_CLAIM="revoke_token_claim" + ) + def test_get_user_with_check_revoke_token(self): + payload = {"some_other_id": "foo"} + + # Should raise error if no recognizable user identification + with self.assertRaises(InvalidToken): + self.backend.get_user(payload) + + payload[api_settings.USER_ID_CLAIM] = 42 + + # Should raise exception if user not found + with self.assertRaises(AuthenticationFailed): + self.backend.get_user(payload) + + u = User.objects.create_user(username="markhamill") + u.is_active = False + u.save() + + payload[api_settings.USER_ID_CLAIM] = getattr(u, api_settings.USER_ID_FIELD) + + # Should raise exception if user is inactive + with self.assertRaises(AuthenticationFailed): + self.backend.get_user(payload) + + u.is_active = True + u.save() + + # Should raise exception if hash password is different + with self.assertRaises(AuthenticationFailed): + self.backend.get_user(payload) + + if api_settings.CHECK_REVOKE_TOKEN: + payload[api_settings.REVOKE_TOKEN_CLAIM] = get_md5_hash_password(u.password) + + # Otherwise, should return correct user + self.assertEqual(self.backend.get_user(payload).id, u.id) + class TestJWTStatelessUserAuthentication(TestCase): def setUp(self): From 47b7a08caddfedbdc008b9e3406b038cb2a8dd32 Mon Sep 17 00:00:00 2001 From: Mahdi Rahimi <31624047+mahdirahimi1999@users.noreply.github.com> Date: Thu, 6 Jul 2023 18:07:42 +0330 Subject: [PATCH 084/171] Updated translations for Persian (fa) language (#723) * Updated translations for Persian (fa) language * Updated translations for Persian (fa) language * Updated translations for Persian (fa) language --- .../locale/fa/LC_MESSAGES/django.mo | Bin 0 -> 3006 bytes .../locale/fa/LC_MESSAGES/django.po | 41 +++++++------ .../locale/fa_IR/LC_MESSAGES/django.mo | Bin 2649 -> 2941 bytes .../locale/fa_IR/LC_MESSAGES/django.po | 56 ++++++++++-------- 4 files changed, 53 insertions(+), 44 deletions(-) diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e94394f2a6dba63320b4750ee0b9b6d3a379a311 100644 GIT binary patch literal 3006 zcmZ`)O>7%Q6ds@yFuyI7|HBAWrHHKir=sHih%|LeRMMD`7PTB;;vL)Du6M27anev# zqL4TdvU)(`fGTly8bVVy2_?Xp3pa$&Y$9<$962B%gv5#O&F;nyv@5N@otZc9eeZj3 z#=mUc^eMyhEZ*nw{*HG$-tX?h51zu^j2#5N3G4-40qy{P3w#dv8*mSh-NV=rU@wsN ze*`3d*MN@#zX$FG{tSEynAsH1zX05V@gCq4z@rJC0g`_Y$blaN2Y_Dy9|Qgcd<3}p zUdDC;w*fQ2e1ZiaLa}#%FlFxoE#zbaZHzzJ%-9Lw-@vzl{r55U3h*j$1o$Ix4A^r& zWBY)g1GfWz0+Lq$0EdCw9$;)2umXG%_!*GaZvcCMKLCl}pFq;_MUb?B?*Rqy3XlW; z0MfoK4>EQZ*b96dIGx~CAmy_FgehADA|0b8z&tdcK3nmzEg6tbplkF+xyYg1(RTat0CJGqY(o>FbLpFlho{N`ycqo-}yfUwdkdI1m31rnDlXjLDTq#0{ zaS6#QKQ=ea#)RXFQCFs$!>sXF4`t93@|p<4aX+v-E{hf6mEn?&7%@!TqAQ%LF_9N) z4wxm2M_f@n?>eDM#);sN7xD$N=$Adzg@RK!?wE{9PSKPq*+aR&x)W#PypzUC?2NuK zHJTX@eCW|N=|Gv3)jCg1I!Q@TtTcyHUP=*!JEbyZCpv6{!TNMB?{TFZ7ZW{kmyM!H zN^!F|p6cZ#*B6TVhI$4Kr$m;WGU*eGxc2b`^^hq(JLA`5XBC0QC;DPRk&~xybQCU;l}|<9U8M zKm69f(8Hb`JX095hUJ(;d#s~46FGh+-#2Ux4p~S0`0GQt z!GV|04xP+r-VmX(Mgrl5u26oE!J+DC6O5%7|eGl?#}MY^yAE;@2wG>qa0WAg4$U__jw068Z*EFICN^{n6}5S2M%#(4GT4{yen978IG?Hu?d!3&(jC3FGSPEo=2ClvK&n& zV_IT*E}B`r7B$EM9`F%OuQgWzjc7)%a5&YsFpmH$(G>h5Kugckco84h^&Bk0WKqv` z`63D??0WPz@%@kQG&U_vB}pPcBbr)k{`x`Fq-;30qRCZ|(`^Kri>6>gNq2TkA(iWT zc|F;dp_3${TdUV#-XNxzu?Nm#0b@#FdMld5FIHe;)a#;-h%IcREK|K2`s=kO!jrkV z9`u*`Ms#^&^el(dTckLYh2XK_EJ{c^Ad7A z$5MQPh<#k*4K7TDZX-jRDvuN?)9(JJ+`IZOUgjhooxqLqrkfL*)PDc#WgV-D!-QZY z2J0jR?ndg)qHcC>dUOE#iS7Z?JK2Tn9yalPZ%D1*_~ss, YEAR. +# FIRST AUTHOR \>, 2023. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-05-07 21:35+0330\n" +"POT-Creation-Date: 2023-07-04 09:31+0330\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Mahdi Rahimi \n" "Language: fa\n" @@ -16,40 +16,45 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:88 + +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا شده با فاصله باشد" -#: authentication.py:114 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" -#: authentication.py:126 authentication.py:153 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" -#: authentication.py:131 +#: authentication.py:132 msgid "User not found" msgstr "کاربر یافت نشد" -#: authentication.py:134 +#: authentication.py:135 msgid "User is inactive" msgstr "کاربر غیرفعال است" +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "رمز عبور کاربر تغییر کرده است" + #: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" #: backends.py:75 msgid "You must have cryptography installed to use {}." -msgstr "msgstr "نوع ناشناخته "{}"، leeway باید از نوع int، float یا timedelta باشد."" +msgstr "برای استفاده از {} باید رمزنگاری را نصب کرده باشید." #: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." -msgstr "" +msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:52 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" @@ -61,7 +66,7 @@ msgstr "الگوریتم نامعتبر مشخص شده است" msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: settings.py:71 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -87,30 +92,30 @@ msgstr "زمان انقضا" msgid "Token Blacklist" msgstr "لیست سیاه توکن" -#: tokens.py:38 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:110 +#: tokens.py:116 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:123 +#: tokens.py:128 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:126 +#: tokens.py:131 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:185 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:190 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:247 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.mo index 6731a91a948a2234262e714f4c1c4b2d9b348195..b43b671dd0758c0457d934ec2082a456b74140e8 100644 GIT binary patch delta 912 zcmYMx-%C?r7{Kv&(`ni-GqqnrFGZXJTcH?4URD&bQVFs}#L07XgY6tSn~6nuAz6$O zg!DJ43mS70EW7Tao4km4m(WE-H+9=((Dyl0eBpgR?|FYd?{n&1|9a-WcQ(IPl%v#M z>L2PU>W2soWjLzT5RPCUzQohGj>qsP_M>W2>J|*3?4L(DZw2?`M;ySfcnI5@!|^$F zg3bX3`mqZyZ+REx0uMD7@H)Q14*ZMzuqCF{Iqb%Eyt3sma+kV?EL9Is9_OHgBP~kZ zP;*MXqjQIWXsc2eFp0PE6+XgWIEeRmHD0!elC2t!;uk!RR+~~iIEFIsqlE>O09R2m z`2)}5aiX=kUnS^hETe4Pz$E_0gLrj!!z9X!JY-4*D1S-Pxm{#@yL8g&-ujSC5oefT z{#aO!&?e+UNk3T$4=1>=?4gzaMsmU+WROIt!_uMbrAk`m#ZrhxbyUwpFGWtKTs@t0 z11qPe>|Acf4;-DcbNZp{dU`x%dy}qHwVPs*YhK`v`;%V!vFqsk?3AmmCr_Po0?g!zc3a3ZN)5^idm*>O6L7$akJPMt(bECxn{CzO4W_l z^@v?xU`I{Y7Z_X%+qb5~8VT4GcOvGnB~B^J=2e!5y9k>#jkuXy+KF7tdb4KA@x?;h F=l?2Kz^woP delta 623 zcmX}pze_?<6u|N0Q_Jj!\n" +"POT-Creation-Date: 2023-07-06 12:57+0330\n" +"Last-Translator: Mahdi Rahimi \n" "Language: fa_IR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا شده با فاصله باشد" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "کاربر یافت نشد" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "رمز عبور کاربر تغییر کرده است" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "برای استفاده از {} باید رمزنگاری را نصب کرده باشید." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." -msgstr "" +msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "الگوریتم نامعتبر مشخص شده است" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "تنظیمات '{}' حذف شده است. لطفا به '{}' برای تنظیمات موجود مراجعه کنید." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "کاربر" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "زمان ایجاد" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "زمان انقضا" @@ -82,30 +86,30 @@ msgstr "زمان انقضا" msgid "Token Blacklist" msgstr "لیست سیاه توکن" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" From 6c52647c4ec2a79c6ab57ba8314eb228346cddf7 Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Wed, 9 Aug 2023 20:31:21 +0300 Subject: [PATCH 085/171] Release version 5.3.0 (#735) --- CHANGELOG.md | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 196f48d1e..3eea04cde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,29 +1,48 @@ -## Unreleased - -* Added support for Python 3.11 by @joshuadavidthomas in https://github.com/jazzband/djangorestframework-simplejwt/pull/636. +## 5.3.0 + +#### Notable Changes: +* Added support for Python 3.11 by @joshuadavidthomas [#636](https://github.com/jazzband/djangorestframework-simplejwt/pull/636) +* Added support for Django 4.2 by @johnthagen [#711](https://github.com/jazzband/djangorestframework-simplejwt/pull/711) +* Added support for DRF 3.14 by @Andrew-Chen-Wang [#623](https://github.com/jazzband/djangorestframework-simplejwt/pull/623) +* Added Inlang to facilitate community translations by @jannesblobel [#662](https://github.com/jazzband/djangorestframework-simplejwt/pull/662) +* Revoke access token if user password is changed by @mahdirahimi1999 [#719](https://github.com/jazzband/djangorestframework-simplejwt/pull/719) +* Added type hints by @abczzz13 [#683](https://github.com/jazzband/djangorestframework-simplejwt/pull/683) +* Improved testing by @kiraware [#688](https://github.com/jazzband/djangorestframework-simplejwt/pull/688) +* Removed support for Django 2.2 by @kiraware [#688](https://github.com/jazzband/djangorestframework-simplejwt/pull/688) + +#### Documentation: +* Added write_only=True to TokenBlacklistSerializer's refresh field for better doc generation by @Yaser-Amiri [#699](https://github.com/jazzband/djangorestframework-simplejwt/pull/699) +* Updated docs on serializer customization by @2ykwang [#668](https://github.com/jazzband/djangorestframework-simplejwt/pull/668) + +#### Translation Updates: +* Updated translations for Persian (fa) language by @mahdirahimi1999 [#723](https://github.com/jazzband/djangorestframework-simplejwt/pull/723) and https://github.com/jazzband/djangorestframework-simplejwt/pull/708 +* Updated translations for Indonesian (id) language by @kiraware [#685](https://github.com/jazzband/djangorestframework-simplejwt/pull/685) +* Added Arabic language translations by @iamjazzar [#690](https://github.com/jazzband/djangorestframework-simplejwt/pull/690) +* Added Hebrew language translations by @elam91 [#679](https://github.com/jazzband/djangorestframework-simplejwt/pull/679) +* Added Slovenian language translations by @banDeveloper [#645](https://github.com/jazzband/djangorestframework-simplejwt/pull/645) ## Version 5.2.2 Major security release -* Revert #605 in https://github.com/jazzband/djangorestframework-simplejwt/pull/629 -* Fix typo in blacklist_app.rst by @cbscsm in https://github.com/jazzband/djangorestframework-simplejwt/pull/593 +* Revert #605 [#629](https://github.com/jazzband/djangorestframework-simplejwt/pull/629) +* Fix typo in blacklist_app.rst by @cbscsm [#593](https://github.com/jazzband/djangorestframework-simplejwt/pull/593) ## Version 5.2.1 -* Add Swedish translations by @PasinduPrabhashitha in https://github.com/jazzband/djangorestframework-simplejwt/pull/579 -* Fixed issue #543 by @armenak-baburyan in https://github.com/jazzband/djangorestframework-simplejwt/pull/586 -* Fix uncaught exception with JWK by @jerr0328 in https://github.com/jazzband/djangorestframework-simplejwt/pull/600 -* Test on Django 4.1 by @2ykwang in https://github.com/jazzband/djangorestframework-simplejwt/pull/604 +* Add Swedish translations by @PasinduPrabhashitha [#579](https://github.com/jazzband/djangorestframework-simplejwt/pull/579) +* Fixed issue #543 by @armenak-baburyan [#586](https://github.com/jazzband/djangorestframework-simplejwt/pull/586) +* Fix uncaught exception with JWK by @jerr0328 [#600](https://github.com/jazzband/djangorestframework-simplejwt/pull/600) +* Test on Django 4.1 by @2ykwang [#604](https://github.com/jazzband/djangorestframework-simplejwt/pull/604) ## Version 5.2.0 -* Remove the JWTTokenUserAuthentication from the Experimental Features #546 by @byrpatrick in https://github.com/jazzband/djangorestframework-simplejwt/pull/547 -* Fix leeway type error by @2ykwang in https://github.com/jazzband/djangorestframework-simplejwt/pull/554 -* Add info on TokenBlacklistView to the docs by @inti7ary in https://github.com/jazzband/djangorestframework-simplejwt/pull/558 -* Update JWTStatelessUserAuthentication docs by @2ykwang in https://github.com/jazzband/djangorestframework-simplejwt/pull/561 -* Allow none jti claim token type claim by @denniskeends in https://github.com/jazzband/djangorestframework-simplejwt/pull/567 -* Allow customizing token JSON encoding by @vainu-arto in https://github.com/jazzband/djangorestframework-simplejwt/pull/568 +* Remove the JWTTokenUserAuthentication from the Experimental Features #546 by @byrpatrick [#547](https://github.com/jazzband/djangorestframework-simplejwt/pull/547) +* Fix leeway type error by @2ykwang [#554](https://github.com/jazzband/djangorestframework-simplejwt/pull/554) +* Add info on TokenBlacklistView to the docs by @inti7ary [#558](https://github.com/jazzband/djangorestframework-simplejwt/pull/558) +* Update JWTStatelessUserAuthentication docs by @2ykwang [#561](https://github.com/jazzband/djangorestframework-simplejwt/pull/561) +* Allow none jti claim token type claim by @denniskeends [#567](https://github.com/jazzband/djangorestframework-simplejwt/pull/567) +* Allow customizing token JSON encoding by @vainu-arto [#568](https://github.com/jazzband/djangorestframework-simplejwt/pull/568) ## Version 5.1.0 From 16866f538e79c39a84676433cdef35b1dd5c72bc Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Thu, 10 Aug 2023 16:27:13 +0300 Subject: [PATCH 086/171] Sync .mo files (#736) --- .../locale/id_ID/LC_MESSAGES/django.mo | Bin 2374 -> 2528 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.mo index c18aaf4a9bb1d90ad49228a3ec729eaa679c43b0..4a56a2ee990db904a6ea04913b0d3ff7cdb2596d 100644 GIT binary patch delta 775 zcmYk(O=}ZD7{KvKn$)($R#RVEYjHG$C?+*ci^NbNY7Z6zLd^$o(oB;j>2BCe45?`S z2txEKdhw#S9uzzjJb3XUwBX4X#G{BGz=Qwk2JFMm{$_S|XP#&FL;U;X*4KFCsUW6l zr)fWFN!sfWH=-C8VhOKd8Xw|$e1$W(hdKO%w=ppktkcE`#*c9UpW{i~8$ADoM}^oD zf9V`!VmuOf zVV?cPE}bL~VuyrS#vIx{6aalNz1N_y}z!Z_rly9&IJN$hYD%+P`w5{~|PV)}EP-!vSIv`3L)9x1a8R z2_AKUv$4(d@|_-<}Pxgm1dOUh`_Mv#G1n^jcb`?mtMSWvZ!lSM^eIqtiCB zqNTSUOgpYg%k`$GjP!hIoDE&oO{3=e)yTV2W>w#F+K%UDmX*;3nak!DGFh%GGMg{V zFJ8U%|e`2bpy3aB;lJDXu9$*_@h4c5=EK-&yf;0>NLsPNp z#u?O@FJKcE@iT7Y2<~A5FG4HG7IKR`@|)osMf|~O^7KcMF`UN<+{XdFFBO6U6aR1l z2Wv%ov5ZOlg?YTdZhXO@lGZwrFF1@;BC{CW;t~e$mqL#)DDW~|zr(NOkC^Bu=!#b> z%wSN#B(f&c82p76|18qclOhUQLzTCqap!L>I8M9&9O>%{CxkOfYnXgOEIn6Z8tZtaPX=>T=+^8{VWDO(nLzO&z(N%V7LwSyy(;Uav tl)Gvvdu7Mcrbvh1)BM_|vNq1IKjdrt`S?uzx@&ED&YG)ME&nv0e+A$zQ_uha From faf92e8e0894f2e744fc4451289ba26278e50bd5 Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Fri, 11 Aug 2023 00:39:06 +0300 Subject: [PATCH 087/171] Sync .mo files (#737) --- .../locale/ar/LC_MESSAGES/django.po | 60 ++++++++++--------- .../locale/cs/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/de/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/es/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/es_AR/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/es_CL/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/fr/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/he_IL/LC_MESSAGES/django.po | 60 ++++++++++--------- .../locale/id_ID/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/it_IT/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/ko_KR/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/nl_NL/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/pl_PL/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/pt_BR/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/ro/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/ru_RU/LC_MESSAGES/django.po | 54 +++++++++-------- .../locale/sl/LC_MESSAGES/django.po | 56 +++++++++-------- .../locale/sv/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/tr/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/uk_UA/LC_MESSAGES/django.po | 50 +++++++++------- .../locale/zh_Hans/LC_MESSAGES/django.po | 50 +++++++++------- 21 files changed, 583 insertions(+), 497 deletions(-) diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po index 426e6d113..bd831256d 100644 --- a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po @@ -10,73 +10,79 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" - -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "يجب أن يحتوي رأس التفويض على قيمتين مفصولتين بمسافات" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "تأشيرة المرور غير صالحة لأي نوع من أنواع التأشيرات" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "لا تحتوي تأشيرة المرور على هوية مستخدم يمكن التعرف عليها" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "لم يتم العثور على المستخدم" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "الحساب غير مفعل" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الخوارزمية غير معروف '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "يجب أن يكون لديك تشفير مثبت لاستخدام {}." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." -msgstr "نوع غير معروف '{}'. يجب أن تكون 'leeway' عددًا صحيحًا أو عددًا نسبيًا أو فرق وقت." +msgstr "" +"نوع غير معروف '{}'. يجب أن تكون 'leeway' عددًا صحيحًا أو عددًا نسبيًا أو فرق وقت." -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "تأشيرة المرور غير صالحة أو منتهية الصلاحية" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "تم تحديد خوارزمية غير صالحة" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." -msgstr "تمت إزالة الإعداد '{}'. يرجى الرجوع إلى '{}' للتعرف على الإعدادات المتاحة." +msgstr "" +"تمت إزالة الإعداد '{}'. يرجى الرجوع إلى '{}' للتعرف على الإعدادات المتاحة." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "المستخدم" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "أنشئت في" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "تنتهي في" @@ -84,30 +90,30 @@ msgstr "تنتهي في" msgid "Token Blacklist" msgstr "قائمة تأشيرات المرور السوداء" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "لا يمكن إنشاء تأشيرة مرور بدون نوع أو عمر" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "التأشيرة ليس لها معرف" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "التأشيرة ليس لها نوع" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "التأشيرة لها نوع خاطئ" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "التأشيرة ليس لديها مطالبة '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "انتهى عمر المطالبة بالتأشيرة '{}'" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "التأشيرة مدرجة في القائمة السوداء" diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index 5f827c050..e26482e58 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -11,70 +11,74 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "Autorizační hlavička musí obsahovat dvě hodnoty oddělené mezerou" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Daný token není validní pro žádný typ tokenu" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Token neobsahoval žádnou rozpoznatelnou identifikaci uživatele" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Uživatel nenalezen" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Uživatel není aktivní" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Nerozpoznaný typ algoritmu '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "Nastavení '{}' bylo odstraněno. Dostupná nastavení jsou v '{}'" -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "uživatel" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "vytvořený v" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "platí do" @@ -82,30 +86,30 @@ msgstr "platí do" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Nelze vytvořit token bez zadaného typu nebo životnosti" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token nemá žádný identifikátor" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token nemá žádný typ" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Token má špatný typ" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token nemá žádnou hodnotu '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Hodnota tokenu '{}' vypršela" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po index 39954f752..bbc09cc66 100644 --- a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po @@ -12,53 +12,57 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "Der Authorizationheader muss zwei leerzeichen-getrennte Werte enthalten" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Der Token ist für keinen Tokentyp gültig" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Token enthält keine erkennbare Benutzeridentifikation" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Benutzer nicht gefunden" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Inaktiver Benutzer" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Unerkannter Algorithmustyp '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -66,19 +70,19 @@ msgstr "" "Die Einstellung '{}' wurde gelöscht. Bitte beachte '{}' für verfügbare " "Einstellungen." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "Benutzer" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "erstellt am" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "läuft ab am" @@ -86,30 +90,30 @@ msgstr "läuft ab am" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Ein Token ohne Typ oder Lebensdauer kann nicht erstellt werden" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token hat keine Id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token hat keinen Typ" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Token hat den falschen Typ" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token hat kein '{}' Recht" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Das Tokenrecht '{}' ist abgelaufen" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index f0b787506..32747208e 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -12,53 +12,57 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "El encabezado 'Authorization' debe contener valores delimitados por espacios" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "El token dado no es valido para ningun tipo de token" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "El token no contenía identificación de usuario reconocible" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Debe tener criptografía instalada para usar {}." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "Algoritmo especificado no válido" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "La combinación de credenciales no tiene una cuenta activa" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -66,19 +70,19 @@ msgstr "" "La configuración '{}' fue removida. Por favor, refiérase a '{}' para " "consultar las disponibles." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "usuario" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "creado en" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "expira en" @@ -86,30 +90,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "No se puede crear un token sin tipo o de tan larga vida" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index 7a290a5d2..14ff0fc11 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -17,54 +17,58 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "El header de autorización debe contener dos valores delimitados por espacio" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "El token dado no es válido para ningún tipo de token" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "El token no contiene ninguna identificación de usuario" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales dadas" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -72,19 +76,19 @@ msgstr "" "La configuración '{}' fue removida. Por favor, refiérase a '{}' para " "consultar las configuraciones disponibles." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "usuario" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "creado en" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "expira en" @@ -92,30 +96,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "El token está en la lista negra" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index bf67fed49..1495e5f8d 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -12,54 +12,58 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "El header de autorización debe contener dos valores delimitados por espacio" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "El token provisto no es válido para ningún tipo de token" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "El token no contiene identificación de usuario reconocible" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "El usuario está inactivo" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Token inválido o expirado" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -67,19 +71,19 @@ msgstr "" "La configuración '{}' fue removida. Por favor, refiérase a '{}' para " "configuraciones disponibles." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "Usuario" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "creado en" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "expira en" @@ -87,30 +91,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token no tiene id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token no tiene tipo" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Token tiene tipo erróneo" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token no tiene privilegio '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "El provilegio '{}' del token está expirado" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index 021b39f57..996248843 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -11,54 +11,58 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "L'en-tête 'Authorization' doit contenir deux valeurs séparées par des espaces" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Le type de jeton fourni n'est pas valide" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "" "Le jeton ne contient aucune information permettant d'identifier l'utilisateur" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "L'utilisateur n'a pas été trouvé" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "L'utilisateur est désactivé" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Type d'algorithme non reconnu '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Vous devez installer cryptography afin d'utiliser {}." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "L'algorithme spécifié est invalide" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -66,19 +70,19 @@ msgstr "" "Le paramètre '{}' a été supprimé. Voir '{}' pour la liste des paramètres " "disponibles." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "Utilisateur" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "Créé le" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "Expire le" @@ -86,30 +90,30 @@ msgstr "Expire le" msgid "Token Blacklist" msgstr "Liste des jetons bannis" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Ne peut pas créer de jeton sans type ni durée de vie" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Le jeton n'a pas d'id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Le jeton n'a pas de type" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Le jeton a un type erroné" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Le jeton n'a pas le privilège '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Le privilège '{}' du jeton a expiré" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po index adf878bdf..88295a48d 100644 --- a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po @@ -12,76 +12,78 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n" -"%10==0 ? 2 : 3);\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==2 ? 1 : n>10 && n%10==0 ? " +"2 : 3);\n" "X-Generator: Poedit 3.2.2\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "Authorization Header חייבת להכיל שני ערכים מופרדים ברווח" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "המזהה הנתון אינו תקף עבור אף סיווג" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "המזהה לא הכיל זיהוי משתמש שניתן לזהות" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "משתמש לא נמצא" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "המשתמש אינו פעיל" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "סוג אלגוריתם לא מזוהה '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "עליך להתקין קריפטוגרפיה כדי להשתמש ב-{}." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." -msgstr "" -"סוג לא מזוהה '{}', 'leeway' חייב להיות מסוג int, float או timedelta." +msgstr "סוג לא מזוהה '{}', 'leeway' חייב להיות מסוג int, float או timedelta." -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "המזהה אינו חוקי או שפג תוקפו" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "צוין אלגוריתם לא חוקי" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." -msgstr "" -"ההגדרה '{}' הוסרה. בבקשה קראו כאן: '{}' בשביל לראות הגדרות אפשרויות" +msgstr "ההגדרה '{}' הוסרה. בבקשה קראו כאן: '{}' בשביל לראות הגדרות אפשרויות" -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "משתמש" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "נוצר בשעה" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "פג תוקף בשעה" @@ -89,30 +91,30 @@ msgstr "פג תוקף בשעה" msgid "Token Blacklist" msgstr "רשימה שחורה של מזהים" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "לא ניתן ליצור מזהה ללא סוג או אורך חיים" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "למזהה אין מספר זיהוי" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "למזהה אין סוג" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "למזהה יש סוג לא נכון" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "למזהה אין '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "מזהה '{}' פג תוקף" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "המזהה ברשימה השחורה." diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index f714d02b3..485cb54e1 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -16,53 +16,57 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "Header otorisasi harus berisi dua nilai yang dipisahkan spasi" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Token yang diberikan tidak valid untuk semua jenis token" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Token tidak mengandung identifikasi pengguna yang dapat dikenali" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Pengguna tidak ditemukan" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Pengguna tidak aktif" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Jenis algoritma tidak dikenal '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Anda harus memasang cryptography untuk menggunakan {}." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "Tipe '{}' tidak dikenali, 'leeway' harus bertipe int, float, atau timedelta." -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "Algoritma yang ditentukan tidak valid" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -70,19 +74,19 @@ msgstr "" "Setelan '{}' telah dihapus. Silakan merujuk ke '{}' untuk pengaturan yang " "tersedia." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "pengguna" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "created at" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "kedaluwarsa pada" @@ -90,30 +94,30 @@ msgstr "kedaluwarsa pada" msgid "Token Blacklist" msgstr "Daftar Hitam Token" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Tidak dapat membuat token tanpa tipe atau masa pakai" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token tidak memiliki id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token tidak memiliki tipe" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Jenis token salah" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token tidak memiliki klaim '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Klaim token '{}' telah kedaluwarsa" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index 48837431c..fa380ae89 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -15,53 +15,57 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "L'header di autorizzazione deve contenere due valori delimitati da uno spazio" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Il token dato non è valido per qualsiasi tipo di token" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Il token non conteneva nessuna informazione riconoscibile dell'utente" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Utente non trovato" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Utente non attivo" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Algoritmo di tipo '{}' non riconosciuto" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Devi avere installato cryptography per usare '{}'." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "L'algoritmo specificato non è valido" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Nessun account attivo trovato con queste credenziali" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -69,19 +73,19 @@ msgstr "" "L'impostazione '{}' è stata rimossa. Per favore utilizza '{}' per " "visualizzare le impostazioni valide." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "utente" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "creato il" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "scade il" @@ -89,30 +93,30 @@ msgstr "scade il" msgid "Token Blacklist" msgstr "Blacklist dei token" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Impossibile creare un token senza tipo o durata" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Il token non ha un id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Il token non ha un tipo" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Il token ha un tipo sbagliato" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Il token non contiene il parametro '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Il parametro '{}' del token è scaduto" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index 0b6df170c..22942641f 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -12,72 +12,76 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "인증 헤더에는 공백으로 구분 된 두 개의 값이 포함되어야 합니다" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "이 토큰은 모든 타입의 토큰에 대해 유효하지 않습니다" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "토큰에 사용자 식별자가 포함되어 있지 않습니다" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "찾을 수 없는 사용자" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "비활성화된 사용자" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "알 수 없는 알고리즘 유형 '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "{}를 사용하려면 암호화가 설치되어 있어야 합니다." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "알 수 없는 타입 '{}', 'leeway' 값은 반드시 int, float 또는 timedelta 타입이어" "야 합니다." -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "유효하지 않거나 만료된 토큰" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "잘못된 알고리즘이 지정되었습니다" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "'{}' 설정이 제거되었습니다. 사용 가능한 설정은 '{}'을 참조하십시오." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "사용자" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "생성 시간" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "만료 시간" @@ -85,30 +89,30 @@ msgstr "만료 시간" msgid "Token Blacklist" msgstr "토큰 블랙리스트" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "타입 또는 수명이 없는 토큰을 생성할 수 없습니다" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "토큰에 식별자가 주어지지 않음" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "토큰 타입이 주어지지 않음" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "잘못된 토큰 타입" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "토큰에 '{}' 클레임이 없음" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "토큰 '{}' 클레임이 만료되었습니다" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "블랙리스트에 추가된 토큰" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index f24fc31e7..6b3bc0de5 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -11,72 +11,76 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "Authorisatie header moet twee waarden bevatten, gescheiden door een spatie" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Het token is voor geen enkel token-type geldig" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Token bevat geen herkenbare gebruikersidentificatie" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Gebruiker niet gevonden" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Gebruiker is inactief" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Niet herkend algoritme type '{}" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Token is niet geldig of verlopen" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Geen actief account gevonden voor deze gegevens" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "" "De '{}' instelling bestaat niet meer. Zie '{}' for beschikbareinstellingen." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "gebruiker" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "aangemaakt op" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "verloopt op" @@ -84,30 +88,30 @@ msgstr "verloopt op" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Kan geen token maken zonder type of levensduur" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token heeft geen id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token heeft geen type" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Token heeft het verkeerde type" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token heeft geen '{}' recht" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Token '{}' recht is verlopen" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index 89212095c..ed09ea23b 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -11,71 +11,75 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "Nagłówek autoryzacji musi zawierać dwie wartości rodzielone spacjami" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Podany token jest błędny dla każdego typu tokena" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Token nie zawierał rozpoznawalnej identyfikacji użytkownika" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Użytkownik nie znaleziony" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Użytkownik jest nieaktywny" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Nierozpoznany typ algorytmu '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Token jest niepoprawny lub wygasł" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "" "Ustawienie '{}' zostało usunięte. Dostępne ustawienia znajdują sie w '{}'" -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "użytkownik" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "stworzony w" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "wygasa o" @@ -83,30 +87,30 @@ msgstr "wygasa o" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Nie można utworzyć tokena bez podanego typu lub żywotności" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token nie posiada numeru identyfikacyjnego" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token nie posiada typu" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Token posiada zły typ" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token nie posiada upoważnienia '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Upoważnienie tokena '{}' wygasło" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index 36e2e1da3..3c171183e 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -12,53 +12,57 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "Cabeçalho de autorização deve conter dois valores delimitados por espaço" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "O token informado não é válido para qualquer tipo de token" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "O token não continha nenhuma identificação reconhecível do usuário" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Usuário não encontrado" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Usuário está inativo" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo '{}' não reconhecido" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Você deve ter criptografia instalada para usar {}." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "O token é inválido ou expirado" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "Algoritmo inválido especificado" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -66,19 +70,19 @@ msgstr "" "A configuração '{}' foi removida. Por favor, consulte '{}' para disponível " "definições." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "usuário" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "criado em" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "expira em" @@ -86,30 +90,30 @@ msgstr "expira em" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Não é possível criar token sem tipo ou tempo de vida" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token não tem id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token não tem nenhum tipo" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Token tem tipo errado" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token não tem '{}' privilégio" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "O privilégio '{}' do token expirou" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po index 3a8d5d036..09b919606 100644 --- a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -12,75 +12,79 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "Header-ul(antetul) de autorizare trebuie să conțină două valori separate " "prin spațiu" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Tokenul dat nu este valid pentru niciun tip de token" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Tokenul nu conține date de identificare a utilizatorului" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Utilizatorul nu a fost găsit" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Utilizatorul este inactiv" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Tipul de algoritm '{}' nu este recunoscut" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Trebuie să aveți instalată criptografia pentru a utiliza {}." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "Tipul '{}' nu este recunoscut, 'leeway' trebuie să fie de tip int, float sau " "timedelta." -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Token nu este valid sau a expirat" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "Algoritm nevalid specificat" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "" "Setarea '{}' a fost ștearsă. Referați la '{}' pentru setări disponibile." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "utilizator" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "creat la" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "expiră la" @@ -88,30 +92,30 @@ msgstr "expiră la" msgid "Token Blacklist" msgstr "Listă de token-uri blocate" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Nu se poate crea token fără tip sau durată de viață" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Tokenul nu are id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Tokenul nu are tip" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Tokenul are tipul greșit" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Tokenul nu are reclamația '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Reclamația tokenului '{}' a expirat" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Tokenul este în listă de tokenuri blocate" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index 02da98bfd..b86361a2d 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -12,57 +12,61 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" "X-Generator: Poedit 2.2.1\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "Заголовок авторизации должен содержать два значения, разделенных пробелом" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Данный токен недействителен для любого типа токена" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Токен не содержит идентификатор пользователя" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Пользователь не найден" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Пользователь неактивен" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Нераспознанный тип алгоритма '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Токен недействителен или просрочен" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Не найдено активной учетной записи с указанными данными" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -70,19 +74,19 @@ msgstr "" "Параметр '{}' был удален. Пожалуйста, обратитесь к '{}' для просмотра " "доступных настроек." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "пользователь" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "создан" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "истекает" @@ -90,30 +94,30 @@ msgstr "истекает" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Невозможно создать токен без типа или времени жизни" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "У токена нет идентификатора" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Токен не имеет типа" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Токен имеет неправильный тип" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Токен не содержит '{}'" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Токен имеет просроченное значение '{}'" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po index b71388344..65924259e 100644 --- a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po @@ -15,72 +15,78 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" -msgstr "Glava 'Authorization' mora vsebovati dve vrednosti, ločeni s presledkom" +msgstr "" +"Glava 'Authorization' mora vsebovati dve vrednosti, ločeni s presledkom" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Podan žeton ni veljaven za nobeno vrsto žetona" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Žeton ni vseboval prepoznavne identifikacije uporabnika" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Uporabnik ni najden" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Uporabnik je neaktiven" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Neprepoznana vrsta algoritma'{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Za uporabo '{}' je potrebna namestitev 'cryptography'." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "Neprepoznana vrsta '{}', 'leeway' mora biti vrste int, float ali timedelta." -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Žeton je neveljaven ali potekel" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "Naveden algoritem je neveljaven" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Aktiven račun s podanimi poverilnicami ni najden" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "" -"Nastavitev '{}' je bila odstranjena. Prosimo, oglejte si '{}' za razpoložljive nastavitve." +"Nastavitev '{}' je bila odstranjena. Prosimo, oglejte si '{}' za " +"razpoložljive nastavitve." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "uporabnik" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "ustvarjen ob" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "poteče ob" @@ -88,30 +94,30 @@ msgstr "poteče ob" msgid "Token Blacklist" msgstr "Črni seznam žetonov" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Ni mogoče ustvariti žetona brez vrste ali življenjske dobe" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Žetonu manjka id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Žetonu manjka vrsta" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Žeton je napačne vrste" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Žeton nima '{}' zahtevka" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "'{}' zahtevek žetona je potekel" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Žeton je na črnem seznamu" diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po index 6e12ed405..8ffcd8968 100644 --- a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -12,71 +12,75 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "Auktoriseringshuvudet måste innehålla två mellanslagsavgränsade värden" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Givet token är inte giltigt för någon tokentyp" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Token innehöll ingen identifiering av användaren" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Användaren hittades inte" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Användaren är inaktiv" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Okänd algoritmtyp '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Du måste ha kryptografi installerad för att kunna använda {}." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Token är ogiltig eller har löpt ut" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "Ogiltig algoritm har angetts" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "" "Inställningen '{}' har tagits bort. Se '{}' för tillgängliga inställningar" -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "användare" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "skapad vid" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "går ut kl" @@ -84,30 +88,30 @@ msgstr "går ut kl" msgid "Token Blacklist" msgstr "Token svartlist" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Kan inte skapa token utan typ eller livslängd" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token har inget id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token har ingen typ" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Token har fel typ" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token har inget '{}'-anspråk" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Token '{}'-anspråket har löpt ut" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token är svartlistad" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 751e0312b..f26ac0384 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -12,72 +12,76 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "" "Yetkilendirme header'i boşlukla sınırlandırılmış iki değer bulundurmak " "zorunda" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Verilen token hiçbir token tipi için geçerli değil" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Token tanınabilir bir kullanıcı kimliği içermiyor" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Kullanıcı bulunamadı" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Kullanıcı etkin değil" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Tanınmayan algortima tipi '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "{} kullanmak için cryptography yüklemeniz gerekiyor." -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Token geçersiz veya süresi geçmiş" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "Geçersiz algoritma belirtildi" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "'{}' ayarı kaldırıldı. Mevcut ayarlar için '{}' adresini ziyaret edin." -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "kullanıcı" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "oluşturulma tarihi" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "sona erme tarihi" @@ -85,30 +89,30 @@ msgstr "sona erme tarihi" msgid "Token Blacklist" msgstr "Token Kara Listesi" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Tipi veya geçerlilik süresi olmayan token oluşturulamaz" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "Token'in id'si yok" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "Token'in tipi yok" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "Token'in tipi yanlış" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "Token'in '{}' claim'i yok" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Token'in '{}' claim'i sona erdi" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Token kara listeye alınmış" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index 838654c06..ae344213f 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -15,70 +15,74 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "Авторизаційний заголовок має містити два значення розділені пробілом" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "Наданий токен не відповідає жодному типу ключа" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "Наданий токен не мітить жодної ідентифікаційної інформації" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "Користувач не знайдений" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "Користувач неактивний" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "Тип алгоритму '{}' не розпізнаний" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "Встановіть модуль cryptography щоб використовувати {}" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "Токен некоректний або термін його дії вичерпаний" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "Вказаний невірний алгоритм" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "Налаштування '{}' видалене. Подивіться у '{}' для інших доступних" -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "користувач" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "створений о" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "дійстний по" @@ -86,30 +90,30 @@ msgstr "дійстний по" msgid "Token Blacklist" msgstr "Чорний список токенів" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "Неможливо створити токен без типу або строку дії" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "У ключі доступу не міститься id" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "У ключі доступу не міститься тип" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "токен позначений невірним типом" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "У токені не міститься '{}' заголовку" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "Заголовок '{}' токена не дійсний" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index 443106e1d..fd45a4e16 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -15,70 +15,74 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:78 +#: authentication.py:89 msgid "Authorization header must contain two space-delimited values" msgstr "授权头必须包含两个用空格分隔的值" -#: authentication.py:104 +#: authentication.py:115 msgid "Given token not valid for any token type" msgstr "此令牌对任何类型的令牌无效" -#: authentication.py:116 authentication.py:143 +#: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" msgstr "令牌未包含用户标识符" -#: authentication.py:121 +#: authentication.py:132 msgid "User not found" msgstr "未找到该用户" -#: authentication.py:124 +#: authentication.py:135 msgid "User is inactive" msgstr "该用户已禁用" -#: backends.py:67 +#: authentication.py:142 +msgid "The user's password has been changed." +msgstr "" + +#: backends.py:69 msgid "Unrecognized algorithm type '{}'" msgstr "未知算法类型 '{}'" -#: backends.py:73 +#: backends.py:75 msgid "You must have cryptography installed to use {}." msgstr "你必须安装 cryptography 才能使用 {}。" -#: backends.py:88 +#: backends.py:90 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:102 backends.py:152 exceptions.py:38 tokens.py:44 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" msgstr "令牌无效或已过期" -#: backends.py:150 +#: backends.py:152 msgid "Invalid algorithm specified" msgstr "指定的算法无效" -#: serializers.py:30 +#: serializers.py:35 msgid "No active account found with the given credentials" msgstr "找不到指定凭据对应的有效用户" -#: settings.py:70 +#: settings.py:73 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." msgstr "'{}' 配置已被移除。 请参阅 '{}' 获取可用的配置。" -#: token_blacklist/admin.py:68 +#: token_blacklist/admin.py:79 msgid "jti" msgstr "jti" -#: token_blacklist/admin.py:74 +#: token_blacklist/admin.py:85 msgid "user" msgstr "用户" -#: token_blacklist/admin.py:80 +#: token_blacklist/admin.py:91 msgid "created at" msgstr "创建时间" -#: token_blacklist/admin.py:86 +#: token_blacklist/admin.py:97 msgid "expires at" msgstr "过期时间" @@ -86,30 +90,30 @@ msgstr "过期时间" msgid "Token Blacklist" msgstr "令牌黑名单" -#: tokens.py:30 +#: tokens.py:44 msgid "Cannot create token with no type or lifetime" msgstr "无法创建没有类型或生存期的令牌" -#: tokens.py:102 +#: tokens.py:116 msgid "Token has no id" msgstr "令牌没有标识符" -#: tokens.py:115 +#: tokens.py:128 msgid "Token has no type" msgstr "令牌没有类型" -#: tokens.py:118 +#: tokens.py:131 msgid "Token has wrong type" msgstr "令牌类型错误" -#: tokens.py:170 +#: tokens.py:190 msgid "Token has no '{}' claim" msgstr "令牌没有 '{}' 声明" -#: tokens.py:175 +#: tokens.py:195 msgid "Token '{}' claim has expired" msgstr "令牌 '{}' 声明已过期" -#: tokens.py:230 +#: tokens.py:257 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" From 19cf38e4a440fd648e82a94a7998ac857d48a28d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliv=C3=A9r=20Kecskem=C3=A9ty?= Date: Mon, 30 Oct 2023 18:04:35 +0100 Subject: [PATCH 088/171] Remove EOL Python, Django and DRF versions (#754) * Replace deprecated pkg_resources method --- .github/workflows/test.yml | 6 +++--- .pre-commit-config.yaml | 2 +- docs/getting_started.rst | 4 ++-- rest_framework_simplejwt/__init__.py | 6 +++--- setup.py | 6 ++---- tox.ini | 11 ++--------- 6 files changed, 13 insertions(+), 22 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b41516d59..7ce5e28aa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,9 +15,9 @@ jobs: fail-fast: false max-parallel: 5 matrix: - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] - django-version: ['3.2', '4.0', '4.1', '4.2'] - drf-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] + python-version: [ '3.8', '3.9', '3.10', '3.11'] + django-version: ['3.2', '4.1', '4.2'] + drf-version: ['3.12', '3.13', '3.14'] exclude: # DRF 3.13 is not compatible with Django 4.2. - django-version: '4.2' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2a2894302..864f1724a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -51,7 +51,7 @@ repos: rev: 'v3.7.0' hooks: - id: pyupgrade - args: ['--py37-plus', '--keep-mock'] + args: ['--py38-plus', '--keep-mock'] - repo: https://github.com/Lucas-C/pre-commit-hooks-markup rev: v1.0.1 diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 42e646187..f7db9b7f1 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -7,8 +7,8 @@ Requirements ------------ * Python (3.8, 3.9, 3.10, 3.11) -* Django (3.2, 4.0, 4.1, 4.2) -* Django REST Framework (3.10, 3.11, 3.12, 3.13, 3.14) +* Django (3.2, 4.1, 4.2) +* Django REST Framework (3.12, 3.13, 3.14) These are the officially supported python and package versions. Other versions will probably work. You're free to modify the tox config and see what is diff --git a/rest_framework_simplejwt/__init__.py b/rest_framework_simplejwt/__init__.py index 6929b410c..b001cf5d3 100644 --- a/rest_framework_simplejwt/__init__.py +++ b/rest_framework_simplejwt/__init__.py @@ -1,7 +1,7 @@ -from pkg_resources import DistributionNotFound, get_distribution +from importlib.metadata import PackageNotFoundError, version try: - __version__ = get_distribution("djangorestframework_simplejwt").version -except DistributionNotFound: + __version__ = version("djangorestframework_simplejwt") +except PackageNotFoundError: # package is not installed __version__ = None diff --git a/setup.py b/setup.py index 4fd09303f..60327eeef 100755 --- a/setup.py +++ b/setup.py @@ -56,10 +56,10 @@ author_email="davesque@gmail.com", install_requires=[ "django>=3.2", - "djangorestframework>=3.10", + "djangorestframework>=3.12", "pyjwt>=1.7.1,<3", ], - python_requires=">=3.7", + python_requires=">=3.8", extras_require=extras_require, packages=find_packages(exclude=["tests", "tests.*", "licenses", "requirements"]), include_package_data=True, @@ -69,7 +69,6 @@ "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 3.2", - "Framework :: Django :: 4.0", "Framework :: Django :: 4.1", "Framework :: Django :: 4.2", "Intended Audience :: Developers", @@ -77,7 +76,6 @@ "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", diff --git a/tox.ini b/tox.ini index 8fb68941b..e127b8b11 100644 --- a/tox.ini +++ b/tox.ini @@ -1,13 +1,12 @@ [tox] envlist= - py{37,38,39,310}-dj{32}-drf{311,312,313}-pyjwt{171,2}-tests - py{38,39,310}-dj{40,41,42}-drf313-pyjwt{171,2}-tests + py{38,39,310}-dj{32}-drf{312,313}-pyjwt{171,2}-tests + py{38,39,310}-dj{41,42}-drf313-pyjwt{171,2}-tests py311-dj{41,42}-drf{313,314}-pyjwt{171,2}-tests docs [gh-actions] python= - 3.7: py37 3.8: py38, docs 3.9: py39 3.10: py310 @@ -16,12 +15,9 @@ python= [gh-actions:env] DJANGO= 3.2: dj32 - 4.0: dj40 4.1: dj41 4.2: dj42 DRF= - 3.10: drf310 - 3.11: drf311 3.12: drf312 3.13: drf313 3.14: drf314 @@ -35,11 +31,8 @@ setenv= PYTHONDONTWRITEBYTECODE=1 deps= dj32: Django>=3.2,<3.3 - dj40: Django>=4.0,<4.1 dj41: Django>=4.1,<4.2 dj42: Django>=4.2,<4.3 - drf310: djangorestframework>=3.10,<3.11 - drf311: djangorestframework>=3.11,<3.12 drf312: djangorestframework>=3.12,<3.13 drf313: djangorestframework>=3.13,<3.14 drf314: djangorestframework>=3.14,<3.15 From ef23fb852f83ac7ec82b9ba885011c69b874ab44 Mon Sep 17 00:00:00 2001 From: JAEGYUN JUNG Date: Thu, 2 Nov 2023 14:52:52 +0900 Subject: [PATCH 089/171] Update Korean translations (#753) --- .../locale/ko_KR/LC_MESSAGES/django.mo | Bin 2720 -> 2912 bytes .../locale/ko_KR/LC_MESSAGES/django.po | 22 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.mo index 2be0e27d5fe32fd74bbac28f6da6365e265f942a..da76a4076e38057546af91cdae62525829adb471 100644 GIT binary patch delta 888 zcmY+>Pe@cj9KiA4uK)I}{joJo`vb#jX;7Q35lGu1+72Be>rmJqVsl?^5Ucr;JwzyF zwP;4Lic6q**o)|4OQOQ)*eU4dDWXFV_@+aLjzQmfyQ%$P-e=~$dB2(Y&0NE`#^JA_ z$|)gs(st7{Z7=P;j|b817m49HJb+KJ9hY$ze#a@7gSs;xH$M7^RU>*L(Em&P8atIqRh^NYSBWuZJWU5@l5Qj?Q zMaG$Gk&`kk@|liFTwha4bQOCTPv8~&fgKnRh(vG*8?k^Va2eb251JG1vqTQ!B~+M2 zQ@MFGc~P-VKV_+@e{`J7jDL*wI$3Z^cu<| zQz`c6RhS#|qM7FzbML17RK-hf5}VjWGxtVuq@HGiLP(R>D{aV>)l|X+dy%@OF8?uK zOUhP5jy>4ssDXszWcmk_DwS~5b=yv>-c%ypXD63#S2X$e%uVUp#nm@+Dt6~)rq}N4 zPbO{0Nu(2pqtULV7gZ^LMBiW3&*$~*Gd+`6?z>U9IO4v_{>;B!EsiL+IO&c&(bHKy z_SzlKy5qUZz(SzhFXUbZ_Sa73|9vauz64tS8~dy#OV2*^{w(C0t=0{r<5qk9+Ba#t sd#_EoW0NX(!wPShHDNuDtk2TL4|--)>1F;>f{4FR>XJd~Ac){nK~Yc;G%n&V{Lw{P z^`SVZWR%oF8aD_302c?_$yNs^O~Ab!`aLi4z`37y?|Ynk?|FBDq<`s8W#O(6Z^;_+ zo{W$u9tNV@5b3}kY{W&Z!|zy)*Z2XS@Dqj#a&>0V$9xN$F^N@ponOyjg~*cpJN=gKICG}X!Wtwo1d0UalN8G_U`^zsL zw2)maGKBp&j45ow;u4VnwqOtTVJ&{c2K<3x{Ed1;!=wus#3**<9m7fHUs1dL7pvJ{ z{2ad*-{VW1%e#hplO5z+*+cy+dYI?X_2;0SZYOoFbu?a){24diFzUwIMVjH(?&Q#J zlrm~tX@*p~E8HCQMj9_jZKq!+1ZNRnI&QRk(y0Q!5!l<#?5{kWZQC6aQ&WlA&m)tg zu~;m9;~h7gM9Hynxama9dS%EA1rIkRbF}}MI)B_cu(KPQ~U0u!`tvknN*!gMJ adBiEVYQ1)Jej)0#TVI?@tHyb\n" +"Last-Translator: 정재균 \n" "Language: ko_KR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -26,19 +26,19 @@ msgstr "토큰에 사용자 식별자가 포함되어 있지 않습니다" #: authentication.py:132 msgid "User not found" -msgstr "찾을 수 없는 사용자" +msgstr "찾을 수 없는 사용자입니다" #: authentication.py:135 msgid "User is inactive" -msgstr "비활성화된 사용자" +msgstr "비활성화된 사용자입니다" #: authentication.py:142 msgid "The user's password has been changed." -msgstr "" +msgstr "사용자의 비밀번호가 바뀌었습니다." #: backends.py:69 msgid "Unrecognized algorithm type '{}'" -msgstr "알 수 없는 알고리즘 유형 '{}'" +msgstr "'{}' 는 알 수 없는 알고리즘 유형입니다" #: backends.py:75 msgid "You must have cryptography installed to use {}." @@ -53,7 +53,7 @@ msgstr "" #: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 msgid "Token is invalid or expired" -msgstr "유효하지 않거나 만료된 토큰" +msgstr "유효하지 않거나 만료된 토큰입니다" #: backends.py:152 msgid "Invalid algorithm specified" @@ -95,19 +95,19 @@ msgstr "타입 또는 수명이 없는 토큰을 생성할 수 없습니다" #: tokens.py:116 msgid "Token has no id" -msgstr "토큰에 식별자가 주어지지 않음" +msgstr "토큰에 식별자가 주어지지 않았습니다" #: tokens.py:128 msgid "Token has no type" -msgstr "토큰 타입이 주어지지 않음" +msgstr "토큰 타입이 주어지지 않았습니다" #: tokens.py:131 msgid "Token has wrong type" -msgstr "잘못된 토큰 타입" +msgstr "잘못된 토큰 타입입니다" #: tokens.py:190 msgid "Token has no '{}' claim" -msgstr "토큰에 '{}' 클레임이 없음" +msgstr "토큰에 '{}' 클레임이 없습니다" #: tokens.py:195 msgid "Token '{}' claim has expired" @@ -115,4 +115,4 @@ msgstr "토큰 '{}' 클레임이 만료되었습니다" #: tokens.py:257 msgid "Token is blacklisted" -msgstr "블랙리스트에 추가된 토큰" +msgstr "블랙리스트에 추가된 토큰입니다" From d810271a78b3a69e9b418ad064b981a20977cf2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20Perp=C3=A9tua?= <46409254+PedroPerpetua@users.noreply.github.com> Date: Mon, 6 Nov 2023 00:35:27 +0000 Subject: [PATCH 090/171] Declare support for type checking (closes #664) (#760) --- MANIFEST.in | 1 + rest_framework_simplejwt/py.typed | 0 2 files changed, 1 insertion(+) create mode 100644 rest_framework_simplejwt/py.typed diff --git a/MANIFEST.in b/MANIFEST.in index 6b427dfc7..1501b7de9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ include README.rst include LICENSE.txt +include rest_framework_simplejwt/py.typed recursive-include rest_framework_simplejwt/locale *.mo recursive-include rest_framework_simplejwt/locale *.po recursive-exclude * __pycache__ diff --git a/rest_framework_simplejwt/py.typed b/rest_framework_simplejwt/py.typed new file mode 100644 index 000000000..e69de29bb From 8ae34dd128ef8c5a79d4632e29fa82162bc9a787 Mon Sep 17 00:00:00 2001 From: Thomas Berdy Date: Mon, 4 Dec 2023 07:34:23 +0100 Subject: [PATCH 091/171] Remove usages of deprecated datetime.utcnow() and datetime.utcfromtimestamp() (#765) * Remove usages of deprecated datetime.utcnow() and datetime.utcfromtimestamp() * Update CHANGELOG.md --------- Co-authored-by: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- CHANGELOG.md | 10 ++++++++++ rest_framework_simplejwt/utils.py | 12 ++++++++++-- setup.py | 1 + tests/test_utils.py | 8 +++----- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eea04cde..14722c445 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## 5.3.1 + +## What's Changed +* Remove EOL Python, Django and DRF version support by @KOliver94 in [#754](https://github.com/jazzband/djangorestframework-simplejwt/pull/754) +* Declare support for type checking (closes #664) by @PedroPerpetua in [#760](https://github.com/jazzband/djangorestframework-simplejwt/pull/760) +* Remove usages of deprecated datetime.utcnow() and datetime.utcfromtimestamp() in [#765](https://github.com/jazzband/djangorestframework-simplejwt/pull/765) + +#### Translation Updates: +* Update Korean translations by @TGoddessana in https://github.com/jazzband/djangorestframework-simplejwt/pull/753 + ## 5.3.0 #### Notable Changes: diff --git a/rest_framework_simplejwt/utils.py b/rest_framework_simplejwt/utils.py index 4490fa23c..cfe5ae189 100644 --- a/rest_framework_simplejwt/utils.py +++ b/rest_framework_simplejwt/utils.py @@ -23,7 +23,11 @@ def make_utc(dt: datetime) -> datetime: def aware_utcnow() -> datetime: - return make_utc(datetime.utcnow()) + dt = datetime.now(tz=timezone.utc) + if not settings.USE_TZ: + dt = dt.replace(tzinfo=None) + + return dt def datetime_to_epoch(dt: datetime) -> int: @@ -31,7 +35,11 @@ def datetime_to_epoch(dt: datetime) -> int: def datetime_from_epoch(ts: float) -> datetime: - return make_utc(datetime.utcfromtimestamp(ts)) + dt = datetime.fromtimestamp(ts, tz=timezone.utc) + if not settings.USE_TZ: + dt = dt.replace(tzinfo=None) + + return dt def format_lazy(s: str, *args, **kwargs) -> str: diff --git a/setup.py b/setup.py index 60327eeef..e6397fc9b 100755 --- a/setup.py +++ b/setup.py @@ -6,6 +6,7 @@ extras_require = { "test": [ "cryptography", + "freezegun", "pytest-cov", "pytest-django", "pytest-xdist", diff --git a/tests/test_utils.py b/tests/test_utils.py index 79afdbbf7..17eca26df 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,8 +1,8 @@ from datetime import datetime, timedelta -from unittest.mock import patch from django.test import TestCase from django.utils import timezone +from freezegun import freeze_time from rest_framework_simplejwt.utils import ( aware_utcnow, @@ -34,11 +34,9 @@ def test_it_should_return_the_correct_values(self): class TestAwareUtcnow(TestCase): def test_it_should_return_the_correct_value(self): - now = datetime.utcnow() - - with patch("rest_framework_simplejwt.utils.datetime") as fake_datetime: - fake_datetime.utcnow.return_value = now + now = datetime.now(tz=timezone.utc).replace(tzinfo=None) + with freeze_time(now): # Should return aware utcnow if USE_TZ == True with self.settings(USE_TZ=True): self.assertEqual( From c3cfd3e374dd406d2c64e7e75650071fec0d4d9f Mon Sep 17 00:00:00 2001 From: kiraware <117554978+kiraware@users.noreply.github.com> Date: Mon, 4 Dec 2023 14:39:37 +0800 Subject: [PATCH 092/171] Increase coverage (#722) * Add tests * pre-commit * improve remove blacklist app * update setup for test_backends --- tests/test_backends.py | 25 ++++++++++++++ tests/test_init.py | 19 +++++++++++ tests/test_models.py | 24 ++++++++++++++ tests/test_serializers.py | 61 +++++++++++++++++++++++++++++++++++ tests/test_token_blacklist.py | 32 ++++++++++++++++++ tests/test_tokens.py | 18 +++++++++++ tests/test_views.py | 13 ++++++++ 7 files changed, 192 insertions(+) create mode 100644 tests/test_init.py diff --git a/tests/test_backends.py b/tests/test_backends.py index 540e01820..fd19183e0 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -1,5 +1,7 @@ +import builtins import uuid from datetime import datetime, timedelta +from importlib import reload from json import JSONEncoder from unittest import mock from unittest.mock import patch @@ -45,6 +47,7 @@ def default(self, obj): class TestTokenBackend(TestCase): def setUp(self): + self.realimport = builtins.__import__ self.hmac_token_backend = TokenBackend("HS256", SECRET) self.hmac_leeway_token_backend = TokenBackend("HS256", SECRET, leeway=LEEWAY) self.rsa_token_backend = TokenBackend("RS256", PRIVATE_KEY, PUBLIC_KEY) @@ -76,6 +79,28 @@ def test_init_fails_for_rs_algorithms_when_crypto_not_installed(self): ): TokenBackend(algo, "not_secret") + def test_jwk_client_not_available(self): + from rest_framework_simplejwt import backends + + def myimport(name, globals=None, locals=None, fromlist=(), level=0): + if name == "jwt" and fromlist == ("PyJWKClient", "PyJWKClientError"): + raise ImportError + return self.realimport(name, globals, locals, fromlist, level) + + builtins.__import__ = myimport + + # Reload backends, mock jwk client is not available + reload(backends) + + self.assertEqual(backends.JWK_CLIENT_AVAILABLE, False) + self.assertEqual(backends.TokenBackend("HS256").jwks_client, None) + + builtins.__import__ = self.realimport + + @patch("jwt.encode", mock.Mock(return_value=b"test")) + def test_token_encode_should_return_str_for_old_PyJWT(self): + self.assertIsInstance(TokenBackend("HS256").encode({}), str) + def test_encode_hmac(self): # Should return a JSON web token for the given payload payload = {"exp": make_utc(datetime(year=2000, month=1, day=1))} diff --git a/tests/test_init.py b/tests/test_init.py new file mode 100644 index 000000000..b68363189 --- /dev/null +++ b/tests/test_init.py @@ -0,0 +1,19 @@ +from importlib import reload +from unittest.mock import Mock, patch + +from django.test import SimpleTestCase +from pkg_resources import DistributionNotFound + + +class TestInit(SimpleTestCase): + def test_package_is_not_installed(self): + with patch( + "pkg_resources.get_distribution", Mock(side_effect=DistributionNotFound) + ): + # Import package mock package is not installed + import rest_framework_simplejwt.__init__ + + self.assertEqual(rest_framework_simplejwt.__init__.__version__, None) + + # Restore origin package without mock + reload(rest_framework_simplejwt.__init__) diff --git a/tests/test_models.py b/tests/test_models.py index 3a017fbfe..c757eea75 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,3 +1,6 @@ +from importlib import reload +from unittest.mock import patch + from django.test import TestCase from rest_framework_simplejwt.models import TokenUser @@ -15,6 +18,18 @@ def setUp(self): self.user = TokenUser(self.token) + def test_type_checking(self): + from rest_framework_simplejwt import models + + with patch("typing.TYPE_CHECKING", True): + # Reload models, mock type checking + reload(models) + + self.assertEqual(models.TYPE_CHECKING, True) + + # Restore origin module without mock + reload(models) + def test_username(self): self.assertEqual(self.user.username, "deep-thought") @@ -60,6 +75,12 @@ def test_eq(self): self.assertNotEqual(user1, user2) self.assertEqual(user1, user3) + def test_eq_not_implemented(self): + user1 = TokenUser({api_settings.USER_ID_CLAIM: 1}) + user2 = "user2" + + self.assertFalse(user1 == user2) + def test_hash(self): self.assertEqual(hash(self.user), hash(self.user.id)) @@ -105,3 +126,6 @@ def test_is_authenticated(self): def test_get_username(self): self.assertEqual(self.user.get_username(), "deep-thought") + + def test_get_custom_claims_through_backup_getattr(self): + self.assertEqual(self.user.some_other_stuff, "arstarst") diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 6db0e3998..322d1cd9d 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -1,6 +1,8 @@ from datetime import timedelta +from importlib import reload from unittest.mock import MagicMock, patch +from django.conf import settings from django.contrib.auth import get_user_model from django.test import TestCase from rest_framework import exceptions as drf_exceptions @@ -76,6 +78,17 @@ def test_it_should_not_validate_if_user_not_found(self): with self.assertRaises(drf_exceptions.AuthenticationFailed): s.is_valid() + def test_it_should_pass_validate_if_request_not_in_context(self): + s = TokenObtainSerializer( + context={}, + data={ + "username": self.username, + "password": self.password, + }, + ) + + s.is_valid() + def test_it_should_raise_if_user_not_active(self): self.user.is_active = False self.user.save() @@ -372,6 +385,32 @@ def test_it_should_blacklist_refresh_token_if_tokens_should_be_rotated_and_black # Assert old refresh token is blacklisted self.assertEqual(BlacklistedToken.objects.first().token.jti, old_jti) + @override_api_settings( + ROTATE_REFRESH_TOKENS=True, + BLACKLIST_AFTER_ROTATION=True, + ) + def test_blacklist_app_not_installed_should_pass(self): + from rest_framework_simplejwt import serializers, tokens + + # Remove blacklist app + new_apps = list(settings.INSTALLED_APPS) + new_apps.remove("rest_framework_simplejwt.token_blacklist") + + with self.settings(INSTALLED_APPS=tuple(new_apps)): + # Reload module that blacklist app not installed + reload(tokens) + reload(serializers) + + refresh = tokens.RefreshToken() + + # Serializer validates + ser = serializers.TokenRefreshSerializer(data={"refresh": str(refresh)}) + ser.validate({"refresh": str(refresh)}) + + # Restore origin module without mock + reload(tokens) + reload(serializers) + class TestTokenVerifySerializer(TestCase): def test_it_should_raise_token_error_if_token_invalid(self): @@ -489,3 +528,25 @@ def test_it_should_blacklist_refresh_token_if_everything_ok(self): # Assert old refresh token is blacklisted self.assertEqual(BlacklistedToken.objects.first().token.jti, old_jti) + + def test_blacklist_app_not_installed_should_pass(self): + from rest_framework_simplejwt import serializers, tokens + + # Remove blacklist app + new_apps = list(settings.INSTALLED_APPS) + new_apps.remove("rest_framework_simplejwt.token_blacklist") + + with self.settings(INSTALLED_APPS=tuple(new_apps)): + # Reload module that blacklist app not installed + reload(tokens) + reload(serializers) + + refresh = tokens.RefreshToken() + + # Serializer validates + ser = serializers.TokenBlacklistSerializer(data={"refresh": str(refresh)}) + ser.validate({"refresh": str(refresh)}) + + # Restore origin module without mock + reload(tokens) + reload(serializers) diff --git a/tests/test_token_blacklist.py b/tests/test_token_blacklist.py index 824808145..b4d576b68 100644 --- a/tests/test_token_blacklist.py +++ b/tests/test_token_blacklist.py @@ -1,9 +1,11 @@ +from importlib import reload from unittest.mock import patch from django.contrib.auth.models import User from django.core.management import call_command 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 @@ -25,6 +27,19 @@ def setUp(self): password="test_password", ) + def test_token_blacklist_old_django(self): + with patch("django.VERSION", (3, 1)): + # Import package mock blacklist old django + import rest_framework_simplejwt.token_blacklist.__init__ as blacklist + + self.assertEqual( + blacklist.default_app_config, + ("rest_framework_simplejwt.token_blacklist.apps.TokenBlacklistConfig"), + ) + + # Restore origin module without mock + reload(blacklist) + def test_sliding_tokens_are_added_to_outstanding_list(self): token = SlidingToken.for_user(self.user) @@ -114,6 +129,23 @@ def test_tokens_can_be_manually_blacklisted(self): self.assertEqual(OutstandingToken.objects.count(), 2) + def test_outstanding_token_and_blacklisted_token_expected_str(self): + outstanding = OutstandingToken.objects.create( + user=self.user, + jti="abc", + token="xyz", + expires_at=timezone.now(), + ) + blacklisted = BlacklistedToken.objects.create(token=outstanding) + + expected_outstanding_str = "Token for {} ({})".format( + outstanding.user, outstanding.jti + ) + expected_blacklisted_str = f"Blacklisted token for {blacklisted.token.user}" + + self.assertEqual(str(outstanding), expected_outstanding_str) + self.assertEqual(str(blacklisted), expected_blacklisted_str) + class TestTokenBlacklistFlushExpiredTokens(TestCase): def setUp(self): diff --git a/tests/test_tokens.py b/tests/test_tokens.py index 9f81a1a76..47702e33a 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -1,4 +1,5 @@ from datetime import datetime, timedelta +from importlib import reload from unittest.mock import patch from django.contrib.auth import get_user_model @@ -39,6 +40,18 @@ def setUpTestData(cls): password="test_password", ) + def test_type_checking(self): + from rest_framework_simplejwt import tokens + + with patch("typing.TYPE_CHECKING", True): + # Reload tokens, mock type checking + reload(tokens) + + self.assertEqual(tokens.TYPE_CHECKING, True) + + # Restore origin module without mock + reload(tokens) + def test_init_no_token_type_or_lifetime(self): class MyTestToken(Token): pass @@ -377,6 +390,11 @@ def test_for_user_with_username(self): token = MyToken.for_user(self.user) self.assertEqual(token[api_settings.USER_ID_CLAIM], self.username) + @override_api_settings(CHECK_REVOKE_TOKEN=True) + def test_revoke_token_claim_included_in_authorization_token(self): + token = MyToken.for_user(self.user) + self.assertIn(api_settings.REVOKE_TOKEN_CLAIM, token) + def test_get_token_backend(self): token = MyToken() diff --git a/tests/test_views.py b/tests/test_views.py index b1fc80113..4927e6ffd 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -440,3 +440,16 @@ class CustomTokenView(TokenViewBase): request = factory.post("/", {}, format="json") res = view(request) self.assertEqual(res.status_code, 400) + + +class TestTokenViewBase(APIViewTestCase): + def test_serializer_class_not_set_in_settings_and_class_attribute_or_wrong_path( + self, + ): + view = TokenViewBase() + msg = "Could not import serializer '%s'" % view._serializer_class + + with self.assertRaises(ImportError) as e: + view.get_serializer_class() + + self.assertEqual(e.exception.msg, msg) From b88182c60d509fc1c99ac8adc8dccab1503e2d6f Mon Sep 17 00:00:00 2001 From: Abdullah Alaqeel Date: Mon, 4 Dec 2023 09:40:25 +0300 Subject: [PATCH 093/171] Update action versions (#739) --- .github/workflows/release.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 53f056262..4c34793ff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,14 +11,14 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: '3.9' - name: Install dependencies run: | @@ -42,7 +42,7 @@ jobs: - name: Upload packages to Jazzband if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') - uses: pypa/gh-action-pypi-publish@master + uses: pypa/gh-action-pypi-publish@release/v1 with: user: jazzband password: ${{ secrets.JAZZBAND_RELEASE_KEY }} From ae5e084e85fc77fd0accb94f190cd086a0fcbb5e Mon Sep 17 00:00:00 2001 From: Yegor Gulido <72152812+Egor-oop@users.noreply.github.com> Date: Mon, 4 Dec 2023 10:07:04 +0300 Subject: [PATCH 094/171] Use f-string in views (#750) --- rest_framework_simplejwt/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/views.py b/rest_framework_simplejwt/views.py index b250ff7a7..c6523da0f 100644 --- a/rest_framework_simplejwt/views.py +++ b/rest_framework_simplejwt/views.py @@ -28,7 +28,7 @@ def get_serializer_class(self) -> Serializer: try: return import_string(self._serializer_class) except ImportError: - msg = "Could not import serializer '%s'" % self._serializer_class + msg = f"Could not import serializer '{self._serializer_class}'" raise ImportError(msg) def get_authenticate_header(self, request: Request) -> str: From 7825d8347cc626a16c3043873395e72e0eb41357 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 02:08:50 -0500 Subject: [PATCH 095/171] [pre-commit.ci] pre-commit autoupdate (#724) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0) - [github.com/psf/black: 23.3.0 → 23.11.0](https://github.com/psf/black/compare/23.3.0...23.11.0) - [github.com/pre-commit/pre-commit-hooks: v4.4.0 → v4.5.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.4.0...v4.5.0) - [github.com/asottile/pyupgrade: v3.7.0 → v3.15.0](https://github.com/asottile/pyupgrade/compare/v3.7.0...v3.15.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 864f1724a..6406f04b3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.4.0' + rev: 'v4.5.0' hooks: - id: check-merge-conflict - repo: https://github.com/asottile/yesqa @@ -13,12 +13,12 @@ repos: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black - rev: '23.3.0' + rev: '23.11.0' hooks: - id: black language_version: python3 # Should be a command that runs python3.6+ - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.4.0' + rev: 'v4.5.0' hooks: - id: end-of-file-fixer exclude: >- @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v3.7.0' + rev: 'v3.15.0' hooks: - id: pyupgrade args: ['--py38-plus', '--keep-mock'] From 53ac872564a79d2d2d02e4b7cba8107783dd1ace Mon Sep 17 00:00:00 2001 From: Francisco de Assis Silva Date: Mon, 4 Dec 2023 04:09:40 -0300 Subject: [PATCH 096/171] Correct AUTH_HEADER_NAME in docs (#725) The correct is X-Access-Token e to AUTH_HEADER_NAME example and not X_Access_Token --- docs/settings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/settings.rst b/docs/settings.rst index 2b466623e..be966ac5b 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -191,7 +191,7 @@ collection will be used to build the "WWW-Authenticate" header in the response. The authorization header name to be used for authentication. The default is ``HTTP_AUTHORIZATION`` which will accept the ``Authorization`` header in the request. For example if you'd -like to use ``X_Access_Token`` in the header of your requests +like to use ``X-Access-Token`` in the header of your requests please specify the ``AUTH_HEADER_NAME`` to be ``HTTP_X_ACCESS_TOKEN`` in your settings. From 0b50ee6721155ce0f652d4c1f47dcbb10c191894 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 4 Dec 2023 17:48:36 -0800 Subject: [PATCH 097/171] Fix tests (#769) --- rest_framework_simplejwt/utils.py | 5 ++--- tests/test_init.py | 5 ++--- tests/test_utils.py | 11 ++++------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/rest_framework_simplejwt/utils.py b/rest_framework_simplejwt/utils.py index cfe5ae189..d94f89292 100644 --- a/rest_framework_simplejwt/utils.py +++ b/rest_framework_simplejwt/utils.py @@ -5,7 +5,6 @@ from django.conf import settings from django.utils.functional import lazy -from django.utils.timezone import is_naive, make_aware def get_md5_hash_password(password: str) -> str: @@ -16,8 +15,8 @@ def get_md5_hash_password(password: str) -> str: def make_utc(dt: datetime) -> datetime: - if settings.USE_TZ and is_naive(dt): - return make_aware(dt, timezone=timezone.utc) + if settings.USE_TZ and dt.tzinfo is None: + return dt.replace(tzinfo=timezone.utc) return dt diff --git a/tests/test_init.py b/tests/test_init.py index b68363189..e99a0f7d2 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -1,16 +1,15 @@ from importlib import reload +from importlib.metadata import PackageNotFoundError from unittest.mock import Mock, patch from django.test import SimpleTestCase -from pkg_resources import DistributionNotFound class TestInit(SimpleTestCase): def test_package_is_not_installed(self): with patch( - "pkg_resources.get_distribution", Mock(side_effect=DistributionNotFound) + "importlib.metadata.version", Mock(side_effect=PackageNotFoundError) ): - # Import package mock package is not installed import rest_framework_simplejwt.__init__ self.assertEqual(rest_framework_simplejwt.__init__.__version__, None) diff --git a/tests/test_utils.py b/tests/test_utils.py index 17eca26df..c97f7c224 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,7 +1,6 @@ -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from django.test import TestCase -from django.utils import timezone from freezegun import freeze_time from rest_framework_simplejwt.utils import ( @@ -24,11 +23,11 @@ def test_it_should_return_the_correct_values(self): with self.settings(USE_TZ=False): dt = make_utc(dt) - self.assertTrue(timezone.is_naive(dt)) + self.assertTrue(dt.tzinfo is None) with self.settings(USE_TZ=True): dt = make_utc(dt) - self.assertTrue(timezone.is_aware(dt)) + self.assertTrue(dt.tzinfo is not None) self.assertEqual(dt.utcoffset(), timedelta(seconds=0)) @@ -39,9 +38,7 @@ def test_it_should_return_the_correct_value(self): with freeze_time(now): # Should return aware utcnow if USE_TZ == True with self.settings(USE_TZ=True): - self.assertEqual( - timezone.make_aware(now, timezone=timezone.utc), aware_utcnow() - ) + self.assertEqual(now.replace(tzinfo=timezone.utc), aware_utcnow()) # Should return naive utcnow if USE_TZ == False with self.settings(USE_TZ=False): From 272e2b205a62b55762e14c317998ac0ab0c2d178 Mon Sep 17 00:00:00 2001 From: Mike Date: Mon, 4 Dec 2023 11:45:50 -0800 Subject: [PATCH 098/171] Enhance BlacklistMixin with Generic Type for Accurate Type Inference --- rest_framework_simplejwt/tokens.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index b207ef27c..32d9c442a 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -1,5 +1,5 @@ from datetime import datetime, timedelta -from typing import TYPE_CHECKING, Any, Dict, Optional, TypeVar +from typing import TYPE_CHECKING, Any, Dict, Generic, Optional, Type, TypeVar from uuid import uuid4 from django.conf import settings @@ -22,6 +22,8 @@ if TYPE_CHECKING: from .backends import TokenBackend +T = TypeVar('T', bound='Token') + AuthUser = TypeVar("AuthUser", AbstractBaseUser, TokenUser) @@ -229,7 +231,7 @@ def get_token_backend(self) -> "TokenBackend": return self.token_backend -class BlacklistMixin: +class BlacklistMixin(Generic[T]): """ If the `rest_framework_simplejwt.token_blacklist` app was configured to be used, tokens created from `BlacklistMixin` subclasses will insert @@ -276,7 +278,7 @@ def blacklist(self) -> BlacklistedToken: return BlacklistedToken.objects.get_or_create(token=token) @classmethod - def for_user(cls, user: AuthUser) -> Token: + def for_user(cls: Type[T], user: AuthUser) -> T: """ Adds this token to the outstanding token list. """ @@ -296,7 +298,7 @@ def for_user(cls, user: AuthUser) -> Token: return token -class SlidingToken(BlacklistMixin, Token): +class SlidingToken(BlacklistMixin['SlidingToken'], Token): token_type = "sliding" lifetime = api_settings.SLIDING_TOKEN_LIFETIME @@ -317,7 +319,7 @@ class AccessToken(Token): lifetime = api_settings.ACCESS_TOKEN_LIFETIME -class RefreshToken(BlacklistMixin, Token): +class RefreshToken(BlacklistMixin['RefreshToken'], Token): token_type = "refresh" lifetime = api_settings.REFRESH_TOKEN_LIFETIME no_copy_claims = ( From 64b32c2b39177bf68def40ceb3fedf0687ff736d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 19:46:19 +0000 Subject: [PATCH 099/171] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- rest_framework_simplejwt/tokens.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 32d9c442a..8dff4e01f 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -22,7 +22,7 @@ if TYPE_CHECKING: from .backends import TokenBackend -T = TypeVar('T', bound='Token') +T = TypeVar("T", bound="Token") AuthUser = TypeVar("AuthUser", AbstractBaseUser, TokenUser) @@ -298,7 +298,7 @@ def for_user(cls: Type[T], user: AuthUser) -> T: return token -class SlidingToken(BlacklistMixin['SlidingToken'], Token): +class SlidingToken(BlacklistMixin["SlidingToken"], Token): token_type = "sliding" lifetime = api_settings.SLIDING_TOKEN_LIFETIME @@ -319,7 +319,7 @@ class AccessToken(Token): lifetime = api_settings.ACCESS_TOKEN_LIFETIME -class RefreshToken(BlacklistMixin['RefreshToken'], Token): +class RefreshToken(BlacklistMixin["RefreshToken"], Token): token_type = "refresh" lifetime = api_settings.REFRESH_TOKEN_LIFETIME no_copy_claims = ( From fc03667cc844cb7ddab780ad1c44bee408c69180 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Tue, 5 Dec 2023 10:01:06 -0500 Subject: [PATCH 100/171] Add pull request write permission to i18n updater --- .github/workflows/i18n.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index 376807f54..0caa13533 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -10,6 +10,8 @@ jobs: locale-updater: name: Locale updater runs-on: ubuntu-latest + permissions: + pull-requests: write steps: - name: Checkout repo uses: actions/checkout@v2 @@ -47,7 +49,7 @@ jobs: python ../scripts/i18n_updater.py - name: Create Pull Request - uses: peter-evans/create-pull-request@v3 + uses: peter-evans/create-pull-request@v5 id: auto-commit-action with: branch: i18n-auto-update @@ -55,6 +57,7 @@ jobs: body: "Updated locale files on master branch" commit-message: "Update locale files" add-paths: rest_framework_simplejwt/locale/** + delete-branch: true - name: Tell whether locale updated run: echo "Locale files updated" From c791e987332ed5e22a86428160d6372b1d85ffae Mon Sep 17 00:00:00 2001 From: STerliakov Date: Fri, 29 Dec 2023 05:23:03 +0400 Subject: [PATCH 101/171] Improve type of `Token.for_user` to allow subclasses --- rest_framework_simplejwt/tokens.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 8dff4e01f..1eeadcf25 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -197,7 +197,7 @@ def check_exp( raise TokenError(format_lazy(_("Token '{}' claim has expired"), claim)) @classmethod - def for_user(cls, user: AuthUser) -> "Token": + def for_user(cls: Type[T], user: AuthUser) -> T: """ Returns an authorization token for the given user that will be provided after authenticating the user's credentials. From 509f2b121589883ac25b9c778e3a53b455aec488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=C2=A0D=C6=B0=C6=A1ng?= Date: Wed, 1 May 2024 13:40:41 -0300 Subject: [PATCH 102/171] Document support for Python 3.12/Django 5.0/DRF 3.15 (#795) --- docs/getting_started.rst | 6 +++--- setup.py | 2 ++ tox.ini | 12 +++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/getting_started.rst b/docs/getting_started.rst index f7db9b7f1..d80295072 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -6,9 +6,9 @@ Getting started Requirements ------------ -* Python (3.8, 3.9, 3.10, 3.11) -* Django (3.2, 4.1, 4.2) -* Django REST Framework (3.12, 3.13, 3.14) +* Python (3.8, 3.9, 3.10, 3.11, 3.12) +* Django (3.2, 4.1, 4.2, 5.0) +* Django REST Framework (3.12, 3.13, 3.14, 3.15) These are the officially supported python and package versions. Other versions will probably work. You're free to modify the tox config and see what is diff --git a/setup.py b/setup.py index e6397fc9b..995e63533 100755 --- a/setup.py +++ b/setup.py @@ -72,6 +72,7 @@ "Framework :: Django :: 3.2", "Framework :: Django :: 4.1", "Framework :: Django :: 4.2", + "Framework :: Django :: 5.0", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", @@ -81,6 +82,7 @@ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Topic :: Internet :: WWW/HTTP", ], ) diff --git a/tox.ini b/tox.ini index e127b8b11..c95258209 100644 --- a/tox.ini +++ b/tox.ini @@ -1,8 +1,9 @@ [tox] envlist= - py{38,39,310}-dj{32}-drf{312,313}-pyjwt{171,2}-tests - py{38,39,310}-dj{41,42}-drf313-pyjwt{171,2}-tests - py311-dj{41,42}-drf{313,314}-pyjwt{171,2}-tests + py{38,39,310}-dj32-drf{312,313,314,315}-pyjwt{171,2}-tests + py{38,39,310,311}-dj41-drf{314,315}-pyjwt{171,2}-tests + py{38,39,310,311,312}-dj42-drf{314,315}-pyjwt{171,2}-tests + py{310, 311, 312}-dj50-drf315-pyjwt{171,2}-tests docs [gh-actions] @@ -11,16 +12,19 @@ python= 3.9: py39 3.10: py310 3.11: py311 + 3.12: py312 [gh-actions:env] DJANGO= 3.2: dj32 4.1: dj41 4.2: dj42 + 5.0: dj50 DRF= 3.12: drf312 3.13: drf313 3.14: drf314 + 3.15: drf315 [testenv] commands = pytest {posargs:tests} --cov-append --cov-report=xml --cov=rest_framework_simplejwt @@ -33,9 +37,11 @@ deps= dj32: Django>=3.2,<3.3 dj41: Django>=4.1,<4.2 dj42: Django>=4.2,<4.3 + dj50: Django>=5.0,<5.1 drf312: djangorestframework>=3.12,<3.13 drf313: djangorestframework>=3.13,<3.14 drf314: djangorestframework>=3.14,<3.15 + drf315: djangorestframework>=3.15,<3.16 pyjwt171: pyjwt>=1.7.1,<1.8 pyjwt2: pyjwt>=2,<3 allowlist_externals=make From 3b71b89779043acd865f13547d88b8355e4ef525 Mon Sep 17 00:00:00 2001 From: David Paul Graham <43794491+dpgraham4401@users.noreply.github.com> Date: Wed, 1 May 2024 12:43:12 -0400 Subject: [PATCH 103/171] Auto Update Locale Files (#780) * update workflow permissions to create PR to trunk when locales need to be updated and clean up the workflow with newer dependencies including: python 3.9 -> 3.12 GH action/checkout@v2 -> action/checkout@v4 create-pull-request@v3 -> create-pull-requests@v6 actions/setup-python@v2 -> actions/setup-python@v5 With the updated dependencies we now cache python dependencies with the built-in functionality. We also only run this action if it's push to the jazzband org repo * add 'delete-branch' to auto delete PR branch after updating locale files * move permissions into job scope --- .github/workflows/i18n.yml | 88 ++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index 0caa13533..411f80702 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -1,63 +1,47 @@ -name: Locale Updater +name: Update locale files on: push: branches: - - master - main + - master + jobs: locale-updater: - name: Locale updater - runs-on: ubuntu-latest permissions: pull-requests: write + contents: write + if: github.repository == 'jazzband/djangorestframework-simplejwt' + name: Locale updater + runs-on: ubuntu-latest steps: - - name: Checkout repo - uses: actions/checkout@v2 - with: - ref: ${{ github.head_ref }} - - - name: Set up Python 3.9 - uses: actions/setup-python@v2 - with: - python-version: '3.9' - - - name: Get pip cache dir - id: pip-cache - run: | - echo "::set-output name=dir::$(pip cache dir)" - - - name: Cache - uses: actions/cache@v2 - with: - path: ${{ steps.pip-cache.outputs.dir }} - key: - 3.9-v1-${{ hashFiles('**/setup.py') }} - restore-keys: | - 3.9-v1- - - - name: Install dependencies - run: | - sudo apt-get install -y gettext - python -m pip install --upgrade pip wheel setuptools - pip install -e .[dev] - - - name: Run locale - working-directory: rest_framework_simplejwt - run: | - python ../scripts/i18n_updater.py - - - name: Create Pull Request - uses: peter-evans/create-pull-request@v5 - id: auto-commit-action - with: - branch: i18n-auto-update - title: "[i18n] Update" - body: "Updated locale files on master branch" - commit-message: "Update locale files" - add-paths: rest_framework_simplejwt/locale/** - delete-branch: true - - - name: Tell whether locale updated - run: echo "Locale files updated" + + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: 'pip' + cache-dependency-path: setup.py + + - name: Install dependencies + run: | + sudo apt-get install -y gettext + python -m pip install --upgrade pip wheel setuptools + pip install -e .[dev] + + - name: Run locale Update Script + run: python scripts/i18n_updater.py + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v6 + with: + branch: i18n-auto-update + title: "[i18n] Update" + body: "Updated locale files on trunk" + commit-message: "Update locale files" + add-paths: rest_framework_simplejwt/locale/** + delete-branch: true From d66d246bf56a27aa3e8383ccbee5c7b92a4b10ef Mon Sep 17 00:00:00 2001 From: Jae Hyuck Sa Date: Fri, 31 May 2024 05:50:49 +0900 Subject: [PATCH 104/171] Fix the None value of the outstanding token of the blacklist (#806) --- rest_framework_simplejwt/tokens.py | 3 +++ tests/test_token_blacklist.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 1eeadcf25..9e9c3b9df 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -265,11 +265,14 @@ 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) # Ensure outstanding token exists with given jti token, _ = OutstandingToken.objects.get_or_create( jti=jti, defaults={ + "user_id": user_id, + "created_at": self.current_time, "token": str(self), "expires_at": datetime_from_epoch(exp), }, diff --git a/tests/test_token_blacklist.py b/tests/test_token_blacklist.py index b4d576b68..fc45adf2e 100644 --- a/tests/test_token_blacklist.py +++ b/tests/test_token_blacklist.py @@ -146,6 +146,20 @@ def test_outstanding_token_and_blacklisted_token_expected_str(self): self.assertEqual(str(outstanding), expected_outstanding_str) self.assertEqual(str(blacklisted), expected_blacklisted_str) + def test_outstanding_token_and_blacklisted_token_created_at(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) + + def test_outstanding_token_and_blacklisted_token_user(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): From 79a0d5289cb9e15a0a34df646624e802e89dd20f Mon Sep 17 00:00:00 2001 From: Ajay Singh Date: Wed, 30 Oct 2024 21:01:13 +0000 Subject: [PATCH 105/171] Fix: Disable refresh token for inactive user. (#814) * Fix: Disable refresh token for inactive user. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Add check in serailizer instead of blacklist mixin. * Update tests. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Remove unused import. * Correct error message * Add test for deleted users. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/serializers.py | 18 ++++++++- tests/test_serializers.py | 49 +++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index 3dc318687..51138f8bf 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -5,7 +5,7 @@ from django.contrib.auth.models import AbstractBaseUser, update_last_login from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions, serializers -from rest_framework.exceptions import ValidationError +from rest_framework.exceptions import AuthenticationFailed, ValidationError from .models import TokenUser from .settings import api_settings @@ -104,9 +104,25 @@ class TokenRefreshSerializer(serializers.Serializer): access = serializers.CharField(read_only=True) token_class = RefreshToken + default_error_messages = { + "no_active_account": _("No active account found for the given token.") + } + def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: refresh = self.token_class(attrs["refresh"]) + user_id = refresh.payload.get(api_settings.USER_ID_CLAIM, None) + if user_id and ( + user := get_user_model().objects.get( + **{api_settings.USER_ID_FIELD: user_id} + ) + ): + if not api_settings.USER_AUTHENTICATION_RULE(user): + raise AuthenticationFailed( + self.error_messages["no_active_account"], + "no_active_account", + ) + data = {"access": str(refresh.access_token)} if api_settings.ROTATE_REFRESH_TOKENS: diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 322d1cd9d..6ec6a8083 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -4,6 +4,7 @@ from django.conf import settings from django.contrib.auth import get_user_model +from django.core import exceptions as django_exceptions from django.test import TestCase from rest_framework import exceptions as drf_exceptions @@ -247,6 +248,54 @@ def test_it_should_update_token_exp_claim_if_everything_ok(self): class TestTokenRefreshSerializer(TestCase): + def setUp(self): + self.username = "test_user" + self.password = "test_password" + + self.user = User.objects.create_user( + username=self.username, + password=self.password, + ) + + def test_it_should_raise_error_for_deleted_users(self): + refresh = RefreshToken.for_user(self.user) + self.user.delete() + + s = TokenRefreshSerializer(data={"refresh": str(refresh)}) + + with self.assertRaises(django_exceptions.ObjectDoesNotExist) as e: + s.is_valid() + + self.assertIn("does not exist", str(e.exception)) + + def test_it_should_raise_error_for_inactive_users(self): + refresh = RefreshToken.for_user(self.user) + self.user.is_active = False + self.user.save() + + s = TokenRefreshSerializer(data={"refresh": str(refresh)}) + + with self.assertRaises(drf_exceptions.AuthenticationFailed) as e: + s.is_valid() + + self.assertIn("No active account", e.exception.args[0]) + + def test_it_should_return_access_token_for_active_users(self): + refresh = RefreshToken.for_user(self.user) + + s = TokenRefreshSerializer(data={"refresh": str(refresh)}) + + now = aware_utcnow() - api_settings.ACCESS_TOKEN_LIFETIME / 2 + with patch("rest_framework_simplejwt.tokens.aware_utcnow") as fake_aware_utcnow: + fake_aware_utcnow.return_value = now + s.is_valid() + + access = AccessToken(s.validated_data["access"]) + + self.assertEqual( + access["exp"], datetime_to_epoch(now + api_settings.ACCESS_TOKEN_LIFETIME) + ) + def test_it_should_raise_token_error_if_token_invalid(self): token = RefreshToken() del token["exp"] From 9911c85e13eda3f98396923d94342c6f9e5e8d8b Mon Sep 17 00:00:00 2001 From: Zakaria Selmani <133883645+zxkeyy@users.noreply.github.com> Date: Mon, 23 Dec 2024 14:22:34 +0100 Subject: [PATCH 106/171] Add option to allow inactive user authentication and token generation (#834) --- rest_framework_simplejwt/authentication.py | 6 ++++-- rest_framework_simplejwt/settings.py | 1 + tests/test_authentication.py | 25 ++++++++++++++++++++++ tests/test_serializers.py | 25 +++++++++++++++++++++- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index 13767e1ee..d9ebc164f 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -131,7 +131,7 @@ def get_user(self, validated_token: Token) -> AuthUser: except self.user_model.DoesNotExist: raise AuthenticationFailed(_("User not found"), code="user_not_found") - if not user.is_active: + if api_settings.CHECK_USER_IS_ACTIVE and not user.is_active: raise AuthenticationFailed(_("User is inactive"), code="user_inactive") if api_settings.CHECK_REVOKE_TOKEN: @@ -175,4 +175,6 @@ def default_user_authentication_rule(user: AuthUser) -> bool: # `AllowAllUsersModelBackend`. However, we explicitly prevent inactive # users from authenticating to enforce a reasonable policy and provide # sensible backwards compatibility with older Django versions. - return user is not None and user.is_active + return user is not None and ( + not api_settings.CHECK_USER_IS_ACTIVE or user.is_active + ) diff --git a/rest_framework_simplejwt/settings.py b/rest_framework_simplejwt/settings.py index 7691bb863..dadcd93a7 100644 --- a/rest_framework_simplejwt/settings.py +++ b/rest_framework_simplejwt/settings.py @@ -44,6 +44,7 @@ "SLIDING_TOKEN_REFRESH_SERIALIZER": "rest_framework_simplejwt.serializers.TokenRefreshSlidingSerializer", "CHECK_REVOKE_TOKEN": False, "REVOKE_TOKEN_CLAIM": "hash_password", + "CHECK_USER_IS_ACTIVE": True, } IMPORT_STRINGS = ( diff --git a/tests/test_authentication.py b/tests/test_authentication.py index 99f0b5525..cb6c3dc3f 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -161,6 +161,31 @@ def test_get_user(self): # Otherwise, should return correct user self.assertEqual(self.backend.get_user(payload).id, u.id) + @override_api_settings( + CHECK_USER_IS_ACTIVE=False, + ) + def test_get_inactive_user(self): + payload = {"some_other_id": "foo"} + + # Should raise error if no recognizable user identification + with self.assertRaises(InvalidToken): + self.backend.get_user(payload) + + payload[api_settings.USER_ID_CLAIM] = 42 + + # Should raise exception if user not found + with self.assertRaises(AuthenticationFailed): + self.backend.get_user(payload) + + u = User.objects.create_user(username="markhamill") + u.is_active = False + u.save() + + payload[api_settings.USER_ID_CLAIM] = getattr(u, api_settings.USER_ID_FIELD) + + # should return correct user + self.assertEqual(self.backend.get_user(payload).id, u.id) + @override_api_settings( CHECK_REVOKE_TOKEN=True, REVOKE_TOKEN_CLAIM="revoke_token_claim" ) diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 6ec6a8083..0fe03a9f1 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -5,7 +5,7 @@ from django.conf import settings from django.contrib.auth import get_user_model from django.core import exceptions as django_exceptions -from django.test import TestCase +from django.test import TestCase, override_settings from rest_framework import exceptions as drf_exceptions from rest_framework_simplejwt.exceptions import TokenError @@ -105,6 +105,29 @@ def test_it_should_raise_if_user_not_active(self): with self.assertRaises(drf_exceptions.AuthenticationFailed): s.is_valid() + @override_settings( + AUTHENTICATION_BACKENDS=[ + "django.contrib.auth.backends.AllowAllUsersModelBackend", + "django.contrib.auth.backends.ModelBackend", + ] + ) + @override_api_settings( + CHECK_USER_IS_ACTIVE=False, + ) + def test_it_should_validate_if_user_inactive_but_rule_allows(self): + self.user.is_active = False + self.user.save() + + s = TokenObtainSerializer( + context=MagicMock(), + data={ + TokenObtainSerializer.username_field: self.username, + "password": self.password, + }, + ) + + self.assertTrue(s.is_valid()) + class TestTokenObtainSlidingSerializer(TestCase): def setUp(self): From c6b428d8d9ca55728b3c87ea1ddf7cdc4df6d453 Mon Sep 17 00:00:00 2001 From: amirreza sohrabi far <119850973+amirreza8002@users.noreply.github.com> Date: Fri, 3 Jan 2025 00:56:59 +0330 Subject: [PATCH 107/171] Added additional explanation for TokenVerifyView (#833) Signed-off-by: amirreza --- docs/getting_started.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/getting_started.rst b/docs/getting_started.rst index d80295072..734c55428 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -92,6 +92,9 @@ signing key: ... ] +The ``TokenVerifyView`` provides no information about a token's fitness for a particular use, +it only verifies if a token is valid or not, and return a 200 or 401 status code respectively. + If you wish to use localizations/translations, simply add ``rest_framework_simplejwt`` to ``INSTALLED_APPS``. From 59ae4b6cdc4040435d6f1422b0e040bf3289c36b Mon Sep 17 00:00:00 2001 From: Shyam Ravikumar <113762018+fossy-dude@users.noreply.github.com> Date: Fri, 3 Jan 2025 03:16:04 +0530 Subject: [PATCH 108/171] fix: Add support for EdDSA and other algorithms in jwt.algorithms.requires_cryptography (#823) --- rest_framework_simplejwt/backends.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index fbe479982..0e3537cf0 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -28,7 +28,7 @@ "ES256", "ES384", "ES512", -} +}.union(algorithms.requires_cryptography) class TokenBackend: From 7f300a26aca9350eb0e1661174f0b09b032570ae Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Fri, 3 Jan 2025 12:10:04 -0500 Subject: [PATCH 109/171] Drop Django <4.2, DRF <3.14, Python <3.9 (#839) --- .github/workflows/test.yml | 13 +++++++------ .readthedocs.yml | 2 +- setup.py | 11 +++++------ tox.ini | 21 +++++++-------------- 4 files changed, 20 insertions(+), 27 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7ce5e28aa..613fb79d8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,13 +15,14 @@ jobs: fail-fast: false max-parallel: 5 matrix: - python-version: [ '3.8', '3.9', '3.10', '3.11'] - django-version: ['3.2', '4.1', '4.2'] - drf-version: ['3.12', '3.13', '3.14'] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] + django-version: ['4.2', '5.0', '5.1'] + drf-version: ['3.14', '3.15'] exclude: - # DRF 3.13 is not compatible with Django 4.2. - - django-version: '4.2' - drf-version: '3.13' + - drf-version: '3.14' + django-version: '5.0' + - drf-version: '3.14' + django-version: '5.1' steps: - uses: actions/checkout@v2 diff --git a/.readthedocs.yml b/.readthedocs.yml index 8896b7862..07c55dbde 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -4,7 +4,7 @@ version: 2 build: os: ubuntu-20.04 tools: - python: "3.9" + python: "3.12" python: install: diff --git a/setup.py b/setup.py index 995e63533..4f4693d0e 100755 --- a/setup.py +++ b/setup.py @@ -56,11 +56,11 @@ author="David Sanders", author_email="davesque@gmail.com", install_requires=[ - "django>=3.2", - "djangorestframework>=3.12", + "django>=4.2", + "djangorestframework>=3.14", "pyjwt>=1.7.1,<3", ], - python_requires=">=3.8", + python_requires=">=3.9", extras_require=extras_require, packages=find_packages(exclude=["tests", "tests.*", "licenses", "requirements"]), include_package_data=True, @@ -69,20 +69,19 @@ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Django", - "Framework :: Django :: 3.2", - "Framework :: Django :: 4.1", "Framework :: Django :: 4.2", "Framework :: Django :: 5.0", + "Framework :: Django :: 5.1", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Internet :: WWW/HTTP", ], ) diff --git a/tox.ini b/tox.ini index c95258209..109266c2f 100644 --- a/tox.ini +++ b/tox.ini @@ -1,28 +1,24 @@ [tox] envlist= - py{38,39,310}-dj32-drf{312,313,314,315}-pyjwt{171,2}-tests - py{38,39,310,311}-dj41-drf{314,315}-pyjwt{171,2}-tests - py{38,39,310,311,312}-dj42-drf{314,315}-pyjwt{171,2}-tests - py{310, 311, 312}-dj50-drf315-pyjwt{171,2}-tests + py{39,310,311,312}-dj42-drf{314,315}-pyjwt{171,2}-tests + py{310,311,312}-dj50-drf315-pyjwt{171,2}-tests + py{310,311,312,313}-dj51-drf315-pyjwt{171,2}-tests docs [gh-actions] python= - 3.8: py38, docs 3.9: py39 3.10: py310 3.11: py311 - 3.12: py312 + 3.12: py312, docs + 3.13: py313 [gh-actions:env] DJANGO= - 3.2: dj32 - 4.1: dj41 4.2: dj42 5.0: dj50 + 5.1: dj51 DRF= - 3.12: drf312 - 3.13: drf313 3.14: drf314 3.15: drf315 @@ -34,12 +30,9 @@ extras= setenv= PYTHONDONTWRITEBYTECODE=1 deps= - dj32: Django>=3.2,<3.3 - dj41: Django>=4.1,<4.2 dj42: Django>=4.2,<4.3 dj50: Django>=5.0,<5.1 - drf312: djangorestframework>=3.12,<3.13 - drf313: djangorestframework>=3.13,<3.14 + dj51: Django>=5.1,<5.2 drf314: djangorestframework>=3.14,<3.15 drf315: djangorestframework>=3.15,<3.16 pyjwt171: pyjwt>=1.7.1,<1.8 From c8f4910d8205ce3c5cb691238330b49553e43882 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:00:34 -0500 Subject: [PATCH 110/171] Bump version to 5.4.0 (#842) --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14722c445..51889a93d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## 5.4.0 +* Changed string formatting in views by @Egor-oop in https://github.com/jazzband/djangorestframework-simplejwt/pull/750 +* Enhance BlacklistMixin with Generic Type for Accurate Type Inference by @Dresdn in https://github.com/jazzband/djangorestframework-simplejwt/pull/768 +* Improve type of `Token.for_user` to allow subclasses by @sterliakov in https://github.com/jazzband/djangorestframework-simplejwt/pull/776 +* Fix the `Null` value of the `OutstandingToken` of the `BlacklistMixin.blacklist` by @JaeHyuckSa in https://github.com/jazzband/djangorestframework-simplejwt/pull/806 +* Fix: Disable refresh token for inactive user. by @ajay09 in https://github.com/jazzband/djangorestframework-simplejwt/pull/814 +* Add option to allow inactive user authentication and token generation by @zxkeyy in https://github.com/jazzband/djangorestframework-simplejwt/pull/834 +* Drop Django <4.2, DRF <3.14, Python <3.9 by @Andrew-Chen-Wang in https://github.com/jazzband/djangorestframework-simplejwt/pull/839 + * Note, many deprecated versions are only officially not supported but probably still work fine. +* Add support for EdDSA and other algorithms in jwt.algorithms.requires_cryptography (#822) https://github.com/jazzband/djangorestframework-simplejwt/pull/823 + ## 5.3.1 ## What's Changed From 7f692a116d98323a0cfbb47bb6b843b6f1ea00fa Mon Sep 17 00:00:00 2001 From: Ashwanth Balakrishnan Date: Tue, 7 Jan 2025 13:35:39 +0530 Subject: [PATCH 111/171] Setup Dependabot Config (#845) --- .github/dependabot.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .github/dependabot.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 000000000..0869c9e9f --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + assignees: + - "djangorestframework-simplejwt" + labels: + - "dependencies" From 3a3e28f9e5d78980664a0f9a964a438228f4df9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:15:21 +0100 Subject: [PATCH 112/171] Bump actions/setup-python from 2 to 5 (#849) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v2...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4c34793ff..1045ce18e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.9' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 613fb79d8..acc392253 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} From 7637f316219798f7236bb586417bfc66cccf3741 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Tue, 7 Jan 2025 03:19:07 -0500 Subject: [PATCH 113/171] Update locale (#844) --- .github/workflows/i18n.yml | 5 ++-- .../locale/ar/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/cs/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/de/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/es/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/es_AR/LC_MESSAGES/django.po | 25 ++++++++++++------- .../locale/es_CL/LC_MESSAGES/django.po | 25 ++++++++++++------- .../locale/fa/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/fa_IR/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/fr/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/he_IL/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/id_ID/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/it_IT/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/ko_KR/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/nl_NL/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/pl_PL/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/pt_BR/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/ro/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/ru_RU/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/sl/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/sv/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/tr/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/uk_UA/LC_MESSAGES/django.po | 24 +++++++++++------- .../locale/zh_Hans/LC_MESSAGES/django.po | 24 +++++++++++------- 24 files changed, 350 insertions(+), 209 deletions(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index 411f80702..d46bebb52 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -6,7 +6,6 @@ on: - main - master - jobs: locale-updater: permissions: @@ -34,7 +33,9 @@ jobs: pip install -e .[dev] - name: Run locale Update Script - run: python scripts/i18n_updater.py + working-directory: + rest_framework_simplejwt + run: python ../scripts/i18n_updater.py - name: Create Pull Request uses: peter-evans/create-pull-request@v6 diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po index bd831256d..6223bbeaa 100644 --- a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po @@ -51,7 +51,7 @@ msgid "" msgstr "" "نوع غير معروف '{}'. يجب أن تكون 'leeway' عددًا صحيحًا أو عددًا نسبيًا أو فرق وقت." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "تأشيرة المرور غير صالحة أو منتهية الصلاحية" @@ -63,7 +63,13 @@ msgstr "تم تحديد خوارزمية غير صالحة" msgid "No active account found with the given credentials" msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,30 +96,30 @@ msgstr "تنتهي في" msgid "Token Blacklist" msgstr "قائمة تأشيرات المرور السوداء" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "لا يمكن إنشاء تأشيرة مرور بدون نوع أو عمر" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "التأشيرة ليس لها معرف" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "التأشيرة ليس لها نوع" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "التأشيرة لها نوع خاطئ" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "التأشيرة ليس لديها مطالبة '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "انتهى عمر المطالبة بالتأشيرة '{}'" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "التأشيرة مدرجة في القائمة السوداء" diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index e26482e58..9590b0d75 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -48,7 +48,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" @@ -60,7 +60,13 @@ msgstr "" msgid "No active account found with the given credentials" msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -86,30 +92,30 @@ msgstr "platí do" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Nelze vytvořit token bez zadaného typu nebo životnosti" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token nemá žádný identifikátor" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token nemá žádný typ" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Token má špatný typ" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token nemá žádnou hodnotu '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Hodnota tokenu '{}' vypršela" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po index bbc09cc66..291961c52 100644 --- a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" @@ -62,7 +62,13 @@ msgstr "" msgid "No active account found with the given credentials" msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,30 +96,30 @@ msgstr "läuft ab am" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Ein Token ohne Typ oder Lebensdauer kann nicht erstellt werden" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token hat keine Id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token hat keinen Typ" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Token hat den falschen Typ" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token hat kein '{}' Recht" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Das Tokenrecht '{}' ist abgelaufen" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 32747208e..b8d0d997b 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" @@ -62,7 +62,13 @@ msgstr "Algoritmo especificado no válido" msgid "No active account found with the given credentials" msgstr "La combinación de credenciales no tiene una cuenta activa" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "La combinación de credenciales no tiene una cuenta activa" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,30 +96,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "No se puede crear un token sin tipo o de tan larga vida" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index 14ff0fc11..ee46b6ccd 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -55,7 +55,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" @@ -68,7 +68,14 @@ msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales dadas" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "" +"No se encontró una cuenta de usuario activa para las credenciales dadas" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -96,30 +103,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "El token está en la lista negra" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index 1495e5f8d..de1b51898 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Token inválido o expirado" @@ -63,7 +63,14 @@ msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "" +"No se encontró una cuenta de usuario activa para las credenciales provistas" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -91,30 +98,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token no tiene id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token no tiene tipo" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Token tiene tipo erróneo" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token no tiene privilegio '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "El provilegio '{}' del token está expirado" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po index dd1667990..0040dc4b0 100644 --- a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po @@ -54,7 +54,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" @@ -66,7 +66,13 @@ msgstr "الگوریتم نامعتبر مشخص شده است" msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -92,30 +98,30 @@ msgstr "زمان انقضا" msgid "Token Blacklist" msgstr "لیست سیاه توکن" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index 291f36a6a..f60998bb2 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -48,7 +48,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" @@ -60,7 +60,13 @@ msgstr "الگوریتم نامعتبر مشخص شده است" msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -86,30 +92,30 @@ msgstr "زمان انقضا" msgid "Token Blacklist" msgstr "لیست سیاه توکن" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index 996248843..d6967e6cf 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" @@ -62,7 +62,13 @@ msgstr "L'algorithme spécifié est invalide" msgid "No active account found with the given credentials" msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,30 +96,30 @@ msgstr "Expire le" msgid "Token Blacklist" msgstr "Liste des jetons bannis" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Ne peut pas créer de jeton sans type ni durée de vie" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Le jeton n'a pas d'id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Le jeton n'a pas de type" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Le jeton a un type erroné" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Le jeton n'a pas le privilège '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Le privilège '{}' du jeton a expiré" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po index 88295a48d..117227360 100644 --- a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po @@ -53,7 +53,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "סוג לא מזוהה '{}', 'leeway' חייב להיות מסוג int, float או timedelta." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "המזהה אינו חוקי או שפג תוקפו" @@ -65,7 +65,13 @@ msgstr "צוין אלגוריתם לא חוקי" msgid "No active account found with the given credentials" msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -91,30 +97,30 @@ msgstr "פג תוקף בשעה" msgid "Token Blacklist" msgstr "רשימה שחורה של מזהים" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "לא ניתן ליצור מזהה ללא סוג או אורך חיים" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "למזהה אין מספר זיהוי" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "למזהה אין סוג" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "למזהה יש סוג לא נכון" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "למזהה אין '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "מזהה '{}' פג תוקף" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "המזהה ברשימה השחורה." diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index 485cb54e1..ced436727 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -54,7 +54,7 @@ msgid "" msgstr "" "Tipe '{}' tidak dikenali, 'leeway' harus bertipe int, float, atau timedelta." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" @@ -66,7 +66,13 @@ msgstr "Algoritma yang ditentukan tidak valid" msgid "No active account found with the given credentials" msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -94,30 +100,30 @@ msgstr "kedaluwarsa pada" msgid "Token Blacklist" msgstr "Daftar Hitam Token" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Tidak dapat membuat token tanpa tipe atau masa pakai" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token tidak memiliki id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token tidak memiliki tipe" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Jenis token salah" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token tidak memiliki klaim '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Klaim token '{}' telah kedaluwarsa" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index fa380ae89..1661dd928 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -53,7 +53,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" @@ -65,7 +65,13 @@ msgstr "L'algoritmo specificato non è valido" msgid "No active account found with the given credentials" msgstr "Nessun account attivo trovato con queste credenziali" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Nessun account attivo trovato con queste credenziali" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -93,30 +99,30 @@ msgstr "scade il" msgid "Token Blacklist" msgstr "Blacklist dei token" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Impossibile creare un token senza tipo o durata" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Il token non ha un id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Il token non ha un tipo" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Il token ha un tipo sbagliato" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Il token non contiene il parametro '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Il parametro '{}' del token è scaduto" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index 9ce292a25..ed400dbf5 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -51,7 +51,7 @@ msgstr "" "알 수 없는 타입 '{}', 'leeway' 값은 반드시 int, float 또는 timedelta 타입이어" "야 합니다." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "유효하지 않거나 만료된 토큰입니다" @@ -63,7 +63,13 @@ msgstr "잘못된 알고리즘이 지정되었습니다" msgid "No active account found with the given credentials" msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -89,30 +95,30 @@ msgstr "만료 시간" msgid "Token Blacklist" msgstr "토큰 블랙리스트" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "타입 또는 수명이 없는 토큰을 생성할 수 없습니다" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "토큰에 식별자가 주어지지 않았습니다" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "토큰 타입이 주어지지 않았습니다" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "잘못된 토큰 타입입니다" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "토큰에 '{}' 클레임이 없습니다" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "토큰 '{}' 클레임이 만료되었습니다" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "블랙리스트에 추가된 토큰입니다" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index 6b3bc0de5..49a8bdefa 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -49,7 +49,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Token is niet geldig of verlopen" @@ -61,7 +61,13 @@ msgstr "" msgid "No active account found with the given credentials" msgstr "Geen actief account gevonden voor deze gegevens" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Geen actief account gevonden voor deze gegevens" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -88,30 +94,30 @@ msgstr "verloopt op" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Kan geen token maken zonder type of levensduur" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token heeft geen id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token heeft geen type" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Token heeft het verkeerde type" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token heeft geen '{}' recht" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Token '{}' recht is verlopen" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index ed09ea23b..d9a94f484 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -48,7 +48,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Token jest niepoprawny lub wygasł" @@ -60,7 +60,13 @@ msgstr "" msgid "No active account found with the given credentials" msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -87,30 +93,30 @@ msgstr "wygasa o" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Nie można utworzyć tokena bez podanego typu lub żywotności" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token nie posiada numeru identyfikacyjnego" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token nie posiada typu" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Token posiada zły typ" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token nie posiada upoważnienia '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Upoważnienie tokena '{}' wygasło" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index 3c171183e..305bb6357 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "O token é inválido ou expirado" @@ -62,7 +62,13 @@ msgstr "Algoritmo inválido especificado" msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Usuário e/ou senha incorreto(s)" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,30 +96,30 @@ msgstr "expira em" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Não é possível criar token sem tipo ou tempo de vida" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token não tem id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token não tem nenhum tipo" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Token tem tipo errado" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token não tem '{}' privilégio" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "O privilégio '{}' do token expirou" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po index 09b919606..e737c7226 100644 --- a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -53,7 +53,7 @@ msgstr "" "Tipul '{}' nu este recunoscut, 'leeway' trebuie să fie de tip int, float sau " "timedelta." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Token nu este valid sau a expirat" @@ -65,7 +65,13 @@ msgstr "Algoritm nevalid specificat" msgid "No active account found with the given credentials" msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -92,30 +98,30 @@ msgstr "expiră la" msgid "Token Blacklist" msgstr "Listă de token-uri blocate" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Nu se poate crea token fără tip sau durată de viață" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Tokenul nu are id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Tokenul nu are tip" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Tokenul are tipul greșit" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Tokenul nu are reclamația '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Reclamația tokenului '{}' a expirat" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Tokenul este în listă de tokenuri blocate" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index b86361a2d..4b1367052 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -54,7 +54,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Токен недействителен или просрочен" @@ -66,7 +66,13 @@ msgstr "" msgid "No active account found with the given credentials" msgstr "Не найдено активной учетной записи с указанными данными" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Не найдено активной учетной записи с указанными данными" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -94,30 +100,30 @@ msgstr "истекает" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Невозможно создать токен без типа или времени жизни" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "У токена нет идентификатора" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Токен не имеет типа" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Токен имеет неправильный тип" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Токен не содержит '{}'" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Токен имеет просроченное значение '{}'" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po index 65924259e..c88f5c39d 100644 --- a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po @@ -54,7 +54,7 @@ msgid "" msgstr "" "Neprepoznana vrsta '{}', 'leeway' mora biti vrste int, float ali timedelta." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Žeton je neveljaven ali potekel" @@ -66,7 +66,13 @@ msgstr "Naveden algoritem je neveljaven" msgid "No active account found with the given credentials" msgstr "Aktiven račun s podanimi poverilnicami ni najden" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Aktiven račun s podanimi poverilnicami ni najden" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -94,30 +100,30 @@ msgstr "poteče ob" msgid "Token Blacklist" msgstr "Črni seznam žetonov" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Ni mogoče ustvariti žetona brez vrste ali življenjske dobe" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Žetonu manjka id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Žetonu manjka vrsta" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Žeton je napačne vrste" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Žeton nima '{}' zahtevka" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "'{}' zahtevek žetona je potekel" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Žeton je na črnem seznamu" diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po index 8ffcd8968..a5593afd6 100644 --- a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -49,7 +49,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Token är ogiltig eller har löpt ut" @@ -61,7 +61,13 @@ msgstr "Ogiltig algoritm har angetts" msgid "No active account found with the given credentials" msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -88,30 +94,30 @@ msgstr "går ut kl" msgid "Token Blacklist" msgstr "Token svartlist" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Kan inte skapa token utan typ eller livslängd" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token har inget id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token har ingen typ" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Token har fel typ" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token har inget '{}'-anspråk" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Token '{}'-anspråket har löpt ut" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token är svartlistad" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index f26ac0384..14e6b6b33 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -51,7 +51,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Token geçersiz veya süresi geçmiş" @@ -63,7 +63,13 @@ msgstr "Geçersiz algoritma belirtildi" msgid "No active account found with the given credentials" msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -89,30 +95,30 @@ msgstr "sona erme tarihi" msgid "Token Blacklist" msgstr "Token Kara Listesi" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Tipi veya geçerlilik süresi olmayan token oluşturulamaz" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "Token'in id'si yok" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "Token'in tipi yok" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "Token'in tipi yanlış" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "Token'in '{}' claim'i yok" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Token'in '{}' claim'i sona erdi" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Token kara listeye alınmış" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index ae344213f..dcd66e381 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -52,7 +52,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "Токен некоректний або термін його дії вичерпаний" @@ -64,7 +64,13 @@ msgstr "Вказаний невірний алгоритм" msgid "No active account found with the given credentials" msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "Не знайдено жодного облікового запису по наданих облікових даних" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,30 +96,30 @@ msgstr "дійстний по" msgid "Token Blacklist" msgstr "Чорний список токенів" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "Неможливо створити токен без типу або строку дії" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "У ключі доступу не міститься id" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "У ключі доступу не міститься тип" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "токен позначений невірним типом" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "У токені не міститься '{}' заголовку" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "Заголовок '{}' токена не дійсний" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index fd45a4e16..3d92d240a 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -52,7 +52,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:58 +#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 msgid "Token is invalid or expired" msgstr "令牌无效或已过期" @@ -64,7 +64,13 @@ msgstr "指定的算法无效" msgid "No active account found with the given credentials" msgstr "找不到指定凭据对应的有效用户" -#: settings.py:73 +#: serializers.py:108 +#, fuzzy +#| msgid "No active account found with the given credentials" +msgid "No active account found for the given token." +msgstr "找不到指定凭据对应的有效用户" + +#: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." @@ -90,30 +96,30 @@ msgstr "过期时间" msgid "Token Blacklist" msgstr "令牌黑名单" -#: tokens.py:44 +#: tokens.py:46 msgid "Cannot create token with no type or lifetime" msgstr "无法创建没有类型或生存期的令牌" -#: tokens.py:116 +#: tokens.py:118 msgid "Token has no id" msgstr "令牌没有标识符" -#: tokens.py:128 +#: tokens.py:130 msgid "Token has no type" msgstr "令牌没有类型" -#: tokens.py:131 +#: tokens.py:133 msgid "Token has wrong type" msgstr "令牌类型错误" -#: tokens.py:190 +#: tokens.py:192 msgid "Token has no '{}' claim" msgstr "令牌没有 '{}' 声明" -#: tokens.py:195 +#: tokens.py:197 msgid "Token '{}' claim has expired" msgstr "令牌 '{}' 声明已过期" -#: tokens.py:257 +#: tokens.py:259 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" From 2dc6c99299d7a33b9b825376256b579288367b4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:39:18 +0100 Subject: [PATCH 114/171] Bump actions/checkout from 2 to 4 (#847) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1045ce18e..5fb877885 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index acc392253..572d62582 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: django-version: '5.1' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 From 413cd3b784b1c714f3e4bf632188e9b5596ba458 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 08:06:24 +0000 Subject: [PATCH 115/171] Bump actions/cache from 2 to 4 Bumps [actions/cache](https://github.com/actions/cache) from 2 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v2...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 572d62582..65ae0fcee 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,7 +38,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ${{ steps.pip-cache.outputs.dir }} key: From 7bda24f22567b0dedcf6c409c4ba7a035e2e4439 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 08:06:35 +0000 Subject: [PATCH 116/171] Bump codecov/codecov-action from 1 to 5 Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1 to 5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v1...v5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 65ae0fcee..76c99c7a1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -59,6 +59,6 @@ jobs: DRF: ${{ matrix.drf-version }} - name: Upload coverage - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v5 with: name: Python ${{ matrix.python-version }} From 23189c3b5f8afa2e50c0463c2f4bbd17e230d1d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:30:37 +0530 Subject: [PATCH 117/171] Bump peter-evans/create-pull-request from 6 to 7 (#848) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6 to 7. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/v6...v7) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/i18n.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index d46bebb52..14c0c7a28 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -38,7 +38,7 @@ jobs: run: python ../scripts/i18n_updater.py - name: Create Pull Request - uses: peter-evans/create-pull-request@v6 + uses: peter-evans/create-pull-request@v7 with: branch: i18n-auto-update title: "[i18n] Update" From cb00a8b7b79b8908d40ae3d337d41e0271225cf4 Mon Sep 17 00:00:00 2001 From: Jason Novinger Date: Tue, 7 Jan 2025 21:50:00 +0000 Subject: [PATCH 118/171] Update requirements in docs (#840) * Update requirements in docs This reflects changes in 7f300a2. * Only list oldest supported Python for dev work --- docs/development_and_contributing.rst | 2 -- docs/getting_started.rst | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/development_and_contributing.rst b/docs/development_and_contributing.rst index 015a37995..b85724224 100644 --- a/docs/development_and_contributing.rst +++ b/docs/development_and_contributing.rst @@ -32,10 +32,8 @@ directory: .. code-block:: bash pyenv install 3.9.x - pyenv install 3.8.x cat > .python-version < Date: Thu, 9 Jan 2025 20:17:20 +0000 Subject: [PATCH 119/171] Cap PyJWT version to <2.10.0 to avoid incompatibility with subject claim type requirement (#843) --- setup.py | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 4f4693d0e..a72e0b3b5 100755 --- a/setup.py +++ b/setup.py @@ -58,7 +58,7 @@ install_requires=[ "django>=4.2", "djangorestframework>=3.14", - "pyjwt>=1.7.1,<3", + "pyjwt>=1.7.1,<2.10.0", ], python_requires=">=3.9", extras_require=extras_require, diff --git a/tox.ini b/tox.ini index 109266c2f..bc63d3640 100644 --- a/tox.ini +++ b/tox.ini @@ -36,7 +36,7 @@ deps= drf314: djangorestframework>=3.14,<3.15 drf315: djangorestframework>=3.15,<3.16 pyjwt171: pyjwt>=1.7.1,<1.8 - pyjwt2: pyjwt>=2,<3 + pyjwt2: pyjwt>=2,<2.10.0 allowlist_externals=make [testenv:docs] From f60213260a7cae5acf7bd1140ef32a237d263743 Mon Sep 17 00:00:00 2001 From: vainu-arto <70135394+vainu-arto@users.noreply.github.com> Date: Sat, 11 Jan 2025 23:18:18 +0200 Subject: [PATCH 120/171] Add specific "token expired" exceptions (#830) * Add a specific backend exception for expired tokens To later allow specific handling for this case in the layers above. * Add a separate TokenError subclass for expired tokens To allow the caller to handle expired tokens separately from invalid ones without resorting to string matching. --- rest_framework_simplejwt/backends.py | 17 ++++++++++++----- rest_framework_simplejwt/exceptions.py | 8 ++++++++ rest_framework_simplejwt/tokens.py | 11 +++++++++-- tests/test_backends.py | 11 ++++++----- tests/test_serializers.py | 8 ++++---- tests/test_tokens.py | 8 ++++++-- 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index 0e3537cf0..c81ba9cc7 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -5,9 +5,14 @@ import jwt from django.utils.translation import gettext_lazy as _ -from jwt import InvalidAlgorithmError, InvalidTokenError, algorithms - -from .exceptions import TokenBackendError +from jwt import ( + ExpiredSignatureError, + InvalidAlgorithmError, + InvalidTokenError, + algorithms, +) + +from .exceptions import TokenBackendError, TokenBackendExpiredToken from .tokens import Token from .utils import format_lazy @@ -101,7 +106,7 @@ def get_verifying_key(self, token: Token) -> Optional[str]: try: return self.jwks_client.get_signing_key_from_jwt(token).key except PyJWKClientError as ex: - raise TokenBackendError(_("Token is invalid or expired")) from ex + raise TokenBackendError(_("Token is invalid")) from ex return self.verifying_key @@ -150,5 +155,7 @@ def decode(self, token: Token, verify: bool = True) -> Dict[str, Any]: ) except InvalidAlgorithmError as ex: raise TokenBackendError(_("Invalid algorithm specified")) from ex + except ExpiredSignatureError as ex: + raise TokenBackendExpiredToken(_("Token is expired")) from ex except InvalidTokenError as ex: - raise TokenBackendError(_("Token is invalid or expired")) from ex + raise TokenBackendError(_("Token is invalid")) from ex diff --git a/rest_framework_simplejwt/exceptions.py b/rest_framework_simplejwt/exceptions.py index 882635215..5db017bbe 100644 --- a/rest_framework_simplejwt/exceptions.py +++ b/rest_framework_simplejwt/exceptions.py @@ -8,10 +8,18 @@ class TokenError(Exception): pass +class ExpiredTokenError(TokenError): + pass + + class TokenBackendError(Exception): pass +class TokenBackendExpiredToken(TokenBackendError): + pass + + class DetailDictMixin: default_detail: str default_code: str diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 9e9c3b9df..01226af49 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -7,7 +7,12 @@ from django.utils.module_loading import import_string from django.utils.translation import gettext_lazy as _ -from .exceptions import TokenBackendError, TokenError +from .exceptions import ( + ExpiredTokenError, + TokenBackendError, + TokenBackendExpiredToken, + TokenError, +) from .models import TokenUser from .settings import api_settings from .token_blacklist.models import BlacklistedToken, OutstandingToken @@ -56,8 +61,10 @@ def __init__(self, token: Optional["Token"] = None, verify: bool = True) -> None # Decode token try: self.payload = token_backend.decode(token, verify=verify) + except TokenBackendExpiredToken: + raise ExpiredTokenError(_("Token is expired")) except TokenBackendError: - raise TokenError(_("Token is invalid or expired")) + raise TokenError(_("Token is invalid")) if verify: self.verify() diff --git a/tests/test_backends.py b/tests/test_backends.py index fd19183e0..4954588db 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -14,7 +14,10 @@ from jwt import algorithms from rest_framework_simplejwt.backends import JWK_CLIENT_AVAILABLE, TokenBackend -from rest_framework_simplejwt.exceptions import TokenBackendError +from rest_framework_simplejwt.exceptions import ( + TokenBackendError, + TokenBackendExpiredToken, +) from rest_framework_simplejwt.utils import aware_utcnow, datetime_to_epoch, make_utc from tests.keys import ( ES256_PRIVATE_KEY, @@ -191,7 +194,7 @@ def test_decode_with_expiry(self): self.payload, backend.signing_key, algorithm=backend.algorithm ) - with self.assertRaises(TokenBackendError): + with self.assertRaises(TokenBackendExpiredToken): backend.decode(expired_token) def test_decode_with_invalid_sig(self): @@ -346,9 +349,7 @@ def test_decode_jwk_missing_key_raises_tokenbackenderror(self): "RS256", PRIVATE_KEY, PUBLIC_KEY, AUDIENCE, ISSUER, JWK_URL ) - with self.assertRaisesRegex( - TokenBackendError, "Token is invalid or expired" - ): + with self.assertRaisesRegex(TokenBackendError, "Token is invalid"): jwk_token_backend.decode(token) def test_decode_when_algorithm_not_available(self): diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 0fe03a9f1..d7b287856 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -206,7 +206,7 @@ def test_it_should_not_validate_if_token_invalid(self): with self.assertRaises(TokenError) as e: s.is_valid() - self.assertIn("invalid or expired", e.exception.args[0]) + self.assertIn("expired", e.exception.args[0]) def test_it_should_raise_token_error_if_token_has_no_refresh_exp_claim(self): token = SlidingToken() @@ -337,7 +337,7 @@ def test_it_should_raise_token_error_if_token_invalid(self): with self.assertRaises(TokenError) as e: s.is_valid() - self.assertIn("invalid or expired", e.exception.args[0]) + self.assertIn("expired", e.exception.args[0]) def test_it_should_raise_token_error_if_token_has_wrong_type(self): token = RefreshToken() @@ -503,7 +503,7 @@ def test_it_should_raise_token_error_if_token_invalid(self): with self.assertRaises(TokenError) as e: s.is_valid() - self.assertIn("invalid or expired", e.exception.args[0]) + self.assertIn("expired", e.exception.args[0]) def test_it_should_not_raise_token_error_if_token_has_wrong_type(self): token = RefreshToken() @@ -548,7 +548,7 @@ def test_it_should_raise_token_error_if_token_invalid(self): with self.assertRaises(TokenError) as e: s.is_valid() - self.assertIn("invalid or expired", e.exception.args[0]) + self.assertIn("expired", e.exception.args[0]) def test_it_should_raise_token_error_if_token_has_wrong_type(self): token = RefreshToken() diff --git a/tests/test_tokens.py b/tests/test_tokens.py index 47702e33a..5605bae08 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -6,7 +6,11 @@ from django.test import TestCase from jose import jwt -from rest_framework_simplejwt.exceptions import TokenBackendError, TokenError +from rest_framework_simplejwt.exceptions import ( + ExpiredTokenError, + TokenBackendError, + TokenError, +) from rest_framework_simplejwt.settings import api_settings from rest_framework_simplejwt.state import token_backend from rest_framework_simplejwt.tokens import ( @@ -157,7 +161,7 @@ def test_init_expired_token_given(self): t = MyToken() t.set_exp(lifetime=-timedelta(seconds=1)) - with self.assertRaises(TokenError): + with self.assertRaises(ExpiredTokenError): MyToken(str(t)) def test_init_no_type_token_given(self): From 2586375114eda607988a220e3caf6c297edfb8ee Mon Sep 17 00:00:00 2001 From: Vjeran Grozdanic Date: Sun, 12 Jan 2025 19:28:47 +0100 Subject: [PATCH 121/171] Move pyupgrade to python version 3.9 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6406f04b3..20a21a34f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -51,7 +51,7 @@ repos: rev: 'v3.15.0' hooks: - id: pyupgrade - args: ['--py38-plus', '--keep-mock'] + args: ['--py39-plus', '--keep-mock'] - repo: https://github.com/Lucas-C/pre-commit-hooks-markup rev: v1.0.1 From bfb27cea30a47ddbc2bd583546461098f936542a Mon Sep 17 00:00:00 2001 From: Vjeran Grozdanic Date: Sun, 12 Jan 2025 19:29:19 +0100 Subject: [PATCH 122/171] Run pyupgrade on project --- rest_framework_simplejwt/authentication.py | 4 ++-- rest_framework_simplejwt/backends.py | 6 +++--- rest_framework_simplejwt/exceptions.py | 2 +- rest_framework_simplejwt/models.py | 2 +- rest_framework_simplejwt/serializers.py | 16 ++++++++-------- rest_framework_simplejwt/settings.py | 2 +- .../token_blacklist/admin.py | 2 +- rest_framework_simplejwt/tokens.py | 6 +++--- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index d9ebc164f..b1bf43868 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -17,7 +17,7 @@ if not isinstance(api_settings.AUTH_HEADER_TYPES, (list, tuple)): AUTH_HEADER_TYPES = (AUTH_HEADER_TYPES,) -AUTH_HEADER_TYPE_BYTES: Set[bytes] = { +AUTH_HEADER_TYPE_BYTES: set[bytes] = { h.encode(HTTP_HEADER_ENCODING) for h in AUTH_HEADER_TYPES } @@ -37,7 +37,7 @@ def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.user_model = get_user_model() - def authenticate(self, request: Request) -> Optional[Tuple[AuthUser, Token]]: + def authenticate(self, request: Request) -> Optional[tuple[AuthUser, Token]]: header = self.get_header(request) if header is None: return None diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index c81ba9cc7..a32d6f8a6 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -46,7 +46,7 @@ def __init__( issuer: Optional[str] = None, jwk_url: Optional[str] = None, leeway: Union[float, int, timedelta, None] = None, - json_encoder: Optional[Type[json.JSONEncoder]] = None, + json_encoder: Optional[type[json.JSONEncoder]] = None, ) -> None: self._validate_algorithm(algorithm) @@ -110,7 +110,7 @@ def get_verifying_key(self, token: Token) -> Optional[str]: return self.verifying_key - def encode(self, payload: Dict[str, Any]) -> str: + def encode(self, payload: dict[str, Any]) -> str: """ Returns an encoded token for the given payload dictionary. """ @@ -132,7 +132,7 @@ def encode(self, payload: Dict[str, Any]) -> str: # For PyJWT >= 2.0.0a1 return token - def decode(self, token: Token, verify: bool = True) -> Dict[str, Any]: + def decode(self, token: Token, verify: bool = True) -> dict[str, Any]: """ Performs a validation of the given token and returns its payload dictionary. diff --git a/rest_framework_simplejwt/exceptions.py b/rest_framework_simplejwt/exceptions.py index 5db017bbe..8a622a8d5 100644 --- a/rest_framework_simplejwt/exceptions.py +++ b/rest_framework_simplejwt/exceptions.py @@ -26,7 +26,7 @@ class DetailDictMixin: def __init__( self, - detail: Union[Dict[str, Any], str, None] = None, + detail: Union[dict[str, Any], str, None] = None, code: Optional[str] = None, ) -> None: """ diff --git a/rest_framework_simplejwt/models.py b/rest_framework_simplejwt/models.py index 437da1e47..7fe6dd952 100644 --- a/rest_framework_simplejwt/models.py +++ b/rest_framework_simplejwt/models.py @@ -93,7 +93,7 @@ def get_all_permissions(self, obj: Optional[object] = None) -> set: def has_perm(self, perm: str, obj: Optional[object] = None) -> bool: return False - def has_perms(self, perm_list: List[str], obj: Optional[object] = None) -> bool: + def has_perms(self, perm_list: list[str], obj: Optional[object] = None) -> bool: return False def has_module_perms(self, module: str) -> bool: diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index 51138f8bf..b486c31e6 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -29,7 +29,7 @@ def __init__(self, *args, **kwargs) -> None: class TokenObtainSerializer(serializers.Serializer): username_field = get_user_model().USERNAME_FIELD - token_class: Optional[Type[Token]] = None + token_class: Optional[type[Token]] = None default_error_messages = { "no_active_account": _("No active account found with the given credentials") @@ -41,7 +41,7 @@ def __init__(self, *args, **kwargs) -> None: self.fields[self.username_field] = serializers.CharField(write_only=True) self.fields["password"] = PasswordField() - def validate(self, attrs: Dict[str, Any]) -> Dict[Any, Any]: + def validate(self, attrs: dict[str, Any]) -> dict[Any, Any]: authenticate_kwargs = { self.username_field: attrs[self.username_field], "password": attrs["password"], @@ -69,7 +69,7 @@ def get_token(cls, user: AuthUser) -> Token: class TokenObtainPairSerializer(TokenObtainSerializer): token_class = RefreshToken - def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: + def validate(self, attrs: dict[str, Any]) -> dict[str, str]: data = super().validate(attrs) refresh = self.get_token(self.user) @@ -86,7 +86,7 @@ def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: class TokenObtainSlidingSerializer(TokenObtainSerializer): token_class = SlidingToken - def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: + def validate(self, attrs: dict[str, Any]) -> dict[str, str]: data = super().validate(attrs) token = self.get_token(self.user) @@ -108,7 +108,7 @@ class TokenRefreshSerializer(serializers.Serializer): "no_active_account": _("No active account found for the given token.") } - def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: + def validate(self, attrs: dict[str, Any]) -> dict[str, str]: refresh = self.token_class(attrs["refresh"]) user_id = refresh.payload.get(api_settings.USER_ID_CLAIM, None) @@ -148,7 +148,7 @@ class TokenRefreshSlidingSerializer(serializers.Serializer): token = serializers.CharField() token_class = SlidingToken - def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: + def validate(self, attrs: dict[str, Any]) -> dict[str, str]: token = self.token_class(attrs["token"]) # Check that the timestamp in the "refresh_exp" claim has not @@ -165,7 +165,7 @@ def validate(self, attrs: Dict[str, Any]) -> Dict[str, str]: class TokenVerifySerializer(serializers.Serializer): token = serializers.CharField(write_only=True) - def validate(self, attrs: Dict[str, None]) -> Dict[Any, Any]: + def validate(self, attrs: dict[str, None]) -> dict[Any, Any]: token = UntypedToken(attrs["token"]) if ( @@ -183,7 +183,7 @@ class TokenBlacklistSerializer(serializers.Serializer): refresh = serializers.CharField(write_only=True) token_class = RefreshToken - def validate(self, attrs: Dict[str, Any]) -> Dict[Any, Any]: + def validate(self, attrs: dict[str, Any]) -> dict[Any, Any]: refresh = self.token_class(attrs["refresh"]) try: refresh.blacklist() diff --git a/rest_framework_simplejwt/settings.py b/rest_framework_simplejwt/settings.py index dadcd93a7..feb35f51d 100644 --- a/rest_framework_simplejwt/settings.py +++ b/rest_framework_simplejwt/settings.py @@ -63,7 +63,7 @@ class APISettings(_APISettings): # pragma: no cover - def __check_user_settings(self, user_settings: Dict[str, Any]) -> Dict[str, Any]: + def __check_user_settings(self, user_settings: dict[str, Any]) -> dict[str, Any]: SETTINGS_DOC = "https://django-rest-framework-simplejwt.readthedocs.io/en/latest/settings.html" for setting in REMOVED_SETTINGS: diff --git a/rest_framework_simplejwt/token_blacklist/admin.py b/rest_framework_simplejwt/token_blacklist/admin.py index a8b32ee11..03b9d5cf8 100644 --- a/rest_framework_simplejwt/token_blacklist/admin.py +++ b/rest_framework_simplejwt/token_blacklist/admin.py @@ -34,7 +34,7 @@ def get_queryset(self, *args, **kwargs) -> QuerySet: # Read-only behavior defined below actions = None - def get_readonly_fields(self, *args, **kwargs) -> List[Any]: + def get_readonly_fields(self, *args, **kwargs) -> list[Any]: return [f.name for f in self.model._meta.fields] def has_add_permission(self, *args, **kwargs) -> bool: diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 01226af49..e3b63a929 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -204,7 +204,7 @@ def check_exp( raise TokenError(format_lazy(_("Token '{}' claim has expired"), claim)) @classmethod - def for_user(cls: Type[T], user: AuthUser) -> T: + def for_user(cls: type[T], user: AuthUser) -> T: """ Returns an authorization token for the given user that will be provided after authenticating the user's credentials. @@ -246,7 +246,7 @@ class BlacklistMixin(Generic[T]): membership in a token blacklist. """ - payload: Dict[str, Any] + payload: dict[str, Any] if "rest_framework_simplejwt.token_blacklist" in settings.INSTALLED_APPS: @@ -288,7 +288,7 @@ def blacklist(self) -> BlacklistedToken: return BlacklistedToken.objects.get_or_create(token=token) @classmethod - def for_user(cls: Type[T], user: AuthUser) -> T: + def for_user(cls: type[T], user: AuthUser) -> T: """ Adds this token to the outstanding token list. """ From 651196286f0d7f0cc4d6b90a496482354aec7161 Mon Sep 17 00:00:00 2001 From: Vjeran Grozdanic Date: Sun, 12 Jan 2025 19:38:32 +0100 Subject: [PATCH 123/171] Remove unused imports in tokens.py --- rest_framework_simplejwt/tokens.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index e3b63a929..e208533d6 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -1,5 +1,5 @@ from datetime import datetime, timedelta -from typing import TYPE_CHECKING, Any, Dict, Generic, Optional, Type, TypeVar +from typing import TYPE_CHECKING, Any, Generic, Optional, TypeVar from uuid import uuid4 from django.conf import settings From d9c7331fa264ebbd7e226357aba5a63d5a31ebbf Mon Sep 17 00:00:00 2001 From: Vjeran Grozdanic Date: Sun, 12 Jan 2025 19:40:32 +0100 Subject: [PATCH 124/171] remove unused imports --- rest_framework_simplejwt/authentication.py | 2 +- rest_framework_simplejwt/backends.py | 2 +- rest_framework_simplejwt/exceptions.py | 2 +- rest_framework_simplejwt/models.py | 2 +- rest_framework_simplejwt/serializers.py | 2 +- rest_framework_simplejwt/settings.py | 2 +- rest_framework_simplejwt/token_blacklist/admin.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index b1bf43868..cadf5bbd0 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -1,4 +1,4 @@ -from typing import Optional, Set, Tuple, TypeVar +from typing import Optional, TypeVar from django.contrib.auth import get_user_model from django.contrib.auth.models import AbstractBaseUser diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index a32d6f8a6..2c2a88874 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -1,7 +1,7 @@ import json from collections.abc import Iterable from datetime import timedelta -from typing import Any, Dict, Optional, Type, Union +from typing import Any, Optional, Union import jwt from django.utils.translation import gettext_lazy as _ diff --git a/rest_framework_simplejwt/exceptions.py b/rest_framework_simplejwt/exceptions.py index 8a622a8d5..8cc58e976 100644 --- a/rest_framework_simplejwt/exceptions.py +++ b/rest_framework_simplejwt/exceptions.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional, Union +from typing import Any, Optional, Union from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions, status diff --git a/rest_framework_simplejwt/models.py b/rest_framework_simplejwt/models.py index 7fe6dd952..a0e2c8345 100644 --- a/rest_framework_simplejwt/models.py +++ b/rest_framework_simplejwt/models.py @@ -1,4 +1,4 @@ -from typing import TYPE_CHECKING, Any, List, Optional, Union +from typing import TYPE_CHECKING, Any, Optional, Union from django.contrib.auth import models as auth_models from django.db.models.manager import EmptyManager diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index b486c31e6..bebc0c4d8 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional, Type, TypeVar +from typing import Any, Optional, TypeVar from django.conf import settings from django.contrib.auth import authenticate, get_user_model diff --git a/rest_framework_simplejwt/settings.py b/rest_framework_simplejwt/settings.py index feb35f51d..518a9ad66 100644 --- a/rest_framework_simplejwt/settings.py +++ b/rest_framework_simplejwt/settings.py @@ -1,5 +1,5 @@ from datetime import timedelta -from typing import Any, Dict +from typing import Any from django.conf import settings from django.test.signals import setting_changed diff --git a/rest_framework_simplejwt/token_blacklist/admin.py b/rest_framework_simplejwt/token_blacklist/admin.py index 03b9d5cf8..a524403b2 100644 --- a/rest_framework_simplejwt/token_blacklist/admin.py +++ b/rest_framework_simplejwt/token_blacklist/admin.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Any, List, Optional, TypeVar +from typing import Any, Optional, TypeVar from django.contrib import admin from django.contrib.auth.models import AbstractBaseUser From e99ea810115b8391e4de35641906f13dfc2c1c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Mon, 13 Jan 2025 01:59:12 +0100 Subject: [PATCH 125/171] chore: clean redefinition of mock_jwk_module in backend tests (#855) --- tests/test_backends.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_backends.py b/tests/test_backends.py index 4954588db..47b22228d 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -302,7 +302,6 @@ def test_decode_rsa_aud_iss_jwk_success(self): # Payload copied self.payload["exp"] = datetime_to_epoch(self.payload["exp"]) - mock_jwk_module = mock.MagicMock() with patch("rest_framework_simplejwt.backends.PyJWKClient") as mock_jwk_module: mock_jwk_client = mock.MagicMock() mock_signing_key = mock.MagicMock() @@ -335,7 +334,6 @@ def test_decode_jwk_missing_key_raises_tokenbackenderror(self): headers={"kid": "230498151c214b788dd97f22b85410a5"}, ) - mock_jwk_module = mock.MagicMock() with patch("rest_framework_simplejwt.backends.PyJWKClient") as mock_jwk_module: mock_jwk_client = mock.MagicMock() From d4d0aaf83b54880a7579c58cf571e359f6067f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Mon, 13 Jan 2025 21:43:13 +0100 Subject: [PATCH 126/171] Add ruff linter and formatter to pre-commit (#856) * Add ruff linter to pre-commit * add ruff formater too * ruff format all files * formatting --- .pre-commit-config.yaml | 20 ++++++++++---------- setup.py | 7 ++++--- tests/test_backends.py | 3 +-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 20a21a34f..10d75fcf2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,20 +3,20 @@ repos: rev: 'v4.5.0' hooks: - id: check-merge-conflict +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.9.1 + hooks: + - id: ruff + types_or: [ python, pyi ] + args: [--select, I, --fix,] + files: "^tests/|^rest_framework_simplejwt/" + - id: ruff-format + types_or: [python, pyi] + files: "^tests/|^rest_framework_simplejwt/" - repo: https://github.com/asottile/yesqa rev: v1.5.0 hooks: - id: yesqa -- repo: https://github.com/pycqa/isort - rev: '5.12.0' - hooks: - - id: isort - args: ["--profile", "black"] -- repo: https://github.com/psf/black - rev: '23.11.0' - hooks: - - id: black - language_version: python3 # Should be a command that runs python3.6+ - repo: https://github.com/pre-commit/pre-commit-hooks rev: 'v4.5.0' hooks: diff --git a/setup.py b/setup.py index a72e0b3b5..aa08d5295 100755 --- a/setup.py +++ b/setup.py @@ -14,9 +14,10 @@ "tox", ], "lint": [ - "flake8", - "pep8", - "isort", + "ruff", + "yesqa", + "pyupgrade", + "pre-commit", ], "doc": [ "Sphinx>=1.6.5,<2", diff --git a/tests/test_backends.py b/tests/test_backends.py index 47b22228d..0d7cce944 100644 --- a/tests/test_backends.py +++ b/tests/test_backends.py @@ -9,9 +9,8 @@ import jwt import pytest from django.test import TestCase -from jwt import PyJWS +from jwt import PyJWS, algorithms from jwt import __version__ as jwt_version -from jwt import algorithms from rest_framework_simplejwt.backends import JWK_CLIENT_AVAILABLE, TokenBackend from rest_framework_simplejwt.exceptions import ( From a9ee40ddf0174f8910fa24166fd8c3dc2459272a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 4 Feb 2025 20:11:09 +0530 Subject: [PATCH 127/171] [pre-commit.ci] pre-commit autoupdate (#772) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v5.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v5.0.0) - [github.com/astral-sh/ruff-pre-commit: v0.9.1 → v0.9.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.1...v0.9.4) - [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v5.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v5.0.0) - [github.com/asottile/pyupgrade: v3.15.0 → v3.19.1](https://github.com/asottile/pyupgrade/compare/v3.15.0...v3.19.1) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 10d75fcf2..0d093a4c4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,10 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.5.0' + rev: 'v5.0.0' hooks: - id: check-merge-conflict - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.1 + rev: v0.9.4 hooks: - id: ruff types_or: [ python, pyi ] @@ -18,7 +18,7 @@ repos: hooks: - id: yesqa - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v4.5.0' + rev: 'v5.0.0' hooks: - id: end-of-file-fixer exclude: >- @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v3.15.0' + rev: 'v3.19.1' hooks: - id: pyupgrade args: ['--py39-plus', '--keep-mock'] From a01cb8bc51401e1bd34aa782fdc66223bf5a5c4a Mon Sep 17 00:00:00 2001 From: Josh Gardner Date: Thu, 6 Feb 2025 14:22:57 -0700 Subject: [PATCH 128/171] 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 Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/tokens.py | 8 +++++++- tests/test_token_blacklist.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index e208533d6..edc905531 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -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 _ @@ -273,12 +274,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), diff --git a/tests/test_token_blacklist.py b/tests/test_token_blacklist.py index fc45adf2e..03bada52c 100644 --- a/tests/test_token_blacklist.py +++ b/tests/test_token_blacklist.py @@ -160,6 +160,34 @@ 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) + + @override_api_settings(USER_ID_FIELD="email", USER_ID_CLAIM="email") + def test_outstanding_token_with_deleted_user_and_modifed_user_id_field(self): + self.assertFalse(BlacklistedToken.objects.exists()) + token = RefreshToken.for_user(self.user) + self.user.delete() + token.blacklist() + self.assertTrue(BlacklistedToken.objects.count(), 1) + class TestTokenBlacklistFlushExpiredTokens(TestCase): def setUp(self): From a041ccf41d90b88e0472abd72b4adb161d3b5c2b Mon Sep 17 00:00:00 2001 From: henryfool91 <82047953+henryfool91@users.noreply.github.com> Date: Fri, 14 Feb 2025 18:57:35 +0300 Subject: [PATCH 129/171] Caching signing key (#859) Co-authored-by: henry_fool Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/backends.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index 2c2a88874..3da9d9aa5 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -1,6 +1,7 @@ import json from collections.abc import Iterable from datetime import timedelta +from functools import cached_property from typing import Any, Optional, Union import jwt @@ -64,6 +65,21 @@ def __init__( self.leeway = leeway self.json_encoder = json_encoder + @cached_property + def prepared_signing_key(self) -> Any: + return self._prepare_key(self.signing_key) + + @cached_property + def prepared_verifying_key(self) -> Any: + return self._prepare_key(self.verifying_key) + + def _prepare_key(self, key: Optional[str]) -> Any: + # Support for PyJWT 1.7.1 or empty signing key + if key is None or not getattr(jwt.PyJWS, "get_algorithm_by_name", None): + return key + jws_alg = jwt.PyJWS().get_algorithm_by_name(self.algorithm) + return jws_alg.prepare_key(key) + def _validate_algorithm(self, algorithm: str) -> None: """ Ensure that the nominated algorithm is recognized, and that cryptography is installed for those @@ -98,9 +114,9 @@ def get_leeway(self) -> timedelta: ) ) - def get_verifying_key(self, token: Token) -> Optional[str]: + def get_verifying_key(self, token: Token) -> Any: if self.algorithm.startswith("HS"): - return self.signing_key + return self.prepared_signing_key if self.jwks_client: try: @@ -108,7 +124,7 @@ def get_verifying_key(self, token: Token) -> Optional[str]: except PyJWKClientError as ex: raise TokenBackendError(_("Token is invalid")) from ex - return self.verifying_key + return self.prepared_verifying_key def encode(self, payload: dict[str, Any]) -> str: """ @@ -122,7 +138,7 @@ def encode(self, payload: dict[str, Any]) -> str: token = jwt.encode( jwt_payload, - self.signing_key, + self.prepared_signing_key, algorithm=self.algorithm, json_encoder=self.json_encoder, ) From b962acadc33e1925cb1d1758d0f113abe030669b Mon Sep 17 00:00:00 2001 From: Jack Carter <71789855+thecarpetjasp@users.noreply.github.com> Date: Fri, 21 Feb 2025 04:16:47 +0000 Subject: [PATCH 130/171] Adds new refresh tokens to OutstandingToken db. (#866) * Adds new refresh tokens to OutstandingToken db. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/serializers.py | 1 + rest_framework_simplejwt/tokens.py | 25 +++++++++++++++++++++++++ tests/test_serializers.py | 2 +- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index bebc0c4d8..7eea55f7f 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -138,6 +138,7 @@ def validate(self, attrs: dict[str, Any]) -> dict[str, str]: refresh.set_jti() refresh.set_exp() refresh.set_iat() + refresh.outstand() data["refresh"] = str(refresh) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index edc905531..337afceb6 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -204,6 +204,31 @@ def check_exp( if claim_time <= current_time - leeway: raise TokenError(format_lazy(_("Token '{}' claim has expired"), claim)) + def outstand(self) -> OutstandingToken: + """ + Ensures this token is included in the outstanding token list and + adds it to the outstanding token list if not. + """ + 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 + return OutstandingToken.objects.get_or_create( + jti=jti, + defaults={ + "user": user, + "created_at": self.current_time, + "token": str(self), + "expires_at": datetime_from_epoch(exp), + }, + ) + @classmethod def for_user(cls: type[T], user: AuthUser) -> T: """ diff --git a/tests/test_serializers.py b/tests/test_serializers.py index d7b287856..7ce35c085 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -451,7 +451,7 @@ def test_it_should_blacklist_refresh_token_if_tokens_should_be_rotated_and_black datetime_to_epoch(now + api_settings.REFRESH_TOKEN_LIFETIME), ) - self.assertEqual(OutstandingToken.objects.count(), 1) + self.assertEqual(OutstandingToken.objects.count(), 2) self.assertEqual(BlacklistedToken.objects.count(), 1) # Assert old refresh token is blacklisted From 93c48919ccb480110688115ae705fb822a4fb303 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:45:25 -0500 Subject: [PATCH 131/171] [pre-commit.ci] pre-commit autoupdate (#862) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.9.4 → v0.9.7](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.4...v0.9.7) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0d093a4c4..8fbe2d201 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-merge-conflict - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.4 + rev: v0.9.7 hooks: - id: ruff types_or: [ python, pyi ] From eb8d61a4d0c2d0a9a36b245982d94fba7398503a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 17:46:39 -0500 Subject: [PATCH 132/171] Update locale files (#853) Co-authored-by: Andrew-Chen-Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- .../locale/ar/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/cs/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/de/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/es/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/es_AR/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/es_CL/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/fa/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/fa_IR/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/fr/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/he_IL/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/id_ID/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/it_IT/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/ko_KR/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/nl_NL/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/pl_PL/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/pt_BR/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/ro/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/ru_RU/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/sl/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/sv/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/tr/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/uk_UA/LC_MESSAGES/django.po | 38 ++++++++++++------- .../locale/zh_Hans/LC_MESSAGES/django.po | 38 ++++++++++++------- 23 files changed, 575 insertions(+), 299 deletions(-) diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po index 6223bbeaa..b2a1bb1ed 100644 --- a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po @@ -37,28 +37,40 @@ msgstr "الحساب غير مفعل" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الخوارزمية غير معروف '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "يجب أن يكون لديك تشفير مثبت لاستخدام {}." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "نوع غير معروف '{}'. يجب أن تكون 'leeway' عددًا صحيحًا أو عددًا نسبيًا أو فرق وقت." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "تأشيرة المرور غير صالحة أو منتهية الصلاحية" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "تم تحديد خوارزمية غير صالحة" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "تأشيرة المرور غير صالحة أو منتهية الصلاحية" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "تأشيرة المرور غير صالحة أو منتهية الصلاحية" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" @@ -96,30 +108,30 @@ msgstr "تنتهي في" msgid "Token Blacklist" msgstr "قائمة تأشيرات المرور السوداء" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "لا يمكن إنشاء تأشيرة مرور بدون نوع أو عمر" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "التأشيرة ليس لها معرف" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "التأشيرة ليس لها نوع" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "التأشيرة لها نوع خاطئ" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "التأشيرة ليس لديها مطالبة '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "انتهى عمر المطالبة بالتأشيرة '{}'" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "التأشيرة مدرجة في القائمة السوداء" diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index 9590b0d75..bbb4cc0c3 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -35,27 +35,39 @@ msgstr "Uživatel není aktivní" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Nerozpoznaný typ algoritmu '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Token není validní nebo vypršela jeho platnost" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Token není validní nebo vypršela jeho platnost" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Token není validní nebo vypršela jeho platnost" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" @@ -92,30 +104,30 @@ msgstr "platí do" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Nelze vytvořit token bez zadaného typu nebo životnosti" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token nemá žádný identifikátor" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token nemá žádný typ" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Token má špatný typ" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token nemá žádnou hodnotu '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Hodnota tokenu '{}' vypršela" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po index 291961c52..2e94bb6e4 100644 --- a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po @@ -37,27 +37,39 @@ msgstr "Inaktiver Benutzer" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Unerkannter Algorithmustyp '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Ungültiger oder abgelaufener Token" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Ungültiger oder abgelaufener Token" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Ungültiger oder abgelaufener Token" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" @@ -96,30 +108,30 @@ msgstr "läuft ab am" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Ein Token ohne Typ oder Lebensdauer kann nicht erstellt werden" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token hat keine Id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token hat keinen Typ" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Token hat den falschen Typ" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token hat kein '{}' Recht" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Das Tokenrecht '{}' ist abgelaufen" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index b8d0d997b..e42d8175b 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -37,27 +37,39 @@ msgstr "El usuario está inactivo" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Debe tener criptografía instalada para usar {}." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "El token es inválido o ha expirado" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "Algoritmo especificado no válido" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "El token es inválido o ha expirado" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "El token es inválido o ha expirado" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "La combinación de credenciales no tiene una cuenta activa" @@ -96,30 +108,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "No se puede crear un token sin tipo o de tan larga vida" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index ee46b6ccd..1d16c66af 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -42,27 +42,39 @@ msgstr "El usuario está inactivo" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "El token es inválido o ha expirado" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "El token es inválido o ha expirado" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "El token es inválido o ha expirado" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "" @@ -103,30 +115,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "El token está en la lista negra" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index de1b51898..d3ba703ea 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -37,27 +37,39 @@ msgstr "El usuario está inactivo" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Token inválido o expirado" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Token inválido o expirado" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Token inválido o expirado" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "" @@ -98,30 +110,30 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token no tiene id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token no tiene tipo" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Token tiene tipo erróneo" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token no tiene privilegio '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "El provilegio '{}' del token está expirado" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po index 0040dc4b0..582061590 100644 --- a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po @@ -41,27 +41,39 @@ msgstr "کاربر غیرفعال است" msgid "The user's password has been changed." msgstr "رمز عبور کاربر تغییر کرده است" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "برای استفاده از {} باید رمزنگاری را نصب کرده باشید." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "توکن نامعتبر است یا منقضی شده است" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "الگوریتم نامعتبر مشخص شده است" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "توکن نامعتبر است یا منقضی شده است" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "توکن نامعتبر است یا منقضی شده است" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" @@ -98,30 +110,30 @@ msgstr "زمان انقضا" msgid "Token Blacklist" msgstr "لیست سیاه توکن" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index f60998bb2..9c9285453 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -35,27 +35,39 @@ msgstr "کاربر غیرفعال است" msgid "The user's password has been changed." msgstr "رمز عبور کاربر تغییر کرده است" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "برای استفاده از {} باید رمزنگاری را نصب کرده باشید." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "توکن نامعتبر است یا منقضی شده است" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "الگوریتم نامعتبر مشخص شده است" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "توکن نامعتبر است یا منقضی شده است" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "توکن نامعتبر است یا منقضی شده است" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" @@ -92,30 +104,30 @@ msgstr "زمان انقضا" msgid "Token Blacklist" msgstr "لیست سیاه توکن" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index d6967e6cf..db9f0704e 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -37,27 +37,39 @@ msgstr "L'utilisateur est désactivé" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Type d'algorithme non reconnu '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Vous devez installer cryptography afin d'utiliser {}." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Le jeton est invalide ou expiré" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "L'algorithme spécifié est invalide" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Le jeton est invalide ou expiré" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Le jeton est invalide ou expiré" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" @@ -96,30 +108,30 @@ msgstr "Expire le" msgid "Token Blacklist" msgstr "Liste des jetons bannis" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Ne peut pas créer de jeton sans type ni durée de vie" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Le jeton n'a pas d'id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Le jeton n'a pas de type" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Le jeton a un type erroné" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Le jeton n'a pas le privilège '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Le privilège '{}' du jeton a expiré" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po index 117227360..bb182f727 100644 --- a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po @@ -40,27 +40,39 @@ msgstr "המשתמש אינו פעיל" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "סוג אלגוריתם לא מזוהה '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "עליך להתקין קריפטוגרפיה כדי להשתמש ב-{}." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "סוג לא מזוהה '{}', 'leeway' חייב להיות מסוג int, float או timedelta." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "המזהה אינו חוקי או שפג תוקפו" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "צוין אלגוריתם לא חוקי" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "המזהה אינו חוקי או שפג תוקפו" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "המזהה אינו חוקי או שפג תוקפו" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" @@ -97,30 +109,30 @@ msgstr "פג תוקף בשעה" msgid "Token Blacklist" msgstr "רשימה שחורה של מזהים" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "לא ניתן ליצור מזהה ללא סוג או אורך חיים" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "למזהה אין מספר זיהוי" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "למזהה אין סוג" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "למזהה יש סוג לא נכון" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "למזהה אין '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "מזהה '{}' פג תוקף" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "המזהה ברשימה השחורה." diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index ced436727..2cc4b3b63 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -40,28 +40,40 @@ msgstr "Pengguna tidak aktif" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Jenis algoritma tidak dikenal '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Anda harus memasang cryptography untuk menggunakan {}." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "Tipe '{}' tidak dikenali, 'leeway' harus bertipe int, float, atau timedelta." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Token tidak valid atau kedaluwarsa" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "Algoritma yang ditentukan tidak valid" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Token tidak valid atau kedaluwarsa" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Token tidak valid atau kedaluwarsa" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" @@ -100,30 +112,30 @@ msgstr "kedaluwarsa pada" msgid "Token Blacklist" msgstr "Daftar Hitam Token" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Tidak dapat membuat token tanpa tipe atau masa pakai" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token tidak memiliki id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token tidak memiliki tipe" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Jenis token salah" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token tidak memiliki klaim '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Klaim token '{}' telah kedaluwarsa" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index 1661dd928..f819b6a0c 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -40,27 +40,39 @@ msgstr "Utente non attivo" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Algoritmo di tipo '{}' non riconosciuto" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Devi avere installato cryptography per usare '{}'." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Il token non è valido o è scaduto" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "L'algoritmo specificato non è valido" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Il token non è valido o è scaduto" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Il token non è valido o è scaduto" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Nessun account attivo trovato con queste credenziali" @@ -99,30 +111,30 @@ msgstr "scade il" msgid "Token Blacklist" msgstr "Blacklist dei token" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Impossibile creare un token senza tipo o durata" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Il token non ha un id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Il token non ha un tipo" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Il token ha un tipo sbagliato" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Il token non contiene il parametro '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Il parametro '{}' del token è scaduto" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index ed400dbf5..a84af8063 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -36,29 +36,41 @@ msgstr "비활성화된 사용자입니다" msgid "The user's password has been changed." msgstr "사용자의 비밀번호가 바뀌었습니다." -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "'{}' 는 알 수 없는 알고리즘 유형입니다" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "{}를 사용하려면 암호화가 설치되어 있어야 합니다." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "알 수 없는 타입 '{}', 'leeway' 값은 반드시 int, float 또는 timedelta 타입이어" "야 합니다." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "유효하지 않거나 만료된 토큰입니다" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "잘못된 알고리즘이 지정되었습니다" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "유효하지 않거나 만료된 토큰입니다" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "유효하지 않거나 만료된 토큰입니다" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" @@ -95,30 +107,30 @@ msgstr "만료 시간" msgid "Token Blacklist" msgstr "토큰 블랙리스트" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "타입 또는 수명이 없는 토큰을 생성할 수 없습니다" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "토큰에 식별자가 주어지지 않았습니다" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "토큰 타입이 주어지지 않았습니다" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "잘못된 토큰 타입입니다" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "토큰에 '{}' 클레임이 없습니다" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "토큰 '{}' 클레임이 만료되었습니다" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "블랙리스트에 추가된 토큰입니다" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index 49a8bdefa..69603bc47 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -36,27 +36,39 @@ msgstr "Gebruiker is inactief" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Niet herkend algoritme type '{}" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Token is niet geldig of verlopen" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Token is niet geldig of verlopen" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Token is niet geldig of verlopen" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Geen actief account gevonden voor deze gegevens" @@ -94,30 +106,30 @@ msgstr "verloopt op" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Kan geen token maken zonder type of levensduur" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token heeft geen id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token heeft geen type" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Token heeft het verkeerde type" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token heeft geen '{}' recht" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Token '{}' recht is verlopen" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index d9a94f484..9037642ba 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -35,27 +35,39 @@ msgstr "Użytkownik jest nieaktywny" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Nierozpoznany typ algorytmu '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Token jest niepoprawny lub wygasł" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Token jest niepoprawny lub wygasł" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Token jest niepoprawny lub wygasł" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" @@ -93,30 +105,30 @@ msgstr "wygasa o" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Nie można utworzyć tokena bez podanego typu lub żywotności" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token nie posiada numeru identyfikacyjnego" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token nie posiada typu" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Token posiada zły typ" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token nie posiada upoważnienia '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Upoważnienie tokena '{}' wygasło" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index 305bb6357..9f1be57ce 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -37,27 +37,39 @@ msgstr "Usuário está inativo" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo '{}' não reconhecido" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Você deve ter criptografia instalada para usar {}." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "O token é inválido ou expirado" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "Algoritmo inválido especificado" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "O token é inválido ou expirado" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "O token é inválido ou expirado" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" @@ -96,30 +108,30 @@ msgstr "expira em" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Não é possível criar token sem tipo ou tempo de vida" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token não tem id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token não tem nenhum tipo" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Token tem tipo errado" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token não tem '{}' privilégio" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "O privilégio '{}' do token expirou" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po index e737c7226..ac1d56442 100644 --- a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -38,29 +38,41 @@ msgstr "Utilizatorul este inactiv" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipul de algoritm '{}' nu este recunoscut" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Trebuie să aveți instalată criptografia pentru a utiliza {}." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "Tipul '{}' nu este recunoscut, 'leeway' trebuie să fie de tip int, float sau " "timedelta." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Token nu este valid sau a expirat" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "Algoritm nevalid specificat" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Token nu este valid sau a expirat" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Token nu este valid sau a expirat" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" @@ -98,30 +110,30 @@ msgstr "expiră la" msgid "Token Blacklist" msgstr "Listă de token-uri blocate" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Nu se poate crea token fără tip sau durată de viață" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Tokenul nu are id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Tokenul nu are tip" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Tokenul are tipul greșit" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Tokenul nu are reclamația '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Reclamația tokenului '{}' a expirat" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Tokenul este în listă de tokenuri blocate" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index 4b1367052..ce3bab13f 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -41,27 +41,39 @@ msgstr "Пользователь неактивен" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Нераспознанный тип алгоритма '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Токен недействителен или просрочен" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Токен недействителен или просрочен" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Токен недействителен или просрочен" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Не найдено активной учетной записи с указанными данными" @@ -100,30 +112,30 @@ msgstr "истекает" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Невозможно создать токен без типа или времени жизни" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "У токена нет идентификатора" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Токен не имеет типа" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Токен имеет неправильный тип" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Токен не содержит '{}'" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Токен имеет просроченное значение '{}'" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po index c88f5c39d..88ce161dc 100644 --- a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po @@ -40,28 +40,40 @@ msgstr "Uporabnik je neaktiven" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Neprepoznana vrsta algoritma'{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Za uporabo '{}' je potrebna namestitev 'cryptography'." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" "Neprepoznana vrsta '{}', 'leeway' mora biti vrste int, float ali timedelta." -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Žeton je neveljaven ali potekel" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "Naveden algoritem je neveljaven" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Žeton je neveljaven ali potekel" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Žeton je neveljaven ali potekel" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Aktiven račun s podanimi poverilnicami ni najden" @@ -100,30 +112,30 @@ msgstr "poteče ob" msgid "Token Blacklist" msgstr "Črni seznam žetonov" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Ni mogoče ustvariti žetona brez vrste ali življenjske dobe" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Žetonu manjka id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Žetonu manjka vrsta" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Žeton je napačne vrste" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Žeton nima '{}' zahtevka" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "'{}' zahtevek žetona je potekel" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Žeton je na črnem seznamu" diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po index a5593afd6..c09b35ef1 100644 --- a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -36,27 +36,39 @@ msgstr "Användaren är inaktiv" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Okänd algoritmtyp '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Du måste ha kryptografi installerad för att kunna använda {}." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Token är ogiltig eller har löpt ut" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "Ogiltig algoritm har angetts" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Token är ogiltig eller har löpt ut" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Token är ogiltig eller har löpt ut" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" @@ -94,30 +106,30 @@ msgstr "går ut kl" msgid "Token Blacklist" msgstr "Token svartlist" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Kan inte skapa token utan typ eller livslängd" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token har inget id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token har ingen typ" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Token har fel typ" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token har inget '{}'-anspråk" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Token '{}'-anspråket har löpt ut" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token är svartlistad" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 14e6b6b33..04ce8e055 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -38,27 +38,39 @@ msgstr "Kullanıcı etkin değil" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tanınmayan algortima tipi '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "{} kullanmak için cryptography yüklemeniz gerekiyor." -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Token geçersiz veya süresi geçmiş" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "Geçersiz algoritma belirtildi" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Token geçersiz veya süresi geçmiş" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Token geçersiz veya süresi geçmiş" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" @@ -95,30 +107,30 @@ msgstr "sona erme tarihi" msgid "Token Blacklist" msgstr "Token Kara Listesi" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Tipi veya geçerlilik süresi olmayan token oluşturulamaz" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "Token'in id'si yok" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "Token'in tipi yok" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "Token'in tipi yanlış" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "Token'in '{}' claim'i yok" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Token'in '{}' claim'i sona erdi" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Token kara listeye alınmış" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index dcd66e381..890c3af58 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -39,27 +39,39 @@ msgstr "Користувач неактивний" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Тип алгоритму '{}' не розпізнаний" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "Встановіть модуль cryptography щоб використовувати {}" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "Токен некоректний або термін його дії вичерпаний" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "Вказаний невірний алгоритм" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "Токен некоректний або термін його дії вичерпаний" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Токен некоректний або термін його дії вичерпаний" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Не знайдено жодного облікового запису по наданих облікових даних" @@ -96,30 +108,30 @@ msgstr "дійстний по" msgid "Token Blacklist" msgstr "Чорний список токенів" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "Неможливо створити токен без типу або строку дії" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "У ключі доступу не міститься id" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "У ключі доступу не міститься тип" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "токен позначений невірним типом" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "У токені не міститься '{}' заголовку" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "Заголовок '{}' токена не дійсний" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index 3d92d240a..317a8e631 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -39,27 +39,39 @@ msgstr "该用户已禁用" msgid "The user's password has been changed." msgstr "" -#: backends.py:69 +#: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "未知算法类型 '{}'" -#: backends.py:75 +#: backends.py:96 msgid "You must have cryptography installed to use {}." msgstr "你必须安装 cryptography 才能使用 {}。" -#: backends.py:90 +#: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:104 backends.py:154 exceptions.py:47 tokens.py:60 -msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:68 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is invalid" msgstr "令牌无效或已过期" -#: backends.py:152 +#: backends.py:173 msgid "Invalid algorithm specified" msgstr "指定的算法无效" +#: backends.py:175 tokens.py:66 +#, fuzzy +#| msgid "Token is invalid or expired" +msgid "Token is expired" +msgstr "令牌无效或已过期" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "令牌无效或已过期" + #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "找不到指定凭据对应的有效用户" @@ -96,30 +108,30 @@ msgstr "过期时间" msgid "Token Blacklist" msgstr "令牌黑名单" -#: tokens.py:46 +#: tokens.py:52 msgid "Cannot create token with no type or lifetime" msgstr "无法创建没有类型或生存期的令牌" -#: tokens.py:118 +#: tokens.py:126 msgid "Token has no id" msgstr "令牌没有标识符" -#: tokens.py:130 +#: tokens.py:138 msgid "Token has no type" msgstr "令牌没有类型" -#: tokens.py:133 +#: tokens.py:141 msgid "Token has wrong type" msgstr "令牌类型错误" -#: tokens.py:192 +#: tokens.py:200 msgid "Token has no '{}' claim" msgstr "令牌没有 '{}' 声明" -#: tokens.py:197 +#: tokens.py:205 msgid "Token '{}' claim has expired" msgstr "令牌 '{}' 声明已过期" -#: tokens.py:259 +#: tokens.py:292 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" From faeea49e33c971f28b505c2d8ba8384b56802f27 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Wed, 26 Feb 2025 14:19:07 -0500 Subject: [PATCH 133/171] Update CHANGELOG.md (#869) --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51889a93d..a7c124d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## 5.5.0 +* Cap PyJWT version to <2.10.0 to avoid incompatibility with subject claim type requirement by @grayver in https://github.com/jazzband/djangorestframework-simplejwt/pull/843 +* Add specific "token expired" exceptions by @vainu-arto in https://github.com/jazzband/djangorestframework-simplejwt/pull/830 +* Fix user_id type mismatch when user claim is not pk by @jdg-journeyfront in https://github.com/jazzband/djangorestframework-simplejwt/pull/851 +* Caching signing key by @henryfool91 in https://github.com/jazzband/djangorestframework-simplejwt/pull/859 +* Adds new refresh tokens to OutstandingToken db. by @thecarpetjasp in https://github.com/jazzband/djangorestframework-simplejwt/pull/866 + ## 5.4.0 * Changed string formatting in views by @Egor-oop in https://github.com/jazzband/djangorestframework-simplejwt/pull/750 * Enhance BlacklistMixin with Generic Type for Accurate Type Inference by @Dresdn in https://github.com/jazzband/djangorestframework-simplejwt/pull/768 From c1231afa18a83c5a9b17a6b792cacc561d6ecbb0 Mon Sep 17 00:00:00 2001 From: Fabian Falon Date: Thu, 27 Feb 2025 17:27:05 +0100 Subject: [PATCH 134/171] :globe_with_meridians: Fix typos and improve clarity in es_AR translations (#876) --- .../locale/es_AR/LC_MESSAGES/django.mo | Bin 2166 -> 2390 bytes .../locale/es_AR/LC_MESSAGES/django.po | 22 ++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.mo index 968365d9e33d43e0fb7431395d514f9be317bc15..0dc8aa18f668d52517058c44320a1289141098bc 100644 GIT binary patch delta 937 zcmZ9}y=#*}9Ki8Qo4)%}Q|n9Pa3z(BFVQMggbtm8N=XOt54b*eX&y=M;`1a?kdi?h z#PLBKYzG$yog`4fOZv zv|ZYH+D3{Gajj2?1)RgnXz>ER#w_mOb=<>coapcTKS00Vb3Bf3@dj?;Y25G3H$`7s zh!ad?@FdQ3y@ftO5hXsraeRTta05s2eb+5yPw^S~i7$L6DdHVprTF&V zK97$hH2*Af6nzjrsjtMxQ5rXQ5M%WG^^4?B>Q(lRZKz79rK+sDD6Ey&WLz~tSPG3! zp7uS&CYp_9RmJfm7in2mv0O36%Al<5s?n{1{>{`>L9K+!%7UsmD;G-bQNH9y ztxxHzsnKfWsxAsbXOsPbTr)538ELw?g6)>9+uj-0oU~3hw%>3rmls7RW0u;$*;>?I zsANz#wx*;CYGH#B87mwrh>T`ks49lz9^_M6#d)#RURMfN>yZk=#1869ovB)+Vzd20 zNo^|BT31o%s8Pmbmw{TNEUl7ngO5kLXHxm(_R#uxZ%JetE>PMfyF)tr|6vce%qRDU Gr~d)?o3T&; delta 714 zcmX}pJxmlq6u|Mf$H(0vDjeb|YBB_4ATbd1)aHT`8%&5MMs1{EayyaL%dG6qVq!Fy zNMWo@Ha2w9X?uw@cC=I!bP`HSZES4(&$;+=Z+<&_GjHC_?bm(}tsm5SKMHZ0JWuYD z7syuu1Mw4^_zN%NbV+0qALA9=z7o0j-$=v%!x!|;_?z&zaEv?(-<-d4et0)V7^&S2e}jXhzjA*#|B}dj z=2qe)dZ}HMH%ssG!_r3Qea~iaWU&?FwRONNuq;BUEMOmxbQA#aqo+LW|S_wxV7A0+bbgB;H{91MVFFfyUwEzGB diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index 1d16c66af..cb47d983a 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -3,14 +3,14 @@ # # Translators: # Ariel Torti , 2020. -# +# Fabian Falón , 2024. #, fuzzy msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-02-22 17:30+0100\n" -"Last-Translator: Ariel Torti \n" +"Last-Translator: Fabian Falon \n" "Language: es_AR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,15 +24,15 @@ msgstr "" #: authentication.py:115 msgid "Given token not valid for any token type" -msgstr "El token dado no es válido para ningún tipo de token" +msgstr "El token proporcionado no es válido para ningún tipo." #: authentication.py:127 authentication.py:162 msgid "Token contained no recognizable user identification" -msgstr "El token no contiene ninguna identificación de usuario" +msgstr "El token no contiene ninguna identificación de usuario válida." #: authentication.py:132 msgid "User not found" -msgstr "Usuario no encontrado" +msgstr "No se encontró el usuario." #: authentication.py:135 msgid "User is inactive" @@ -40,7 +40,7 @@ msgstr "El usuario está inactivo" #: authentication.py:142 msgid "The user's password has been changed." -msgstr "" +msgstr "La contraseña del usuario ha sido cambiada." #: backends.py:90 msgid "Unrecognized algorithm type '{}'" @@ -63,7 +63,7 @@ msgstr "El token es inválido o ha expirado" #: backends.py:173 msgid "Invalid algorithm specified" -msgstr "" +msgstr "Se especificó un algoritmo no válido." #: backends.py:175 tokens.py:66 #, fuzzy @@ -77,15 +77,13 @@ msgstr "El token es inválido o ha expirado" #: serializers.py:35 msgid "No active account found with the given credentials" -msgstr "" -"No se encontró una cuenta de usuario activa para las credenciales dadas" +msgstr "No se encontró una cuenta activa con las credenciales proporcionadas." #: serializers.py:108 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." -msgstr "" -"No se encontró una cuenta de usuario activa para las credenciales dadas" +msgstr "No se encontró una cuenta activa para el token proporcionado" #: settings.py:74 msgid "" @@ -141,4 +139,4 @@ msgstr "El privilegio '{}' del token ha expirado" #: tokens.py:292 msgid "Token is blacklisted" -msgstr "El token está en la lista negra" +msgstr "El token ha sido revocado" From 1ad763bfe73936515aa4756263338c63866364c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Thu, 27 Feb 2025 17:28:06 +0100 Subject: [PATCH 135/171] docs: Add warning in docs for `for_user` usage (#872) --- docs/creating_tokens_manually.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/creating_tokens_manually.rst b/docs/creating_tokens_manually.rst index 5c42b0cee..8dc5caa04 100644 --- a/docs/creating_tokens_manually.rst +++ b/docs/creating_tokens_manually.rst @@ -6,11 +6,19 @@ Creating tokens manually Sometimes, you may wish to manually create a token for a user. This could be done as follows: +.. warning:: + The ``for_user`` method does not check if the user is active. If you need to verify the user's status, + this check needs to be done before creating the tokens. + .. code-block:: python from rest_framework_simplejwt.tokens import RefreshToken + from rest_framework_simplejwt.exceptions import AuthenticationFailed def get_tokens_for_user(user): + if not user.is_active: + raise AuthenticationFailed("User is not active") + refresh = RefreshToken.for_user(user) return { From 14e8b2cf5fa0df954af82ff3926fa6d6c4ecf13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Fri, 28 Feb 2025 18:22:46 +0100 Subject: [PATCH 136/171] feat: log warning if token is being created for inactive user (#873) As per [discussion](https://github.com/jazzband/djangorestframework-simplejwt/issues/779#issuecomment-2208889198), this PR adds a warning if a developer tries to create the token for the non-active user. Part of https://github.com/jazzband/djangorestframework-simplejwt/issues/779 --- rest_framework_simplejwt/tokens.py | 7 +++++++ rest_framework_simplejwt/utils.py | 3 +++ 2 files changed, 10 insertions(+) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 337afceb6..36c9a86f1 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -23,6 +23,7 @@ datetime_to_epoch, format_lazy, get_md5_hash_password, + logger, ) if TYPE_CHECKING: @@ -235,6 +236,12 @@ def for_user(cls: type[T], user: AuthUser) -> T: Returns an authorization token for the given user that will be provided after authenticating the user's credentials. """ + + if hasattr(user, "is_active") and not user.is_active: + logger.warning( + f"Creating token for inactive user: {user.id}. If this is not intentional, consider checking the user's status before calling the `for_user` method." + ) + user_id = getattr(user, api_settings.USER_ID_FIELD) if not isinstance(user_id, int): user_id = str(user_id) diff --git a/rest_framework_simplejwt/utils.py b/rest_framework_simplejwt/utils.py index d94f89292..202f12e9e 100644 --- a/rest_framework_simplejwt/utils.py +++ b/rest_framework_simplejwt/utils.py @@ -1,4 +1,5 @@ import hashlib +import logging from calendar import timegm from datetime import datetime, timezone from typing import Callable @@ -46,3 +47,5 @@ def format_lazy(s: str, *args, **kwargs) -> str: format_lazy: Callable = lazy(format_lazy, str) + +logger = logging.getLogger("rest_framework_simplejwt") From 4def3fb27879fd703b54a3c2a244433df093895a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Sun, 2 Mar 2025 19:32:13 +0100 Subject: [PATCH 137/171] ref: full tracebacks on exceptions (#870) --- rest_framework_simplejwt/authentication.py | 12 ++++++++---- rest_framework_simplejwt/backends.py | 16 ++++++++-------- rest_framework_simplejwt/tokens.py | 16 ++++++++-------- rest_framework_simplejwt/views.py | 6 +++--- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index cadf5bbd0..239d242a2 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -123,13 +123,17 @@ def get_user(self, validated_token: Token) -> AuthUser: """ try: user_id = validated_token[api_settings.USER_ID_CLAIM] - except KeyError: - raise InvalidToken(_("Token contained no recognizable user identification")) + except KeyError as e: + raise InvalidToken( + _("Token contained no recognizable user identification") + ) from e try: user = self.user_model.objects.get(**{api_settings.USER_ID_FIELD: user_id}) - except self.user_model.DoesNotExist: - raise AuthenticationFailed(_("User not found"), code="user_not_found") + except self.user_model.DoesNotExist as e: + raise AuthenticationFailed( + _("User not found"), code="user_not_found" + ) from e if api_settings.CHECK_USER_IS_ACTIVE and not user.is_active: raise AuthenticationFailed(_("User is inactive"), code="user_inactive") diff --git a/rest_framework_simplejwt/backends.py b/rest_framework_simplejwt/backends.py index 3da9d9aa5..0967fc188 100644 --- a/rest_framework_simplejwt/backends.py +++ b/rest_framework_simplejwt/backends.py @@ -121,8 +121,8 @@ def get_verifying_key(self, token: Token) -> Any: if self.jwks_client: try: return self.jwks_client.get_signing_key_from_jwt(token).key - except PyJWKClientError as ex: - raise TokenBackendError(_("Token is invalid")) from ex + except PyJWKClientError as e: + raise TokenBackendError(_("Token is invalid")) from e return self.prepared_verifying_key @@ -169,9 +169,9 @@ def decode(self, token: Token, verify: bool = True) -> dict[str, Any]: "verify_signature": verify, }, ) - except InvalidAlgorithmError as ex: - raise TokenBackendError(_("Invalid algorithm specified")) from ex - except ExpiredSignatureError as ex: - raise TokenBackendExpiredToken(_("Token is expired")) from ex - except InvalidTokenError as ex: - raise TokenBackendError(_("Token is invalid")) from ex + except InvalidAlgorithmError as e: + raise TokenBackendError(_("Invalid algorithm specified")) from e + except ExpiredSignatureError as e: + raise TokenBackendExpiredToken(_("Token is expired")) from e + except InvalidTokenError as e: + raise TokenBackendError(_("Token is invalid")) from e diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 36c9a86f1..92d395306 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -63,10 +63,10 @@ def __init__(self, token: Optional["Token"] = None, verify: bool = True) -> None # Decode token try: self.payload = token_backend.decode(token, verify=verify) - except TokenBackendExpiredToken: - raise ExpiredTokenError(_("Token is expired")) - except TokenBackendError: - raise TokenError(_("Token is invalid")) + except TokenBackendExpiredToken as e: + raise ExpiredTokenError(_("Token is expired")) from e + except TokenBackendError as e: + raise TokenError(_("Token is invalid")) from e if verify: self.verify() @@ -135,8 +135,8 @@ def verify_token_type(self) -> None: """ try: token_type = self.payload[api_settings.TOKEN_TYPE_CLAIM] - except KeyError: - raise TokenError(_("Token has no type")) + except KeyError as e: + raise TokenError(_("Token has no type")) from e if self.token_type != token_type: raise TokenError(_("Token has wrong type")) @@ -197,8 +197,8 @@ def check_exp( try: claim_value = self.payload[claim] - except KeyError: - raise TokenError(format_lazy(_("Token has no '{}' claim"), claim)) + except KeyError as e: + raise TokenError(format_lazy(_("Token has no '{}' claim"), claim)) from e claim_time = datetime_from_epoch(claim_value) leeway = self.get_token_backend().get_leeway() diff --git a/rest_framework_simplejwt/views.py b/rest_framework_simplejwt/views.py index c6523da0f..98697ed72 100644 --- a/rest_framework_simplejwt/views.py +++ b/rest_framework_simplejwt/views.py @@ -27,9 +27,9 @@ def get_serializer_class(self) -> Serializer: return self.serializer_class try: return import_string(self._serializer_class) - except ImportError: + except ImportError as e: msg = f"Could not import serializer '{self._serializer_class}'" - raise ImportError(msg) + raise ImportError(msg) from e def get_authenticate_header(self, request: Request) -> str: return '{} realm="{}"'.format( @@ -43,7 +43,7 @@ def post(self, request: Request, *args, **kwargs) -> Response: try: serializer.is_valid(raise_exception=True) except TokenError as e: - raise InvalidToken(e.args[0]) + raise InvalidToken(e.args[0]) from e return Response(serializer.validated_data, status=status.HTTP_200_OK) From efb105e0f2c64f94f1245811b343e4e168a388d7 Mon Sep 17 00:00:00 2001 From: Cloves Oliveira Date: Sun, 2 Mar 2025 16:12:15 -0300 Subject: [PATCH 138/171] #858 New i18n messages (#879) * Mapping messages that needed to be translated. * Generating pt_BR translation file, translating and reviewing. * Adjust message references in pt_BR translations. * Add translations for blacklisted token messages in languages other than pt_BR. --- .../locale/ar/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/cs/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/de/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/es/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/es_AR/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/es_CL/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/fa/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/fa_IR/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/fr/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/he_IL/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/id_ID/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/it_IT/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/ko_KR/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/nl_NL/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/pl_PL/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/pt_BR/LC_MESSAGES/django.mo | Bin 2324 -> 3226 bytes .../locale/pt_BR/LC_MESSAGES/django.po | 71 ++++++++++++------ .../locale/ro/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/ru_RU/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/sl/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/sv/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/tr/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/uk_UA/LC_MESSAGES/django.po | 52 +++++++++---- .../locale/zh_Hans/LC_MESSAGES/django.po | 52 +++++++++---- rest_framework_simplejwt/serializers.py | 2 +- .../token_blacklist/models.py | 15 ++-- 26 files changed, 915 insertions(+), 317 deletions(-) diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po index b2a1bb1ed..ee3d7817c 100644 --- a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-03-20 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Ahmed Jazzar \n" "Language: ar\n" "MIME-Version: 1.0\n" @@ -51,7 +51,7 @@ msgid "" msgstr "" "نوع غير معروف '{}'. يجب أن تكون 'leeway' عددًا صحيحًا أو عددًا نسبيًا أو فرق وقت." -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -61,7 +61,7 @@ msgstr "تأشيرة المرور غير صالحة أو منتهية الصلا msgid "Invalid algorithm specified" msgstr "تم تحديد خوارزمية غير صالحة" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -81,6 +81,10 @@ msgstr "لم يتم العثور على حساب نشط للبيانات الم msgid "No active account found for the given token." msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "التأشيرة مدرجة في القائمة السوداء" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -108,30 +112,52 @@ msgstr "تنتهي في" msgid "Token Blacklist" msgstr "قائمة تأشيرات المرور السوداء" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "لا يمكن إنشاء تأشيرة مرور بدون نوع أو عمر" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "التأشيرة ليس لها معرف" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "التأشيرة ليس لها نوع" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "التأشيرة لها نوع خاطئ" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "التأشيرة ليس لديها مطالبة '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "انتهى عمر المطالبة بالتأشيرة '{}'" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "التأشيرة مدرجة في القائمة السوداء" diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index bbb4cc0c3..ff8d0632a 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Lukáš Rod \n" "Language: cs\n" "MIME-Version: 1.0\n" @@ -48,7 +48,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -58,7 +58,7 @@ msgstr "Token není validní nebo vypršela jeho platnost" msgid "Invalid algorithm specified" msgstr "" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -78,6 +78,10 @@ msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" msgid "No active account found for the given token." msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token je na černé listině" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -104,30 +108,52 @@ msgstr "platí do" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Nelze vytvořit token bez zadaného typu nebo životnosti" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token nemá žádný identifikátor" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token nemá žádný typ" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Token má špatný typ" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token nemá žádnou hodnotu '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Hodnota tokenu '{}' vypršela" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po index 2e94bb6e4..a3a638088 100644 --- a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: rene \n" "Language: de_CH\n" "MIME-Version: 1.0\n" @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -60,7 +60,7 @@ msgstr "Ungültiger oder abgelaufener Token" msgid "Invalid algorithm specified" msgstr "" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -80,6 +80,10 @@ msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" msgid "No active account found for the given token." msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token steht auf der Blacklist" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -108,30 +112,52 @@ msgstr "läuft ab am" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Ein Token ohne Typ oder Lebensdauer kann nicht erstellt werden" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token hat keine Id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token hat keinen Typ" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Token hat den falschen Typ" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token hat kein '{}' Recht" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Das Tokenrecht '{}' ist abgelaufen" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index e42d8175b..325d0327b 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: zeack \n" "Language: es\n" "MIME-Version: 1.0\n" @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -60,7 +60,7 @@ msgstr "El token es inválido o ha expirado" msgid "Invalid algorithm specified" msgstr "Algoritmo especificado no válido" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -80,6 +80,10 @@ msgstr "La combinación de credenciales no tiene una cuenta activa" msgid "No active account found for the given token." msgstr "La combinación de credenciales no tiene una cuenta activa" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "El token está en lista negra" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -108,30 +112,52 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "No se puede crear un token sin tipo o de tan larga vida" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index cb47d983a..a6a7bbdb9 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Fabian Falon \n" "Language: es_AR\n" "MIME-Version: 1.0\n" @@ -55,7 +55,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -65,7 +65,7 @@ msgstr "El token es inválido o ha expirado" msgid "Invalid algorithm specified" msgstr "Se especificó un algoritmo no válido." -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -85,6 +85,10 @@ msgstr "No se encontró una cuenta activa con las credenciales proporcionadas." msgid "No active account found for the given token." msgstr "No se encontró una cuenta activa para el token proporcionado" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "El token ha sido revocado" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -113,30 +117,52 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "El token no tiene id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "El token no tiene tipo" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "El token tiene un tipo incorrecto" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "El token no tiene el privilegio '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "El privilegio '{}' del token ha expirado" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "El token ha sido revocado" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index d3ba703ea..cf195f7e8 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Alfonso Pola \n" "Language: es_CL\n" "MIME-Version: 1.0\n" @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -60,7 +60,7 @@ msgstr "Token inválido o expirado" msgid "Invalid algorithm specified" msgstr "" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -82,6 +82,10 @@ msgid "No active account found for the given token." msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token está en la blacklist" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -110,30 +114,52 @@ msgstr "expira en" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "No es posible crear un token sin tipo o tiempo de vida" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token no tiene id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token no tiene tipo" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Token tiene tipo erróneo" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token no tiene privilegio '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "El provilegio '{}' del token está expirado" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po index 582061590..c4156f93d 100644 --- a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-04 09:31+0330\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Mahdi Rahimi \n" "Language: fa\n" @@ -54,7 +54,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -64,7 +64,7 @@ msgstr "توکن نامعتبر است یا منقضی شده است" msgid "Invalid algorithm specified" msgstr "الگوریتم نامعتبر مشخص شده است" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -84,6 +84,10 @@ msgstr "هیچ اکانت فعالی برای اطلاعات داده شده ی msgid "No active account found for the given token." msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "توکن به لیست سیاه رفته است" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -110,30 +114,52 @@ msgstr "زمان انقضا" msgid "Token Blacklist" msgstr "لیست سیاه توکن" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index 9c9285453..7a16cefc3 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-07-06 12:57+0330\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Mahdi Rahimi \n" "Language: fa_IR\n" "MIME-Version: 1.0\n" @@ -48,7 +48,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -58,7 +58,7 @@ msgstr "توکن نامعتبر است یا منقضی شده است" msgid "Invalid algorithm specified" msgstr "الگوریتم نامعتبر مشخص شده است" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -78,6 +78,10 @@ msgstr "هیچ اکانت فعالی برای اطلاعات داده شده ی msgid "No active account found for the given token." msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "توکن به لیست سیاه رفته است" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -104,30 +108,52 @@ msgstr "زمان انقضا" msgid "Token Blacklist" msgstr "لیست سیاه توکن" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "توکن id ندارد" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "توکن نوع ندارد" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "توکن نوع اشتباهی دارد" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "توکن دارای '{}' claim نمی‌باشد" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "'{}' claim توکن منقضی شده" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index db9f0704e..540dff517 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Stéphane Malta e Sousa \n" "Language: fr\n" "MIME-Version: 1.0\n" @@ -50,7 +50,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -60,7 +60,7 @@ msgstr "Le jeton est invalide ou expiré" msgid "Invalid algorithm specified" msgstr "L'algorithme spécifié est invalide" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -80,6 +80,10 @@ msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" msgid "No active account found for the given token." msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Le jeton a été banni" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -108,30 +112,52 @@ msgstr "Expire le" msgid "Token Blacklist" msgstr "Liste des jetons bannis" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Ne peut pas créer de jeton sans type ni durée de vie" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Le jeton n'a pas d'id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Le jeton n'a pas de type" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Le jeton a un type erroné" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Le jeton n'a pas le privilège '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Le privilège '{}' du jeton a expiré" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po index bb182f727..bb934e523 100644 --- a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -53,7 +53,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "סוג לא מזוהה '{}', 'leeway' חייב להיות מסוג int, float או timedelta." -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -63,7 +63,7 @@ msgstr "המזהה אינו חוקי או שפג תוקפו" msgid "Invalid algorithm specified" msgstr "צוין אלגוריתם לא חוקי" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -83,6 +83,10 @@ msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" msgid "No active account found for the given token." msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "המזהה ברשימה השחורה." + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -109,30 +113,52 @@ msgstr "פג תוקף בשעה" msgid "Token Blacklist" msgstr "רשימה שחורה של מזהים" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "לא ניתן ליצור מזהה ללא סוג או אורך חיים" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "למזהה אין מספר זיהוי" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "למזהה אין סוג" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "למזהה יש סוג לא נכון" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "למזהה אין '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "מזהה '{}' פג תוקף" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "המזהה ברשימה השחורה." diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index 2cc4b3b63..48cc7d949 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "PO-Revision-Date: 2023-03-09 08:14+0000\n" "Last-Translator: Kira \n" "Language: id_ID\n" @@ -54,7 +54,7 @@ msgid "" msgstr "" "Tipe '{}' tidak dikenali, 'leeway' harus bertipe int, float, atau timedelta." -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -64,7 +64,7 @@ msgstr "Token tidak valid atau kedaluwarsa" msgid "Invalid algorithm specified" msgstr "Algoritma yang ditentukan tidak valid" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -84,6 +84,10 @@ msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" msgid "No active account found for the given token." msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token masuk daftar hitam" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -112,30 +116,52 @@ msgstr "kedaluwarsa pada" msgid "Token Blacklist" msgstr "Daftar Hitam Token" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Tidak dapat membuat token tanpa tipe atau masa pakai" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token tidak memiliki id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token tidak memiliki tipe" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Jenis token salah" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token tidak memiliki klaim '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Klaim token '{}' telah kedaluwarsa" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index f819b6a0c..05f68fffb 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "PO-Revision-Date: \n" "Last-Translator: Adriano Di Dio <95adriano@gmail.com>\n" "Language-Team: \n" @@ -53,7 +53,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -63,7 +63,7 @@ msgstr "Il token non è valido o è scaduto" msgid "Invalid algorithm specified" msgstr "L'algoritmo specificato non è valido" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -83,6 +83,10 @@ msgstr "Nessun account attivo trovato con queste credenziali" msgid "No active account found for the given token." msgstr "Nessun account attivo trovato con queste credenziali" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Il token è stato inserito nella blacklist" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -111,30 +115,52 @@ msgstr "scade il" msgid "Token Blacklist" msgstr "Blacklist dei token" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Impossibile creare un token senza tipo o durata" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Il token non ha un id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Il token non ha un tipo" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Il token ha un tipo sbagliato" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Il token non contiene il parametro '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Il parametro '{}' del token è scaduto" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index a84af8063..4cdb4061d 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-05 06:48+0900\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: 정재균 \n" "Language: ko_KR\n" "MIME-Version: 1.0\n" @@ -51,7 +51,7 @@ msgstr "" "알 수 없는 타입 '{}', 'leeway' 값은 반드시 int, float 또는 timedelta 타입이어" "야 합니다." -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -61,7 +61,7 @@ msgstr "유효하지 않거나 만료된 토큰입니다" msgid "Invalid algorithm specified" msgstr "잘못된 알고리즘이 지정되었습니다" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -81,6 +81,10 @@ msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 msgid "No active account found for the given token." msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "블랙리스트에 추가된 토큰입니다" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -107,30 +111,52 @@ msgstr "만료 시간" msgid "Token Blacklist" msgstr "토큰 블랙리스트" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "타입 또는 수명이 없는 토큰을 생성할 수 없습니다" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "토큰에 식별자가 주어지지 않았습니다" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "토큰 타입이 주어지지 않았습니다" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "잘못된 토큰 타입입니다" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "토큰에 '{}' 클레임이 없습니다" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "토큰 '{}' 클레임이 만료되었습니다" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "블랙리스트에 추가된 토큰입니다" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index 69603bc47..c52ea9f42 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-17 11:06+0200\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: rene \n" "Language: nl_NL\n" "MIME-Version: 1.0\n" @@ -49,7 +49,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -59,7 +59,7 @@ msgstr "Token is niet geldig of verlopen" msgid "Invalid algorithm specified" msgstr "" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -79,6 +79,10 @@ msgstr "Geen actief account gevonden voor deze gegevens" msgid "No active account found for the given token." msgstr "Geen actief account gevonden voor deze gegevens" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token is ge-blacklist" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -106,30 +110,52 @@ msgstr "verloopt op" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Kan geen token maken zonder type of levensduur" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token heeft geen id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token heeft geen type" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Token heeft het verkeerde type" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token heeft geen '{}' recht" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Token '{}' recht is verlopen" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index 9037642ba..8437ce90f 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Mateusz Slisz \n" "Language: pl_PL\n" "MIME-Version: 1.0\n" @@ -48,7 +48,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -58,7 +58,7 @@ msgstr "Token jest niepoprawny lub wygasł" msgid "Invalid algorithm specified" msgstr "" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -78,6 +78,10 @@ msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" msgid "No active account found for the given token." msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token znajduję się na czarnej liście" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -105,30 +109,52 @@ msgstr "wygasa o" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Nie można utworzyć tokena bez podanego typu lub żywotności" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token nie posiada numeru identyfikacyjnego" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token nie posiada typu" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Token posiada zły typ" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token nie posiada upoważnienia '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Upoważnienie tokena '{}' wygasło" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.mo index 7592fcb28fb76d1386f315edba252bf5e5d17545..1ac0f47e1d78a35417672e49a6c30f24f9b05fde 100644 GIT binary patch delta 1484 zcmZwF&uf%N7zgk%ztdKYF&blxd6G450x^YZZ3Jr@#i+$56g~L!Fx_{uJLb*I^3J#hj24EiSY9V>+R7#^;{4_Z^L5W8VBTmwg8D?A1_!$~*@=U_ivfSqtL zoqq#A!FZr9S$_)hdIQIWm=)*n(1(e?AP4XYu7+*(LTrayAkQCz?XU#-|4Wbqx&hnZ z-PGS<3&xL9pFs}jH6+;HAjBa!3|nx%IFE-_n1~?X{1*HGK1h8GaS8DhA~x{?b|OnJ z;bDwdHYEX^fa@@}uoqr{pTXPkbGQfzZf+K0C;S2u&KG4oZ~#{!NB$c;2^U}wT#INj z@KeYK9ES&>g%v^%FocIMIF>!f7oGs1-zr&4#;)^Ubd_Q~Q8}TiEOE?hTm{KfK@!a3yoa^o*%B|3-Qh>n`QZQaqf znvuPGeVLo|wF{L;NA09CV%dy)XDZ~EXu<~6*I#lf7>N9ui)}m(3ySi(jDO>IhN34m zJ2K;?(1p@?+T_#ym(4_LYL8^FmUqiKDoW?h+Q6fNbo8ylcDaHydF4g2RFb|r~FV3MPA+go_)S8D@Wr#E~^7cyL0h`O~<)h zG+O`9*GU*g5@%PEQTae7u{nC*?EfZ_2W*|@*hSkLuI(ICrcj!al(PmK%21ajDZ`^c zdNNsHljL)OjLK=x4n_AHdb^WgipqG(glZ{_rLl{iH=L#sayUSeXHkk$Wj@dr+h~%0 zsQ7?rv~jNeov5k`@Mq(NjB;URp5ih{&x-Lhl*%2hL}lJbG|~R1uf~q*qKykcrt+&L fE{!R~!B$noQ)PvK0uCqS1=S@fRhQ)Frl0-;vWhx4 delta 655 zcmX}pODIH97{Kw5x%2j%@upl!EW97tuowvoC2KaGvk^5lQp&R_&4xOpu$Js)$-+V` zZ0tyOO0u!BK>pvI%h#OyJKs5H&b{Y52j#nw)u)KHCqx;oiuOpWqa9`OAX>9Udaw-} zaUL7+5G(Nt+wmDkFzU(dGllu&YuJH1Sc+Hf_#+mItjZgmA|`%ZqgH0)2DBOP#{!(e zJY2*UOkoJmTrZI=g=gf{sA)?*w?aNC_fMy<#N26?}HXa~PhPv9q^D`DgS z&gS5RuKNr9h^U+7x<-(ja6-$i*Q(Xy@Xp@4uSS@r)okOi|G`0=FV%q@nwC+oMng-j z_bJBfiJ7z~ZDLlXS+_>br!{Mqy>Vmty3D5Ux~wmeoL{i}lT(R_\n" +"POT-Creation-Date: 2025-02-28 15:08-0300\n" +"Last-Translator: Cloves Oliveira \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -35,7 +35,7 @@ msgstr "Usuário está inativo" #: authentication.py:142 msgid "The user's password has been changed." -msgstr "" +msgstr "A senha do usuário foi alterada." #: backends.py:90 msgid "Unrecognized algorithm type '{}'" @@ -49,36 +49,35 @@ msgstr "Você deve ter criptografia instalada para usar {}." msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" +"Tipo '{}' não reconhecido, 'leeway' deve ser do tipo int, float ou timedelta." -#: backends.py:125 backends.py:177 tokens.py:68 -#, fuzzy -#| msgid "Token is invalid or expired" +#: backends.py:125 backends.py:177 tokens.py:69 msgid "Token is invalid" -msgstr "O token é inválido ou expirado" +msgstr "O token é inválido" #: backends.py:173 msgid "Invalid algorithm specified" msgstr "Algoritmo inválido especificado" -#: backends.py:175 tokens.py:66 -#, fuzzy -#| msgid "Token is invalid or expired" +#: backends.py:175 tokens.py:67 msgid "Token is expired" -msgstr "O token é inválido ou expirado" +msgstr "Token expirado" #: exceptions.py:55 msgid "Token is invalid or expired" -msgstr "O token é inválido ou expirado" +msgstr "Token inválido ou expirado" #: serializers.py:35 msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" #: serializers.py:108 -#, fuzzy -#| msgid "No active account found with the given credentials" msgid "No active account found for the given token." -msgstr "Usuário e/ou senha incorreto(s)" +msgstr "Nenhuma conta ativa encontrada para o token fornecido." + +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token está na blacklist" #: settings.py:74 msgid "" @@ -108,30 +107,52 @@ msgstr "expira em" msgid "Token Blacklist" msgstr "Lista negra de Tokens" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "Token pendente" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "Tokens pendentes" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "Token para %(user)s (%(jti)s)" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "Token na lista negra" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "Tokens na lista negra" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "Token na lista negra para %(user)s" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Não é possível criar token sem tipo ou tempo de vida" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token não tem id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token não tem nenhum tipo" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Token tem tipo errado" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token não tem '{}' privilégio" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "O privilégio '{}' do token expirou" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po index ac1d56442..3cd280dfd 100644 --- a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-07-13 10:45+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Daniel Cuznetov \n" "Language: ro\n" "MIME-Version: 1.0\n" @@ -53,7 +53,7 @@ msgstr "" "Tipul '{}' nu este recunoscut, 'leeway' trebuie să fie de tip int, float sau " "timedelta." -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -63,7 +63,7 @@ msgstr "Token nu este valid sau a expirat" msgid "Invalid algorithm specified" msgstr "Algoritm nevalid specificat" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -83,6 +83,10 @@ msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" msgid "No active account found for the given token." msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Tokenul este în listă de tokenuri blocate" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -110,30 +114,52 @@ msgstr "expiră la" msgid "Token Blacklist" msgstr "Listă de token-uri blocate" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Nu se poate crea token fără tip sau durată de viață" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Tokenul nu are id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Tokenul nu are tip" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Tokenul are tipul greșit" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Tokenul nu are reclamația '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Reclamația tokenului '{}' a expirat" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Tokenul este în listă de tokenuri blocate" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index ce3bab13f..1ffe05aea 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-02-22 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "PO-Revision-Date: \n" "Last-Translator: Sergey Ozeranskiy \n" "Language-Team: \n" @@ -54,7 +54,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -64,7 +64,7 @@ msgstr "Токен недействителен или просрочен" msgid "Invalid algorithm specified" msgstr "" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -84,6 +84,10 @@ msgstr "Не найдено активной учетной записи с ук msgid "No active account found for the given token." msgstr "Не найдено активной учетной записи с указанными данными" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Токен занесен в черный список" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -112,30 +116,52 @@ msgstr "истекает" msgid "Token Blacklist" msgstr "Token Blacklist" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Невозможно создать токен без типа или времени жизни" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "У токена нет идентификатора" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Токен не имеет типа" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Токен имеет неправильный тип" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Токен не содержит '{}'" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Токен имеет просроченное значение '{}'" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po index 88ce161dc..46cc09cef 100644 --- a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-11-19 20:46+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "PO-Revision-Date: \n" "Last-Translator: Urban Prevc \n" "Language-Team: \n" @@ -54,7 +54,7 @@ msgid "" msgstr "" "Neprepoznana vrsta '{}', 'leeway' mora biti vrste int, float ali timedelta." -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -64,7 +64,7 @@ msgstr "Žeton je neveljaven ali potekel" msgid "Invalid algorithm specified" msgstr "Naveden algoritem je neveljaven" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -84,6 +84,10 @@ msgstr "Aktiven račun s podanimi poverilnicami ni najden" msgid "No active account found for the given token." msgstr "Aktiven račun s podanimi poverilnicami ni najden" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Žeton je na črnem seznamu" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -112,30 +116,52 @@ msgstr "poteče ob" msgid "Token Blacklist" msgstr "Črni seznam žetonov" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Ni mogoče ustvariti žetona brez vrste ali življenjske dobe" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Žetonu manjka id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Žetonu manjka vrsta" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Žeton je napačne vrste" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Žeton nima '{}' zahtevka" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "'{}' zahtevek žetona je potekel" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Žeton je na črnem seznamu" diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po index c09b35ef1..f6cb0e0a7 100644 --- a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-05-29 17:30+0100\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Pasindu \n" "Language: sv\n" "MIME-Version: 1.0\n" @@ -49,7 +49,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -59,7 +59,7 @@ msgstr "Token är ogiltig eller har löpt ut" msgid "Invalid algorithm specified" msgstr "Ogiltig algoritm har angetts" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -79,6 +79,10 @@ msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" msgid "No active account found for the given token." msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token är svartlistad" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -106,30 +110,52 @@ msgstr "går ut kl" msgid "Token Blacklist" msgstr "Token svartlist" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Kan inte skapa token utan typ eller livslängd" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token har inget id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token har ingen typ" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Token har fel typ" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token har inget '{}'-anspråk" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Token '{}'-anspråket har löpt ut" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token är svartlistad" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 04ce8e055..5464e09a9 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-13 23:05+0300\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "Last-Translator: Şuayip Üzülmez \n" "Language: tr\n" "MIME-Version: 1.0\n" @@ -51,7 +51,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -61,7 +61,7 @@ msgstr "Token geçersiz veya süresi geçmiş" msgid "Invalid algorithm specified" msgstr "Geçersiz algoritma belirtildi" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -81,6 +81,10 @@ msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" msgid "No active account found for the given token." msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Token kara listeye alınmış" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -107,30 +111,52 @@ msgstr "sona erme tarihi" msgid "Token Blacklist" msgstr "Token Kara Listesi" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Tipi veya geçerlilik süresi olmayan token oluşturulamaz" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "Token'in id'si yok" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "Token'in tipi yok" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "Token'in tipi yanlış" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "Token'in '{}' claim'i yok" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Token'in '{}' claim'i sona erdi" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Token kara listeye alınmış" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index 890c3af58..cc94accd2 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-17 12:32+0300\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Artiukhov Artem \n" "Language-Team: LANGUAGE \n" @@ -52,7 +52,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -62,7 +62,7 @@ msgstr "Токен некоректний або термін його дії в msgid "Invalid algorithm specified" msgstr "Вказаний невірний алгоритм" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -82,6 +82,10 @@ msgstr "Не знайдено жодного облікового запису msgid "No active account found for the given token." msgstr "Не знайдено жодного облікового запису по наданих облікових даних" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "Токен занесений у чорний список" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -108,30 +112,52 @@ msgstr "дійстний по" msgid "Token Blacklist" msgstr "Чорний список токенів" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "Неможливо створити токен без типу або строку дії" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "У ключі доступу не міститься id" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "У ключі доступу не міститься тип" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "токен позначений невірним типом" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "У токені не міститься '{}' заголовку" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "Заголовок '{}' токена не дійсний" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index 317a8e631..b6fb095ed 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-06-23 13:29+0800\n" +"POT-Creation-Date: 2025-02-28 15:09-0300\n" "PO-Revision-Date: 2021-06-23 13:29+080\n" "Last-Translator: zengqiu \n" "Language: zh_Hans\n" @@ -52,7 +52,7 @@ msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." msgstr "" -#: backends.py:125 backends.py:177 tokens.py:68 +#: backends.py:125 backends.py:177 tokens.py:69 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is invalid" @@ -62,7 +62,7 @@ msgstr "令牌无效或已过期" msgid "Invalid algorithm specified" msgstr "指定的算法无效" -#: backends.py:175 tokens.py:66 +#: backends.py:175 tokens.py:67 #, fuzzy #| msgid "Token is invalid or expired" msgid "Token is expired" @@ -82,6 +82,10 @@ msgstr "找不到指定凭据对应的有效用户" msgid "No active account found for the given token." msgstr "找不到指定凭据对应的有效用户" +#: serializers.py:178 tokens.py:299 +msgid "Token is blacklisted" +msgstr "令牌已被加入黑名单" + #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " @@ -108,30 +112,52 @@ msgstr "过期时间" msgid "Token Blacklist" msgstr "令牌黑名单" -#: tokens.py:52 +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "" + +#: tokens.py:53 msgid "Cannot create token with no type or lifetime" msgstr "无法创建没有类型或生存期的令牌" -#: tokens.py:126 +#: tokens.py:127 msgid "Token has no id" msgstr "令牌没有标识符" -#: tokens.py:138 +#: tokens.py:139 msgid "Token has no type" msgstr "令牌没有类型" -#: tokens.py:141 +#: tokens.py:142 msgid "Token has wrong type" msgstr "令牌类型错误" -#: tokens.py:200 +#: tokens.py:201 msgid "Token has no '{}' claim" msgstr "令牌没有 '{}' 声明" -#: tokens.py:205 +#: tokens.py:206 msgid "Token '{}' claim has expired" msgstr "令牌 '{}' 声明已过期" - -#: tokens.py:292 -msgid "Token is blacklisted" -msgstr "令牌已被加入黑名单" diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index 7eea55f7f..45c5a771c 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -175,7 +175,7 @@ def validate(self, attrs: dict[str, None]) -> dict[Any, Any]: ): jti = token.get(api_settings.JTI_CLAIM) if BlacklistedToken.objects.filter(token__jti=jti).exists(): - raise ValidationError("Token is blacklisted") + raise ValidationError(_("Token is blacklisted")) return {} diff --git a/rest_framework_simplejwt/token_blacklist/models.py b/rest_framework_simplejwt/token_blacklist/models.py index e5058fd34..30e9ee38d 100644 --- a/rest_framework_simplejwt/token_blacklist/models.py +++ b/rest_framework_simplejwt/token_blacklist/models.py @@ -1,5 +1,6 @@ from django.conf import settings from django.db import models +from django.utils.translation import gettext_lazy as _ class OutstandingToken(models.Model): @@ -15,6 +16,8 @@ class OutstandingToken(models.Model): expires_at = models.DateTimeField() class Meta: + verbose_name = _("Outstanding Token") + verbose_name_plural = _("Outstanding Tokens") # Work around for a bug in Django: # https://code.djangoproject.com/ticket/19422 # @@ -26,10 +29,10 @@ class Meta: ordering = ("user",) def __str__(self) -> str: - return "Token for {} ({})".format( - self.user, - self.jti, - ) + return _("Token for %(user)s (%(jti)s)") % { + "user": self.user, + "jti": self.jti, + } class BlacklistedToken(models.Model): @@ -39,6 +42,8 @@ class BlacklistedToken(models.Model): blacklisted_at = models.DateTimeField(auto_now_add=True) class Meta: + verbose_name = _("Blacklisted Token") + verbose_name_plural = _("Blacklisted Tokens") # Work around for a bug in Django: # https://code.djangoproject.com/ticket/19422 # @@ -49,4 +54,4 @@ class Meta: ) def __str__(self) -> str: - return f"Blacklisted token for {self.token.user}" + return _("Blacklisted token for %(user)s") % {"user": self.token.user} From 00de02864403aadc60a5ad43feb27afa0fec1fbd Mon Sep 17 00:00:00 2001 From: Jonathan Hanson Date: Mon, 3 Mar 2025 11:44:56 -0800 Subject: [PATCH 139/171] Repair the type annotations in the TokenViewBase class. (#880) * Repair the type annotations in the TokenViewBase class. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Ah, python3.9 did support parameterizing the 'type' type. I wasn't sure. So we don't need the Type from typing. * The abstract type is BaseSerializer, not Serializer --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- rest_framework_simplejwt/views.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rest_framework_simplejwt/views.py b/rest_framework_simplejwt/views.py index 98697ed72..f0c257dc6 100644 --- a/rest_framework_simplejwt/views.py +++ b/rest_framework_simplejwt/views.py @@ -1,8 +1,10 @@ +from typing import Optional + from django.utils.module_loading import import_string from rest_framework import generics, status from rest_framework.request import Request from rest_framework.response import Response -from rest_framework.serializers import Serializer +from rest_framework.serializers import BaseSerializer from .authentication import AUTH_HEADER_TYPES from .exceptions import InvalidToken, TokenError @@ -13,12 +15,12 @@ class TokenViewBase(generics.GenericAPIView): permission_classes = () authentication_classes = () - serializer_class = None + serializer_class: Optional[type[BaseSerializer]] = None _serializer_class = "" www_authenticate_realm = "api" - def get_serializer_class(self) -> Serializer: + def get_serializer_class(self) -> type[BaseSerializer]: """ If serializer_class is set, use it directly. Otherwise get the class from settings. """ From 027c79c8f35b2520a675e728db4c37848025297b Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Mon, 10 Mar 2025 14:39:06 -0400 Subject: [PATCH 140/171] fix: Token.outstand forces users to install blacklist app (#884) --- rest_framework_simplejwt/tokens.py | 47 +++++++++++++++++------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 92d395306..431540760 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -205,30 +205,12 @@ def check_exp( if claim_time <= current_time - leeway: raise TokenError(format_lazy(_("Token '{}' claim has expired"), claim)) - def outstand(self) -> OutstandingToken: + def outstand(self) -> Optional[OutstandingToken]: """ Ensures this token is included in the outstanding token list and adds it to the outstanding token list if not. """ - 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 - return OutstandingToken.objects.get_or_create( - jti=jti, - defaults={ - "user": user, - "created_at": self.current_time, - "token": str(self), - "expires_at": datetime_from_epoch(exp), - }, - ) + return None @classmethod def for_user(cls: type[T], user: AuthUser) -> T: @@ -325,6 +307,31 @@ def blacklist(self) -> BlacklistedToken: return BlacklistedToken.objects.get_or_create(token=token) + def outstand(self) -> Optional[OutstandingToken]: + """ + Ensures this token is included in the outstanding token list and + adds it to the outstanding token list if not. + """ + 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 + return OutstandingToken.objects.get_or_create( + jti=jti, + defaults={ + "user": user, + "created_at": self.current_time, + "token": str(self), + "expires_at": datetime_from_epoch(exp), + }, + ) + @classmethod def for_user(cls: type[T], user: AuthUser) -> T: """ From 1ac00c62a835d77914a6976a13bff108d1dcb411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Mon, 10 Mar 2025 21:49:26 +0100 Subject: [PATCH 141/171] fix: PytestConfigWarning Unknown config option: python_paths (#886) --- pytest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest.ini b/pytest.ini index f5fdc0ec9..85e8da7f9 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,6 @@ [pytest] addopts= -v --showlocals --durations 10 -python_paths= . +pythonpath= . xfail_strict=true [pytest-watch] From acacec825f16acf092c8a69ab7a109fb5f36c14e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Mon, 10 Mar 2025 22:32:42 +0100 Subject: [PATCH 142/171] fix: Do not copy `iat` claim from refresh token (#888) * fix: Do not copy `iat` claim from refresh token * fix test by freezing time --- rest_framework_simplejwt/tokens.py | 1 + tests/test_tokens.py | 10 +++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 431540760..d97b3de96 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -386,6 +386,7 @@ class RefreshToken(BlacklistMixin["RefreshToken"], Token): # we wouldn't want to copy either one. api_settings.JTI_CLAIM, "jti", + "iat", ) access_token_class = AccessToken diff --git a/tests/test_tokens.py b/tests/test_tokens.py index 5605bae08..455870f9c 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -4,6 +4,7 @@ from django.contrib.auth import get_user_model from django.test import TestCase +from freezegun import freeze_time from jose import jwt from rest_framework_simplejwt.exceptions import ( @@ -434,10 +435,13 @@ def test_init(self): def test_access_token(self): # Should create an access token from a refresh token - refresh = RefreshToken() - refresh["test_claim"] = "arst" + with freeze_time("2025-01-01"): + refresh = RefreshToken() + refresh["test_claim"] = "arst" - access = refresh.access_token + with freeze_time("2025-01-02"): + # Ensure iat is different + access = refresh.access_token self.assertIsInstance(access, AccessToken) self.assertEqual(access[api_settings.TOKEN_TYPE_CLAIM], "access") From 54703bbce9dc5f83b8e031498d6710f690fb6d10 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 13:42:44 +0530 Subject: [PATCH 143/171] [pre-commit.ci] pre-commit autoupdate (#882) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.9.7 → v0.9.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.7...v0.9.10) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Ashwanth Balakrishnan --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8fbe2d201..02f1e5d4b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-merge-conflict - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.7 + rev: v0.9.10 hooks: - id: ruff types_or: [ python, pyi ] From acb1483e21953282423a5b97b9c535f686ec71d0 Mon Sep 17 00:00:00 2001 From: Mahdi Rahimi <31624047+mahdirahimi1999@users.noreply.github.com> Date: Fri, 28 Mar 2025 04:09:42 +0330 Subject: [PATCH 144/171] Update Persian translations (fa, fa_IR) for Django application (#897) --- .../locale/fa/LC_MESSAGES/django.mo | Bin 3006 -> 3823 bytes .../locale/fa/LC_MESSAGES/django.po | 51 ++++++++---------- .../locale/fa_IR/LC_MESSAGES/django.mo | Bin 2941 -> 3722 bytes .../locale/fa_IR/LC_MESSAGES/django.po | 38 ++++++------- 4 files changed, 38 insertions(+), 51 deletions(-) diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo index e94394f2a6dba63320b4750ee0b9b6d3a379a311..8d996fbafc49435b6afe5aa8ca66146f7663fcaa 100644 GIT binary patch delta 1449 zcmZwFTS!zv7{KvyGu_>8TI!Z&PF_kwE4vXDK|OSVN(w=Z3M4n%lr7vLMhzO#mf{OZoXHQ!^0*ohnP5lY}=cnBBz zl&ZpGxI^ag08U~h`>R5B%f!nlCB22M_!PI}`bCKnpT=zZ*YN~C#6tXzn=yBBqLRl@ zDi%c0*j?|h#_Vp>Hxawz&saKlijgX3M4NsyDDV7DA~L;Prs8&w-KFg= zyT^>`iJ0lrW`vDK5rqA?CpHG-4bmG<--%9Iv>cEalNFHQona_LMbBGPjoag4zFOGOK#^zTN3& zn5|i2cT*UN*Lva0@i=6jHF2gAg>bWVUXC-y9+b!3Y&stnkbWmwGq25%6vytCg76il n#+jFV8FQCfQ{HSV$G>hU-+wcyXeOGO8aZdJ#s{2G$VUAEKQ@p0 delta 866 zcmZ|MPe>F|9Ki9P?(CN1Y^J$cS@0;#0!32_f-aIBq9BbRvY>*6vV*4xqQhdDyDs9P zM~7I5Zu=)_8#V|jf-YUUMZ}wxIz-2yAR?$s-`}vFq945Z{N~Nfd%yX;Z@XUgvk z7tiNpH%T`WW7vz6EzhBDFoy<;tuyDl`*ZC7>` zy>E~_aWy;H@!FpBM{Vej*w6kWyVQBpmIB`%2=?Y?vn=H5ycxQ>xLQ\>, 2023. +# FIRST AUTHOR , 2023. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-02-28 15:09-0300\n" +"POT-Creation-Date: 2025-03-27 15:19+0330\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Mahdi Rahimi \n" "Language: fa\n" @@ -25,19 +24,19 @@ msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا ش msgid "Given token not valid for any token type" msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "کاربر یافت نشد" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "رمز عبور کاربر تغییر کرده است" @@ -55,20 +54,16 @@ msgid "" msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." #: backends.py:125 backends.py:177 tokens.py:69 -#, fuzzy -#| msgid "Token is invalid or expired" msgid "Token is invalid" -msgstr "توکن نامعتبر است یا منقضی شده است" +msgstr "توکن نامعتبر است" #: backends.py:173 msgid "Invalid algorithm specified" msgstr "الگوریتم نامعتبر مشخص شده است" #: backends.py:175 tokens.py:67 -#, fuzzy -#| msgid "Token is invalid or expired" msgid "Token is expired" -msgstr "توکن نامعتبر است یا منقضی شده است" +msgstr "توکن منقضی شده است" #: exceptions.py:55 msgid "Token is invalid or expired" @@ -79,24 +74,22 @@ msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" #: serializers.py:108 -#, fuzzy -#| msgid "No active account found with the given credentials" msgid "No active account found for the given token." -msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" +msgstr "هیچ اکانت فعالی برای این توکن یافت نشد" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:281 msgid "Token is blacklisted" -msgstr "توکن به لیست سیاه رفته است" +msgstr "توکن در لیست سیاه قرار گرفته است" #: settings.py:74 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." -msgstr "تنظیمات '{}' حذف شده است. لطفا به '{}' برای تنظیمات موجود مراجعه کنید." +msgstr "تنظیمات '{}' حذف شده است. لطفاً به '{}' برای تنظیمات موجود مراجعه کنید." #: token_blacklist/admin.py:79 msgid "jti" -msgstr "jti" +msgstr "شناسه توکن (jti)" #: token_blacklist/admin.py:85 msgid "user" @@ -116,33 +109,33 @@ msgstr "لیست سیاه توکن" #: token_blacklist/models.py:19 msgid "Outstanding Token" -msgstr "" +msgstr "توکن برجسته" #: token_blacklist/models.py:20 msgid "Outstanding Tokens" -msgstr "" +msgstr "توکن‌های برجسته" #: token_blacklist/models.py:32 #, python-format msgid "Token for %(user)s (%(jti)s)" -msgstr "" +msgstr "توکن برای %(user)s (%(jti)s)" #: token_blacklist/models.py:45 msgid "Blacklisted Token" -msgstr "" +msgstr "توکن لیست سیاه شده" #: token_blacklist/models.py:46 msgid "Blacklisted Tokens" -msgstr "" +msgstr "توکن‌های لیست سیاه شده" #: token_blacklist/models.py:57 #, python-format msgid "Blacklisted token for %(user)s" -msgstr "" +msgstr "توکن لیست سیاه شده برای %(user)s" #: tokens.py:53 msgid "Cannot create token with no type or lifetime" -msgstr "توکن بدون هیچ نوع و طول عمر قابل ساخت نیست" +msgstr "توکن بدون نوع یا طول عمر قابل ایجاد نیست" #: tokens.py:127 msgid "Token has no id" @@ -150,11 +143,11 @@ msgstr "توکن id ندارد" #: tokens.py:139 msgid "Token has no type" -msgstr "توکن نوع ندارد" +msgstr "توکن نوعی ندارد" #: tokens.py:142 msgid "Token has wrong type" -msgstr "توکن نوع اشتباهی دارد" +msgstr "توکن دارای نوع نادرستی است" #: tokens.py:201 msgid "Token has no '{}' claim" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.mo index b43b671dd0758c0457d934ec2082a456b74140e8..ff90df9e84dea63b3e18d2f3b4fdb600ebb89afe 100644 GIT binary patch delta 1311 zcmaLVPe>F|90%~(<(uJ3^ra1e6)DCB^~U^z@XzJR6pw;Y!s2lNFB zSW!rH93FzDSf6gAupSi>^3ET^BKX$v9mFPR5h6BPhRg6148u7uQ7vrqe=SiZJO)q0URVzw!@V#E zd3v z6e314pbPT#aN^V2j?AaWiRY@bOZg9iFzlUkRD4H>gK$l>1(_2zM1EwPpnXLGa^eTX zcV5FkNc;{sAWj?zCw{;DZul*1M&`ut2YcX~Alw=i+AE;IsaBqHA8l=og?ghgRgXu) zqN_g|(P&kT{zp}uJBjoC1EL`?s7D5ZGUZN{^MCw8MD(dcXtnz^$?xu#y3WD49uH|@ zRqJ!+UsWTU3+DYRCe%fsA#gFS2KAs+JX%HM%4KyR5+*x5q3S}_hC(ql6Z3SrjkGx< ztUI}snK7q?nL%OPN|HHc4QD5<#D|+HD`}4BQvd0*x=EN5=8Qec*`oeyLT*Z1!&X9A z$y_R%kgp4uyv}0srB}F`!oe|!2tq=lRc|pc zTxQ$0tVNg*MA5QEt62<#1T%}MHZ$9SHbVdNbPnA6yPoHJ_uO;6Q{z-`CvL3^k!H*> z_84avUjs};H7IfkYj_q{aUQ>527hA_B_whKN~rI@MEzbLWB46QxP`|tYWew|oMv&9 zL=h8sdFmb14LX=Z4=eZ{kKjHYMmsEW9+McwD^sh;UUC=ttK3IDToapEvqi2;PvjGe zB@)3Ik&9TzTeyZ#@h>jmy~yNb2DMwC@g{C!0rQ7MQg|En`6JAuhg#rA)K31wbC{*t z2K&n*iyVGHeQ^WpxQoZ|sxz^UdZG^UNFJl!lD6|8G=C6r7Rl)k?G$zT9p=XTILTbo z4YmDr#s4_P`Qb9_z0n-M2u;!mIiU+;mZ5Fc6Khb5e=TCdp|bHpo+(=y^TOIT-SESq zWmkgcTjZayqZdp&`p(IBpXYNA+Ktvq&b)Th=9=@&{Ba7wR?}qNSLTPC7>?aeAh!IZ QB|rP4H>1Jm?PwtX0at=fegFUf diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index 7a16cefc3..55329e0c8 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: djangorestframework_simplejwt\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-02-28 15:09-0300\n" +"POT-Creation-Date: 2025-03-27 15:19+0330\n" "Last-Translator: Mahdi Rahimi \n" "Language: fa_IR\n" "MIME-Version: 1.0\n" @@ -19,19 +19,19 @@ msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا ش msgid "Given token not valid for any token type" msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "کاربر یافت نشد" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "رمز عبور کاربر تغییر کرده است" @@ -49,20 +49,16 @@ msgid "" msgstr "نوع ناشناخته '{}'، 'leeway' باید از نوع int، float یا timedelta باشد." #: backends.py:125 backends.py:177 tokens.py:69 -#, fuzzy -#| msgid "Token is invalid or expired" msgid "Token is invalid" -msgstr "توکن نامعتبر است یا منقضی شده است" +msgstr "توکن نامعتبر است" #: backends.py:173 msgid "Invalid algorithm specified" msgstr "الگوریتم نامعتبر مشخص شده است" #: backends.py:175 tokens.py:67 -#, fuzzy -#| msgid "Token is invalid or expired" msgid "Token is expired" -msgstr "توکن نامعتبر است یا منقضی شده است" +msgstr "توکن منقضی شده است" #: exceptions.py:55 msgid "Token is invalid or expired" @@ -73,12 +69,10 @@ msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" #: serializers.py:108 -#, fuzzy -#| msgid "No active account found with the given credentials" msgid "No active account found for the given token." -msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" +msgstr "هیچ اکانت فعالی برای توکن داده شده یافت نشد" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:281 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" @@ -90,7 +84,7 @@ msgstr "تنظیمات '{}' حذف شده است. لطفا به '{}' برای ت #: token_blacklist/admin.py:79 msgid "jti" -msgstr "jti" +msgstr "شناسه توکن (jti)" #: token_blacklist/admin.py:85 msgid "user" @@ -110,29 +104,29 @@ msgstr "لیست سیاه توکن" #: token_blacklist/models.py:19 msgid "Outstanding Token" -msgstr "" +msgstr "توکن برجسته" #: token_blacklist/models.py:20 msgid "Outstanding Tokens" -msgstr "" +msgstr "توکن‌های برجسته" #: token_blacklist/models.py:32 #, python-format msgid "Token for %(user)s (%(jti)s)" -msgstr "" +msgstr "توکن برای %(user)s (%(jti)s)" #: token_blacklist/models.py:45 msgid "Blacklisted Token" -msgstr "" +msgstr "توکن در لیست سیاه" #: token_blacklist/models.py:46 msgid "Blacklisted Tokens" -msgstr "" +msgstr "توکن‌های لیست سیاه" #: token_blacklist/models.py:57 #, python-format msgid "Blacklisted token for %(user)s" -msgstr "" +msgstr "توکن لیست سیاه برای %(user)s" #: tokens.py:53 msgid "Cannot create token with no type or lifetime" From 774a6f8634446a6c48e8801eb05935afa053252a Mon Sep 17 00:00:00 2001 From: juanBailon <66891215+juanbailon@users.noreply.github.com> Date: Mon, 28 Apr 2025 14:55:14 -0500 Subject: [PATCH 145/171] fix: add missing migration for token_blacklist app (#894) * fix: add missing migration for token_blacklist app PR #879 modified both the OutstandingToken and BlacklistedToken models Meta class, but did not include the migration. This commit adds the missing migration file. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * test: Add check for ungenerated migrations This adds a test to ensure all model changes are reflected in migrations. If ungenerated migrations are detected, the test will fail, enforcing migration consistency. References: - PR #894 - Issue #895 * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- ...alter_blacklistedtoken_options_and_more.py | 27 ++++++++++++ tests/test_migrations.py | 42 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 rest_framework_simplejwt/token_blacklist/migrations/0013_alter_blacklistedtoken_options_and_more.py create mode 100644 tests/test_migrations.py diff --git a/rest_framework_simplejwt/token_blacklist/migrations/0013_alter_blacklistedtoken_options_and_more.py b/rest_framework_simplejwt/token_blacklist/migrations/0013_alter_blacklistedtoken_options_and_more.py new file mode 100644 index 000000000..9212c7cf4 --- /dev/null +++ b/rest_framework_simplejwt/token_blacklist/migrations/0013_alter_blacklistedtoken_options_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 5.1.7 on 2025-03-23 06:56 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("token_blacklist", "0012_alter_outstandingtoken_user"), + ] + + operations = [ + migrations.AlterModelOptions( + name="blacklistedtoken", + options={ + "verbose_name": "Blacklisted Token", + "verbose_name_plural": "Blacklisted Tokens", + }, + ), + migrations.AlterModelOptions( + name="outstandingtoken", + options={ + "ordering": ("user",), + "verbose_name": "Outstanding Token", + "verbose_name_plural": "Outstanding Tokens", + }, + ), + ] diff --git a/tests/test_migrations.py b/tests/test_migrations.py new file mode 100644 index 000000000..6e8d08b47 --- /dev/null +++ b/tests/test_migrations.py @@ -0,0 +1,42 @@ +from io import StringIO +from typing import Optional + +import pytest +from django.core.management import call_command +from django.test import TestCase + + +class MigrationTestCase(TestCase): + def test_no_missing_migrations(self): + """ + Ensures all model changes are reflected in migrations. + If this test fails, there are model changes that require a new migration. + + Behavior: + - Passes silently if no migrations are required + - Fails with a detailed message if migrations are need + """ + + output = StringIO() + + # Initialize exception variable to track migration check result + exec: Optional[SystemExit] = None + + try: + # Check for pending migrations without actually creating them + call_command( + "makemigrations", "--check", "--dry-run", stdout=output, stderr=output + ) + except SystemExit as e: + # Capture the SystemExit if migrations are needed (the command will had ended with exit code 1) + exec = e + + # If an exception was raised, verify it indicates no migration changes are required + if exec is not None: + self.assertEqual( + exec.code, + 0, # 0 means no migrations needed + f"Model changes detected that require migrations!\n" + f"Please run `python manage.py makemigrations` to create the necessary migrations.\n\n" + f"Detected Changes:\n{output.getvalue()}", + ) From 71c72e1555c9288814ad2e32a38738639ad6d753 Mon Sep 17 00:00:00 2001 From: Mahdi Date: Sat, 12 Apr 2025 14:57:55 +0330 Subject: [PATCH 146/171] chore: add Django 5.2 support to test matrix and packaging - Added Django 5.2 to the GitHub Actions workflow matrix - Updated tox.ini to include Django 5.2 test environments - Declared Django 5.2 support in setup.py classifiers and deps --- .github/workflows/test.yml | 2 +- setup.py | 1 + tox.ini | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 76c99c7a1..3d5049fa7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,7 +16,7 @@ jobs: max-parallel: 5 matrix: python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] - django-version: ['4.2', '5.0', '5.1'] + django-version: ['4.2', '5.0', '5.1', '5.2'] drf-version: ['3.14', '3.15'] exclude: - drf-version: '3.14' diff --git a/setup.py b/setup.py index aa08d5295..eca37ad62 100755 --- a/setup.py +++ b/setup.py @@ -73,6 +73,7 @@ "Framework :: Django :: 4.2", "Framework :: Django :: 5.0", "Framework :: Django :: 5.1", + "Framework :: Django :: 5.2", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", diff --git a/tox.ini b/tox.ini index bc63d3640..5db99c96b 100644 --- a/tox.ini +++ b/tox.ini @@ -3,6 +3,7 @@ envlist= py{39,310,311,312}-dj42-drf{314,315}-pyjwt{171,2}-tests py{310,311,312}-dj50-drf315-pyjwt{171,2}-tests py{310,311,312,313}-dj51-drf315-pyjwt{171,2}-tests + py{311,312,313}-dj52-drf315-pyjwt{171,2}-tests docs [gh-actions] @@ -18,6 +19,7 @@ DJANGO= 4.2: dj42 5.0: dj50 5.1: dj51 + 5.2: dj52 DRF= 3.14: drf314 3.15: drf315 @@ -33,6 +35,7 @@ deps= dj42: Django>=4.2,<4.3 dj50: Django>=5.0,<5.1 dj51: Django>=5.1,<5.2 + dj52: Django>=5.2,<5.3 drf314: djangorestframework>=3.14,<3.15 drf315: djangorestframework>=3.15,<3.16 pyjwt171: pyjwt>=1.7.1,<1.8 From d63d86ddb7158d2f7fbeb1de62384a1eea96473d Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Wed, 11 Jun 2025 10:29:19 +0200 Subject: [PATCH 147/171] Update RTD config This should fix #877. --- .readthedocs.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 07c55dbde..843783c61 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -2,15 +2,17 @@ version: 2 # Set the version of Python and other tools you might need build: - os: ubuntu-20.04 + os: ubuntu-22.04 tools: python: "3.12" python: install: # Install dependencies from setup.py . - - method: setuptools + - method: pip path: . + extra_requirements: + - dev # Build documentation in the docs/ directory with Sphinx sphinx: From b3584176296441dc7647a7b76697f5d264a91d0c Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Wed, 11 Jun 2025 10:31:29 +0200 Subject: [PATCH 148/171] Remove pin for Sphinx. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index eca37ad62..7f454aea7 100755 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ "pre-commit", ], "doc": [ - "Sphinx>=1.6.5,<2", + "Sphinx", "sphinx_rtd_theme>=0.1.9", ], "dev": [ From 6bc2a145358d851c4ad4ee4819a06b61b567af5a Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Wed, 11 Jun 2025 10:36:10 +0200 Subject: [PATCH 149/171] Fix rST syntax. --- docs/settings.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index be966ac5b..03219f7c1 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -157,7 +157,7 @@ tokens. When set to ``None``, this field is excluded from tokens and is not validated. ``JWK_URL`` ----------- +----------- The JWK_URL is used to dynamically resolve the public keys needed to verify the signing of tokens. When using Auth0 for example you might set this to @@ -274,7 +274,7 @@ The claim name that is used to store the expiration time of a sliding token's refresh period. More about this in the "Sliding tokens" section below. ``CHECK_REVOKE_TOKEN`` --------------------- +---------------------- If this field is set to ``True``, the system will verify whether the token has been revoked or not by comparing the md5 hash of the user's current @@ -282,7 +282,7 @@ password with the value stored in the REVOKE_TOKEN_CLAIM field within the payload of the JWT token. ``REVOKE_TOKEN_CLAIM`` --------------------- +---------------------- The claim name that is used to store a user hash password. If the value of this CHECK_REVOKE_TOKEN field is ``True``, this field will be From e58e16b574ecac3a08190045c8a7f8c99c72d995 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Wed, 11 Jun 2025 10:36:39 +0200 Subject: [PATCH 150/171] For rST fixes. --- docs/stateless_user_authentication.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/stateless_user_authentication.rst b/docs/stateless_user_authentication.rst index dcb1aea83..c02604ba1 100644 --- a/docs/stateless_user_authentication.rst +++ b/docs/stateless_user_authentication.rst @@ -1,10 +1,10 @@ .. _stateless_user_authentication: Stateless User Authentication -===================== +============================= JWTStatelessUserAuthentication backend ----------------------------------- +-------------------------------------- The ``JWTStatelessUserAuthentication`` backend's ``authenticate`` method does not perform a database lookup to obtain a user instance. Instead, it returns a From 890e13691f919e4088f47000c853ffd0bcb64c76 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Wed, 11 Jun 2025 10:38:33 +0200 Subject: [PATCH 151/171] Fix ref. --- docs/drf_yasg_integration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/drf_yasg_integration.rst b/docs/drf_yasg_integration.rst index 6d47c6208..e5c7700ad 100644 --- a/docs/drf_yasg_integration.rst +++ b/docs/drf_yasg_integration.rst @@ -1,4 +1,4 @@ -.. _drf_yasg_integration +.. _drf_yasg_integration: ``drf-yasg`` Integration ------------------------ From d77ae207a28099d3e15e05a0c1e40b57b32a2882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Mon, 21 Jul 2025 18:41:36 +0200 Subject: [PATCH 152/171] fix: always stringify user_id claim (#887) * fix: always stringify user_id claim * loose PyJWT requirement --- rest_framework_simplejwt/models.py | 4 ++-- rest_framework_simplejwt/tokens.py | 3 +-- setup.py | 2 +- tests/test_authentication.py | 11 +++++++++++ tests/test_models.py | 18 +++++++++--------- tests/test_tokens.py | 7 +++++-- tox.ini | 2 +- 7 files changed, 30 insertions(+), 17 deletions(-) diff --git a/rest_framework_simplejwt/models.py b/rest_framework_simplejwt/models.py index a0e2c8345..859dfd3ae 100644 --- a/rest_framework_simplejwt/models.py +++ b/rest_framework_simplejwt/models.py @@ -34,11 +34,11 @@ def __str__(self) -> str: return f"TokenUser {self.id}" @cached_property - def id(self) -> Union[int, str]: + def id(self) -> str: return self.token[api_settings.USER_ID_CLAIM] @cached_property - def pk(self) -> Union[int, str]: + def pk(self) -> str: return self.id @cached_property diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index d97b3de96..3d9e363b4 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -225,8 +225,7 @@ def for_user(cls: type[T], user: AuthUser) -> T: ) user_id = getattr(user, api_settings.USER_ID_FIELD) - if not isinstance(user_id, int): - user_id = str(user_id) + user_id = str(user_id) token = cls() token[api_settings.USER_ID_CLAIM] = user_id diff --git a/setup.py b/setup.py index 7f454aea7..81982ba42 100755 --- a/setup.py +++ b/setup.py @@ -59,7 +59,7 @@ install_requires=[ "django>=4.2", "djangorestframework>=3.14", - "pyjwt>=1.7.1,<2.10.0", + "pyjwt>=1.7.1", ], python_requires=">=3.9", extras_require=extras_require, diff --git a/tests/test_authentication.py b/tests/test_authentication.py index cb6c3dc3f..b17a12caa 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -225,6 +225,17 @@ def test_get_user_with_check_revoke_token(self): # Otherwise, should return correct user self.assertEqual(self.backend.get_user(payload).id, u.id) + def test_get_user_with_str_user_id_claim(self): + """ + Verify that even though the user id is an int, it can be verified + and retrieved if the user id claim value is a string + """ + + user = User.objects.create_user(username="testuser") + payload = {api_settings.USER_ID_CLAIM: str(user.id)} + auth_user = self.backend.get_user(payload) + self.assertEqual(auth_user.id, user.id) + class TestJWTStatelessUserAuthentication(TestCase): def setUp(self): diff --git a/tests/test_models.py b/tests/test_models.py index c757eea75..719470639 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -12,7 +12,7 @@ class TestTokenUser(TestCase): def setUp(self): self.token = AuthToken() - self.token[api_settings.USER_ID_CLAIM] = 42 + self.token[api_settings.USER_ID_CLAIM] = "42" self.token["username"] = "deep-thought" self.token["some_other_stuff"] = "arstarst" @@ -40,13 +40,13 @@ def test_str(self): self.assertEqual(str(self.user), "TokenUser 42") def test_id(self): - self.assertEqual(self.user.id, 42) + self.assertEqual(self.user.id, "42") def test_pk(self): - self.assertEqual(self.user.pk, 42) + self.assertEqual(self.user.pk, "42") def test_is_staff(self): - payload = {api_settings.USER_ID_CLAIM: 42} + payload = {api_settings.USER_ID_CLAIM: "42"} user = TokenUser(payload) self.assertFalse(user.is_staff) @@ -57,7 +57,7 @@ def test_is_staff(self): self.assertTrue(user.is_staff) def test_is_superuser(self): - payload = {api_settings.USER_ID_CLAIM: 42} + payload = {api_settings.USER_ID_CLAIM: "42"} user = TokenUser(payload) self.assertFalse(user.is_superuser) @@ -68,15 +68,15 @@ def test_is_superuser(self): self.assertTrue(user.is_superuser) def test_eq(self): - user1 = TokenUser({api_settings.USER_ID_CLAIM: 1}) - user2 = TokenUser({api_settings.USER_ID_CLAIM: 2}) - user3 = TokenUser({api_settings.USER_ID_CLAIM: 1}) + user1 = TokenUser({api_settings.USER_ID_CLAIM: "1"}) + user2 = TokenUser({api_settings.USER_ID_CLAIM: "2"}) + user3 = TokenUser({api_settings.USER_ID_CLAIM: "1"}) self.assertNotEqual(user1, user2) self.assertEqual(user1, user3) def test_eq_not_implemented(self): - user1 = TokenUser({api_settings.USER_ID_CLAIM: 1}) + user1 = TokenUser({api_settings.USER_ID_CLAIM: "1"}) user2 = "user2" self.assertFalse(user1 == user2) diff --git a/tests/test_tokens.py b/tests/test_tokens.py index 455870f9c..30aeed53f 100644 --- a/tests/test_tokens.py +++ b/tests/test_tokens.py @@ -384,8 +384,7 @@ def test_for_user(self): token = MyToken.for_user(self.user) user_id = getattr(self.user, api_settings.USER_ID_FIELD) - if not isinstance(user_id, int): - user_id = str(user_id) + user_id = str(user_id) self.assertEqual(token[api_settings.USER_ID_CLAIM], user_id) @@ -405,6 +404,10 @@ def test_get_token_backend(self): self.assertEqual(token.get_token_backend(), token_backend) + def test_token_user_id_claim_should_always_be_string(self): + token = MyToken.for_user(self.user) + self.assertIsInstance(token[api_settings.USER_ID_CLAIM], str) + class TestSlidingToken(TestCase): def test_init(self): diff --git a/tox.ini b/tox.ini index 5db99c96b..2392f697d 100644 --- a/tox.ini +++ b/tox.ini @@ -39,7 +39,7 @@ deps= drf314: djangorestframework>=3.14,<3.15 drf315: djangorestframework>=3.15,<3.16 pyjwt171: pyjwt>=1.7.1,<1.8 - pyjwt2: pyjwt>=2,<2.10.0 + pyjwt2: pyjwt>=2,<3 allowlist_externals=make [testenv:docs] From a3f0e6db4763a21b59a8fc8121dc2dca523e3adb Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:41:52 -0400 Subject: [PATCH 153/171] [pre-commit.ci] pre-commit autoupdate (#892) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.9.10 → v0.12.3](https://github.com/astral-sh/ruff-pre-commit/compare/v0.9.10...v0.12.3) - [github.com/asottile/pyupgrade: v3.19.1 → v3.20.0](https://github.com/asottile/pyupgrade/compare/v3.19.1...v3.20.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 02f1e5d4b..b3f684ab6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-merge-conflict - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.10 + rev: v0.12.3 hooks: - id: ruff types_or: [ python, pyi ] @@ -48,7 +48,7 @@ repos: - id: detect-private-key exclude: ^tests/ - repo: https://github.com/asottile/pyupgrade - rev: 'v3.19.1' + rev: 'v3.20.0' hooks: - id: pyupgrade args: ['--py39-plus', '--keep-mock'] From a2d0a0201b6123536ecf76cd4d0ec7389317d0a7 Mon Sep 17 00:00:00 2001 From: Andrew Chen Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:46:58 -0400 Subject: [PATCH 154/171] Update CHANGELOG.md for 5.5.1 (#891) --- CHANGELOG.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7c124d23..2d1d8618a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,35 @@ +## 5.5.1 + +Missing Migration for rest_framework_simplejwt.token_blacklist app. A previously missing migration (0013_blacklist) has now been added. This issue arose because the migration file was mistakenly not generated earlier. This migration was never part of an official release, but users following the latest master branch may have encountered it. + +**Notes for Users** +If you previously ran makemigrations in production and have a 0013_blacklist migration in your django_migrations table, follow these steps before upgrading: + +1. Roll back to the last known migration: +```bash +python manage.py migrate rest_framework_simplejwt.token_blacklist 0012 +``` +2. Upgrade djangorestframework-simplejwt to the latest version. +3. Apply the migrations correctly: +```bash +python manage.py migrate +``` +**Important**: If other migrations depend on 0013_blacklist, be cautious when removing it. You may need to adjust or regenerate dependent migrations to ensure database integrity. + +* fix: add missing migration for token_blacklist app by @juanbailon in https://github.com/jazzband/djangorestframework-simplejwt/pull/894 +* :globe_with_meridians: Fix typos and improve clarity in es_AR translations by @fabianfalon in https://github.com/jazzband/djangorestframework-simplejwt/pull/876 +* docs: Add warning in docs for `for_user` usage by @vgrozdanic in https://github.com/jazzband/djangorestframework-simplejwt/pull/872 +* feat: log warning if token is being created for inactive user by @vgrozdanic in https://github.com/jazzband/djangorestframework-simplejwt/pull/873 +* ref: full tracebacks on exceptions by @vgrozdanic in https://github.com/jazzband/djangorestframework-simplejwt/pull/870 +* #858 New i18n messages by @Cloves23 in https://github.com/jazzband/djangorestframework-simplejwt/pull/879 +* Repair the type annotations in the TokenViewBase class. by @triplepoint in https://github.com/jazzband/djangorestframework-simplejwt/pull/880 +* fix: Token.outstand forces users to install blacklist app by @Andrew-Chen-Wang in https://github.com/jazzband/djangorestframework-simplejwt/pull/884 +* fix: PytestConfigWarning Unknown config option: python_paths by @vgrozdanic in https://github.com/jazzband/djangorestframework-simplejwt/pull/886 +* fix: Do not copy `iat` claim from refresh token by @vgrozdanic in https://github.com/jazzband/djangorestframework-simplejwt/pull/888 +* fix: add missing migration for token_blacklist app by @juanbailon in https://github.com/jazzband/djangorestframework-simplejwt/pull/894 +* Update Persian translations (fa, fa_IR) for Django application by @mahdirahimi1999 in https://github.com/jazzband/djangorestframework-simplejwt/pull/897 +* fix: always stringify user_id claim ([#887](https://github.com/jazzband/djangorestframework-simplejwt/pull/897)) + ## 5.5.0 * Cap PyJWT version to <2.10.0 to avoid incompatibility with subject claim type requirement by @grayver in https://github.com/jazzband/djangorestframework-simplejwt/pull/843 * Add specific "token expired" exceptions by @vainu-arto in https://github.com/jazzband/djangorestframework-simplejwt/pull/830 From be0301eb11c1550d0f7254289f713d6a34c61ac6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 21 Jul 2025 12:48:59 -0400 Subject: [PATCH 155/171] Update locale files (#878) Co-authored-by: Andrew-Chen-Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- .../locale/ar/LC_MESSAGES/django.po | 10 +++++----- .../locale/cs/LC_MESSAGES/django.po | 10 +++++----- .../locale/de/LC_MESSAGES/django.po | 10 +++++----- .../locale/es/LC_MESSAGES/django.po | 10 +++++----- .../locale/es_AR/LC_MESSAGES/django.po | 10 +++++----- .../locale/es_CL/LC_MESSAGES/django.po | 10 +++++----- .../locale/fa/LC_MESSAGES/django.mo | Bin 3823 -> 3800 bytes .../locale/fa/LC_MESSAGES/django.po | 2 +- .../locale/fa_IR/LC_MESSAGES/django.mo | Bin 3722 -> 3707 bytes .../locale/fa_IR/LC_MESSAGES/django.po | 2 +- .../locale/fr/LC_MESSAGES/django.po | 10 +++++----- .../locale/he_IL/LC_MESSAGES/django.po | 10 +++++----- .../locale/id_ID/LC_MESSAGES/django.po | 10 +++++----- .../locale/it_IT/LC_MESSAGES/django.po | 10 +++++----- .../locale/ko_KR/LC_MESSAGES/django.po | 10 +++++----- .../locale/nl_NL/LC_MESSAGES/django.po | 10 +++++----- .../locale/pl_PL/LC_MESSAGES/django.po | 10 +++++----- .../locale/pt_BR/LC_MESSAGES/django.mo | Bin 3226 -> 3213 bytes .../locale/pt_BR/LC_MESSAGES/django.po | 10 +++++----- .../locale/ro/LC_MESSAGES/django.po | 10 +++++----- .../locale/ru_RU/LC_MESSAGES/django.po | 10 +++++----- .../locale/sl/LC_MESSAGES/django.po | 10 +++++----- .../locale/sv/LC_MESSAGES/django.po | 10 +++++----- .../locale/tr/LC_MESSAGES/django.po | 10 +++++----- .../locale/uk_UA/LC_MESSAGES/django.po | 10 +++++----- .../locale/zh_Hans/LC_MESSAGES/django.po | 10 +++++----- 26 files changed, 107 insertions(+), 107 deletions(-) diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po index ee3d7817c..1c83868c1 100644 --- a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po @@ -21,19 +21,19 @@ msgstr "يجب أن يحتوي رأس التفويض على قيمتين مفص msgid "Given token not valid for any token type" msgstr "تأشيرة المرور غير صالحة لأي نوع من أنواع التأشيرات" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "لا تحتوي تأشيرة المرور على هوية مستخدم يمكن التعرف عليها" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "لم يتم العثور على المستخدم" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "الحساب غير مفعل" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -81,7 +81,7 @@ msgstr "لم يتم العثور على حساب نشط للبيانات الم msgid "No active account found for the given token." msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "التأشيرة مدرجة في القائمة السوداء" diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index ff8d0632a..be0db1b33 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -19,19 +19,19 @@ msgstr "Autorizační hlavička musí obsahovat dvě hodnoty oddělené mezerou" msgid "Given token not valid for any token type" msgstr "Daný token není validní pro žádný typ tokenu" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Token neobsahoval žádnou rozpoznatelnou identifikaci uživatele" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Uživatel nenalezen" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Uživatel není aktivní" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -78,7 +78,7 @@ msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" msgid "No active account found for the given token." msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po index a3a638088..6b614adab 100644 --- a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po @@ -21,19 +21,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Der Token ist für keinen Tokentyp gültig" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Token enthält keine erkennbare Benutzeridentifikation" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Benutzer nicht gefunden" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Inaktiver Benutzer" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -80,7 +80,7 @@ msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" msgid "No active account found for the given token." msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 325d0327b..4bb9e0bea 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -21,19 +21,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "El token dado no es valido para ningun tipo de token" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "El token no contenía identificación de usuario reconocible" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "El usuario está inactivo" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -80,7 +80,7 @@ msgstr "La combinación de credenciales no tiene una cuenta activa" msgid "No active account found for the given token." msgstr "La combinación de credenciales no tiene una cuenta activa" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index a6a7bbdb9..aeca82b76 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -26,19 +26,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "El token proporcionado no es válido para ningún tipo." -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "El token no contiene ninguna identificación de usuario válida." -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "No se encontró el usuario." -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "El usuario está inactivo" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "La contraseña del usuario ha sido cambiada." @@ -85,7 +85,7 @@ msgstr "No se encontró una cuenta activa con las credenciales proporcionadas." msgid "No active account found for the given token." msgstr "No se encontró una cuenta activa para el token proporcionado" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "El token ha sido revocado" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index cf195f7e8..3c812f6a7 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -21,19 +21,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "El token provisto no es válido para ningún tipo de token" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "El token no contiene identificación de usuario reconocible" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "El usuario está inactivo" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -82,7 +82,7 @@ msgid "No active account found for the given token." msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.mo index 8d996fbafc49435b6afe5aa8ca66146f7663fcaa..145b393f9f05e9e272f9c96298fd43d1fda8fff3 100644 GIT binary patch delta 248 zcmXZWzpFt30LAg+F1Rj>t|CN!Wl(ovkd=C6k_=){cVIW@Ew3!EmohNRA0Vaf-@)va zw^|we0q;wuPv

+*0S%Ve0#8O8N^*UCf!1jWbN+5@)!_Di%Xh0SB1CId*V^dAy^8 zwk5@|g-IOZv;V|8?l6m2OTE`nAS^W~N?1V`N4UZaKJYncN2ESF7{$fgEyl?n@>NIg Z!}#^DFTt|cHfz51Pv~S!TyJcB8~-F>AXNYW delta 268 zcmXZWF-rn*9LDkAx#W3wf{26SS%D(KDK0jII4U6og){^Xz6S@zp=eMLLG<215Yi&S zg)hKSaQ`3GBJQp(g5T2V!}Bc9qwKBy+0vdXBJ!(?)G-|riD3s*IKnp0u!vbh#K8t8 zaDWf^j%nOs0c}$xgLjz37XI~Pyuk%t;@*_U|DkhBq(o819CopZA9#UA_&Dg`6S;~} zd^V BEfoL& diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po index eaf3ed298..589a12da1 100644 --- a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po @@ -77,7 +77,7 @@ msgstr "هیچ اکانت فعالی برای اطلاعات داده شده ی msgid "No active account found for the given token." msgstr "هیچ اکانت فعالی برای این توکن یافت نشد" -#: serializers.py:178 tokens.py:281 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "توکن در لیست سیاه قرار گرفته است" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.mo index ff90df9e84dea63b3e18d2f3b4fdb600ebb89afe..e76a81308b4f256cb359009765497b43ccf0d632 100644 GIT binary patch delta 279 zcmXBOF-rmg7{>9(TSV__NEDLF3yjl2Q$z@AatRlQh=W>0Z1AMOL0lx7b7{E1t+k{j zxuwtG;No&L=m&AIzcu}MA0FQK9UZO@zWR};hNPF6bd5_)VkIseVI2q9!78rs1e2ze z#&f(v7qd9Q63#J&8{GC%mgHa=Pw@ti@!695cj%Mgf?$RPjP6J+tfGx$+%EdYTU=lQ zi@X2UaG%*lepD~08?Vt|89R%Z&hXK(+xIQ+!S>&*w0~*N4eu_} delta 295 zcmXZWF-rn*7{~GFgowNQTSDZZR~iHtL|LGlTM*?EgebH`IEl~{EfKdRNa%3RtriG% zoCs~bfZG4+pkwc$p}wb0AD-v=Jv`5k)7p5uF}yPo>6jvAoZ>p>Es;$u;Vss&fHOSA zq%D%d6FkQnZsQOSaDvgkQj6R!y41&*!)x5aCnc46@PkH?#uWF^iHlre3A5P8=-?M# z;5V+}(aOT=zYXL^@xs$sciGtY+vZNVWF?GM-P5o7UH2xBS@-VV^)q(b|5c`6v_CC9 X7(Fl#N6pYumoX*d7s^0C>p=bh;d3|e diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index 55329e0c8..e42d27d46 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -72,7 +72,7 @@ msgstr "هیچ اکانت فعالی برای اطلاعات داده شده ی msgid "No active account found for the given token." msgstr "هیچ اکانت فعالی برای توکن داده شده یافت نشد" -#: serializers.py:178 tokens.py:281 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index 540dff517..78536c27b 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -20,20 +20,20 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Le type de jeton fourni n'est pas valide" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "" "Le jeton ne contient aucune information permettant d'identifier l'utilisateur" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "L'utilisateur n'a pas été trouvé" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "L'utilisateur est désactivé" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -80,7 +80,7 @@ msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" msgid "No active account found for the given token." msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po index bb934e523..48c3f7d10 100644 --- a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po @@ -24,19 +24,19 @@ msgstr "Authorization Header חייבת להכיל שני ערכים מופרד msgid "Given token not valid for any token type" msgstr "המזהה הנתון אינו תקף עבור אף סיווג" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "המזהה לא הכיל זיהוי משתמש שניתן לזהות" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "משתמש לא נמצא" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "המשתמש אינו פעיל" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -83,7 +83,7 @@ msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" msgid "No active account found for the given token." msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "המזהה ברשימה השחורה." diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index 48cc7d949..f4ac200d5 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -24,19 +24,19 @@ msgstr "Header otorisasi harus berisi dua nilai yang dipisahkan spasi" msgid "Given token not valid for any token type" msgstr "Token yang diberikan tidak valid untuk semua jenis token" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Token tidak mengandung identifikasi pengguna yang dapat dikenali" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Pengguna tidak ditemukan" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Pengguna tidak aktif" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -84,7 +84,7 @@ msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" msgid "No active account found for the given token." msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index 05f68fffb..9389d8b06 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -24,19 +24,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Il token dato non è valido per qualsiasi tipo di token" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Il token non conteneva nessuna informazione riconoscibile dell'utente" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Utente non trovato" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Utente non attivo" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -83,7 +83,7 @@ msgstr "Nessun account attivo trovato con queste credenziali" msgid "No active account found for the given token." msgstr "Nessun account attivo trovato con queste credenziali" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index 4cdb4061d..350bd3512 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -20,19 +20,19 @@ msgstr "인증 헤더에는 공백으로 구분 된 두 개의 값이 포함되 msgid "Given token not valid for any token type" msgstr "이 토큰은 모든 타입의 토큰에 대해 유효하지 않습니다" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "토큰에 사용자 식별자가 포함되어 있지 않습니다" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "찾을 수 없는 사용자입니다" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "비활성화된 사용자입니다" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "사용자의 비밀번호가 바뀌었습니다." @@ -81,7 +81,7 @@ msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 msgid "No active account found for the given token." msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "블랙리스트에 추가된 토큰입니다" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index c52ea9f42..b87b5da79 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -20,19 +20,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Het token is voor geen enkel token-type geldig" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Token bevat geen herkenbare gebruikersidentificatie" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Gebruiker niet gevonden" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Gebruiker is inactief" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -79,7 +79,7 @@ msgstr "Geen actief account gevonden voor deze gegevens" msgid "No active account found for the given token." msgstr "Geen actief account gevonden voor deze gegevens" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index 8437ce90f..0ec26bc85 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -19,19 +19,19 @@ msgstr "Nagłówek autoryzacji musi zawierać dwie wartości rodzielone spacjami msgid "Given token not valid for any token type" msgstr "Podany token jest błędny dla każdego typu tokena" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Token nie zawierał rozpoznawalnej identyfikacji użytkownika" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Użytkownik nie znaleziony" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Użytkownik jest nieaktywny" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -78,7 +78,7 @@ msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" msgid "No active account found for the given token." msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.mo index 1ac0f47e1d78a35417672e49a6c30f24f9b05fde..e7d0c23f302ba18b8b7e3001d8ae434425461f0e 100644 GIT binary patch delta 127 zcmbOw*(4Pz`H0|P@KHv@wRkWK*7(m=WtNUH#8lW(M+mfiwq@p19eQiG!2ZU!f#FJ2g)swYcQ)!pULW@{<#|MK-r^ Hb20(|buSb* diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index 8ee8f597a..a7aabb13d 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -21,19 +21,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "O token informado não é válido para qualquer tipo de token" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "O token não continha nenhuma identificação reconhecível do usuário" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Usuário não encontrado" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Usuário está inativo" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "A senha do usuário foi alterada." @@ -75,7 +75,7 @@ msgstr "Usuário e/ou senha incorreto(s)" msgid "No active account found for the given token." msgstr "Nenhuma conta ativa encontrada para o token fornecido." -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po index 3cd280dfd..1dcfc1235 100644 --- a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -22,19 +22,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Tokenul dat nu este valid pentru niciun tip de token" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Tokenul nu conține date de identificare a utilizatorului" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Utilizatorul nu a fost găsit" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Utilizatorul este inactiv" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -83,7 +83,7 @@ msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" msgid "No active account found for the given token." msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Tokenul este în listă de tokenuri blocate" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index 1ffe05aea..9a1c55723 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -25,19 +25,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Данный токен недействителен для любого типа токена" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Токен не содержит идентификатор пользователя" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Пользователь не найден" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Пользователь неактивен" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -84,7 +84,7 @@ msgstr "Не найдено активной учетной записи с ук msgid "No active account found for the given token." msgstr "Не найдено активной учетной записи с указанными данными" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po index 46cc09cef..91d7fa88a 100644 --- a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po @@ -24,19 +24,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Podan žeton ni veljaven za nobeno vrsto žetona" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Žeton ni vseboval prepoznavne identifikacije uporabnika" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Uporabnik ni najden" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Uporabnik je neaktiven" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -84,7 +84,7 @@ msgstr "Aktiven račun s podanimi poverilnicami ni najden" msgid "No active account found for the given token." msgstr "Aktiven račun s podanimi poverilnicami ni najden" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Žeton je na črnem seznamu" diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po index f6cb0e0a7..3928eeed4 100644 --- a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -20,19 +20,19 @@ msgstr "Auktoriseringshuvudet måste innehålla två mellanslagsavgränsade vär msgid "Given token not valid for any token type" msgstr "Givet token är inte giltigt för någon tokentyp" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Token innehöll ingen identifiering av användaren" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Användaren hittades inte" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Användaren är inaktiv" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -79,7 +79,7 @@ msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" msgid "No active account found for the given token." msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token är svartlistad" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 5464e09a9..82604445c 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -22,19 +22,19 @@ msgstr "" msgid "Given token not valid for any token type" msgstr "Verilen token hiçbir token tipi için geçerli değil" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Token tanınabilir bir kullanıcı kimliği içermiyor" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Kullanıcı bulunamadı" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Kullanıcı etkin değil" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -81,7 +81,7 @@ msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" msgid "No active account found for the given token." msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Token kara listeye alınmış" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index cc94accd2..92b53187b 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -23,19 +23,19 @@ msgstr "Авторизаційний заголовок має містити д msgid "Given token not valid for any token type" msgstr "Наданий токен не відповідає жодному типу ключа" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "Наданий токен не мітить жодної ідентифікаційної інформації" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "Користувач не знайдений" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "Користувач неактивний" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -82,7 +82,7 @@ msgstr "Не знайдено жодного облікового запису msgid "No active account found for the given token." msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index b6fb095ed..cf4de1ada 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -23,19 +23,19 @@ msgstr "授权头必须包含两个用空格分隔的值" msgid "Given token not valid for any token type" msgstr "此令牌对任何类型的令牌无效" -#: authentication.py:127 authentication.py:162 +#: authentication.py:128 authentication.py:166 msgid "Token contained no recognizable user identification" msgstr "令牌未包含用户标识符" -#: authentication.py:132 +#: authentication.py:135 msgid "User not found" msgstr "未找到该用户" -#: authentication.py:135 +#: authentication.py:139 msgid "User is inactive" msgstr "该用户已禁用" -#: authentication.py:142 +#: authentication.py:146 msgid "The user's password has been changed." msgstr "" @@ -82,7 +82,7 @@ msgstr "找不到指定凭据对应的有效用户" msgid "No active account found for the given token." msgstr "找不到指定凭据对应的有效用户" -#: serializers.py:178 tokens.py:299 +#: serializers.py:178 tokens.py:280 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" From d520fd759b2751bf07f10dcb2dca33bc5611141e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 22 Jul 2025 18:11:10 -0400 Subject: [PATCH 156/171] [pre-commit.ci] pre-commit autoupdate (#921) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.3 → v0.12.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.3...v0.12.4) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b3f684ab6..6cda928b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-merge-conflict - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.3 + rev: v0.12.4 hooks: - id: ruff types_or: [ python, pyi ] From 6c45510dc8c0caee37a98f3df6392ab3e3ed8ad1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 18:38:15 -0400 Subject: [PATCH 157/171] Bump actions/checkout from 4 to 5 (#926) Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/i18n.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index 14c0c7a28..3712f67e0 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout Repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Python uses: actions/setup-python@v5 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5fb877885..f115c638d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3d5049fa7..a8a282a81 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,7 +25,7 @@ jobs: django-version: '5.1' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 From 930cf85c83333451393cf78b740d576fe8a1dfba Mon Sep 17 00:00:00 2001 From: Yuekui Date: Sun, 17 Aug 2025 21:47:28 -0700 Subject: [PATCH 158/171] fix: Avoid DoesNotExist exception in TokenRefreshSerializer (#861) * Check user before passing it to the rule * Use `Optional` in the type annotation for the default user authentication rule since the user can be `None` --- rest_framework_simplejwt/authentication.py | 2 +- rest_framework_simplejwt/serializers.py | 11 ++++++----- tests/test_serializers.py | 5 ++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index 239d242a2..060ddcc33 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -171,7 +171,7 @@ def get_user(self, validated_token: Token) -> AuthUser: JWTTokenUserAuthentication = JWTStatelessUserAuthentication -def default_user_authentication_rule(user: AuthUser) -> bool: +def default_user_authentication_rule(user: Optional[AuthUser]) -> bool: # Prior to Django 1.10, inactive users could be authenticated with the # default `ModelBackend`. As of Django 1.10, the `ModelBackend` # prevents inactive users from authenticating. App designers can still diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index 45c5a771c..7fa717c67 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -112,12 +112,13 @@ def validate(self, attrs: dict[str, Any]) -> dict[str, str]: refresh = self.token_class(attrs["refresh"]) user_id = refresh.payload.get(api_settings.USER_ID_CLAIM, None) - if user_id and ( - user := get_user_model().objects.get( - **{api_settings.USER_ID_FIELD: user_id} + if user_id: + user = ( + get_user_model() + .objects.filter(**{api_settings.USER_ID_FIELD: user_id}) + .first() ) - ): - if not api_settings.USER_AUTHENTICATION_RULE(user): + if not user or not api_settings.USER_AUTHENTICATION_RULE(user): raise AuthenticationFailed( self.error_messages["no_active_account"], "no_active_account", diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 7ce35c085..b3cdf4c72 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -4,7 +4,6 @@ from django.conf import settings from django.contrib.auth import get_user_model -from django.core import exceptions as django_exceptions from django.test import TestCase, override_settings from rest_framework import exceptions as drf_exceptions @@ -286,10 +285,10 @@ def test_it_should_raise_error_for_deleted_users(self): s = TokenRefreshSerializer(data={"refresh": str(refresh)}) - with self.assertRaises(django_exceptions.ObjectDoesNotExist) as e: + with self.assertRaises(drf_exceptions.AuthenticationFailed) as e: s.is_valid() - self.assertIn("does not exist", str(e.exception)) + self.assertIn("No active account", str(e.exception)) def test_it_should_raise_error_for_inactive_users(self): refresh = RefreshToken.for_user(self.user) From 4d6e4fd74376dd8db8658088d1d5b5d3823bb6ef Mon Sep 17 00:00:00 2001 From: Mahdi Rahimi <31624047+mahdirahimi1999@users.noreply.github.com> Date: Thu, 21 Aug 2025 18:30:49 +0330 Subject: [PATCH 159/171] feat(auth): Revoke refresh token on password change (#928) * feat(auth): Revoke refresh token on password change * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * refactor(serializers): Correct validation order in TokenRefreshSerializer * refactor: centralize password changed error messages in error dictionaries * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * feat(serializers): Add full user validation to sliding token refresh Implements the same user validation logic (active status, password change) in to ensure consistent behavior with the standard . * refactor: Inline password hash comparison in serializers Simplifies the conditional check by removing temporary variables for the token hash and user password hash. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * BREAKING: return 401 AuthenticationFailed instead of 404 DoesNotExist for missing users --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- CHANGELOG.md | 10 ++ rest_framework_simplejwt/authentication.py | 7 +- rest_framework_simplejwt/serializers.py | 86 ++++++++++++-- tests/test_serializers.py | 124 ++++++++++++++++++++- 4 files changed, 215 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d1d8618a..8839c4889 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [Unreleased] + +### Changed +- **BREAKING:** In `serializers.py`, when a user linked to a token is missing or deleted, the code now raises `AuthenticationFailed("no_active_account")` instead of allowing `DoesNotExist` to propagate. + - Response changed from **404 Not Found** → **401 Unauthorized**. + - Improves security by not leaking whether a user/token exists. + - Follows RFC 7235, where authentication failures should return 401. + - Clearer for clients: signals an auth issue instead of suggesting the endpoint is missing. + + ## 5.5.1 Missing Migration for rest_framework_simplejwt.token_blacklist app. A previously missing migration (0013_blacklist) has now been added. This issue arose because the migration file was mistakenly not generated earlier. This migration was never part of an official release, but users following the latest master branch may have encountered it. diff --git a/rest_framework_simplejwt/authentication.py b/rest_framework_simplejwt/authentication.py index 060ddcc33..706196600 100644 --- a/rest_framework_simplejwt/authentication.py +++ b/rest_framework_simplejwt/authentication.py @@ -33,6 +33,10 @@ class JWTAuthentication(authentication.BaseAuthentication): www_authenticate_realm = "api" media_type = "application/json" + default_error_messages = { + "password_changed": _("The user's password has been changed."), + } + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.user_model = get_user_model() @@ -143,7 +147,8 @@ def get_user(self, validated_token: Token) -> AuthUser: api_settings.REVOKE_TOKEN_CLAIM ) != get_md5_hash_password(user.password): raise AuthenticationFailed( - _("The user's password has been changed."), code="password_changed" + self.default_error_messages["password_changed"], + code="password_changed", ) return user diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index 7fa717c67..04c8be43b 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -10,6 +10,7 @@ from .models import TokenUser from .settings import api_settings from .tokens import RefreshToken, SlidingToken, Token, UntypedToken +from .utils import get_md5_hash_password AuthUser = TypeVar("AuthUser", AbstractBaseUser, TokenUser) @@ -105,7 +106,8 @@ class TokenRefreshSerializer(serializers.Serializer): token_class = RefreshToken default_error_messages = { - "no_active_account": _("No active account found for the given token.") + "no_active_account": _("No active account found for the given token."), + "password_changed": _("The user's password has been changed."), } def validate(self, attrs: dict[str, Any]) -> dict[str, str]: @@ -113,19 +115,42 @@ def validate(self, attrs: dict[str, Any]) -> dict[str, str]: user_id = refresh.payload.get(api_settings.USER_ID_CLAIM, None) if user_id: - user = ( - get_user_model() - .objects.filter(**{api_settings.USER_ID_FIELD: user_id}) - .first() - ) - if not user or not api_settings.USER_AUTHENTICATION_RULE(user): + try: + user = get_user_model().objects.get( + **{api_settings.USER_ID_FIELD: user_id} + ) + except get_user_model().DoesNotExist: + # This handles the case where the user has been deleted. raise AuthenticationFailed( - self.error_messages["no_active_account"], - "no_active_account", + self.error_messages["no_active_account"], "no_active_account" ) - data = {"access": str(refresh.access_token)} + if not api_settings.USER_AUTHENTICATION_RULE(user): + raise AuthenticationFailed( + self.error_messages["no_active_account"], "no_active_account" + ) + if api_settings.CHECK_REVOKE_TOKEN: + if refresh.payload.get( + api_settings.REVOKE_TOKEN_CLAIM + ) != get_md5_hash_password(user.password): + # If the password has changed, we blacklist the token + # to prevent any further use. + if ( + "rest_framework_simplejwt.token_blacklist" + in settings.INSTALLED_APPS + ): + try: + refresh.blacklist() + except AttributeError: + pass + + raise AuthenticationFailed( + self.error_messages["password_changed"], + code="password_changed", + ) + + data = {"access": str(refresh.access_token)} if api_settings.ROTATE_REFRESH_TOKENS: if api_settings.BLACKLIST_AFTER_ROTATION: try: @@ -150,8 +175,49 @@ class TokenRefreshSlidingSerializer(serializers.Serializer): token = serializers.CharField() token_class = SlidingToken + default_error_messages = { + "no_active_account": _("No active account found for the given token."), + "password_changed": _("The user's password has been changed."), + } + def validate(self, attrs: dict[str, Any]) -> dict[str, str]: token = self.token_class(attrs["token"]) + user_id = token.payload.get(api_settings.USER_ID_CLAIM, None) + if user_id: + try: + user = get_user_model().objects.get( + **{api_settings.USER_ID_FIELD: user_id} + ) + except get_user_model().DoesNotExist: + # This handles the case where the user has been deleted. + raise AuthenticationFailed( + self.error_messages["no_active_account"], "no_active_account" + ) + + if not api_settings.USER_AUTHENTICATION_RULE(user): + raise AuthenticationFailed( + self.error_messages["no_active_account"], "no_active_account" + ) + + if api_settings.CHECK_REVOKE_TOKEN: + if token.payload.get( + api_settings.REVOKE_TOKEN_CLAIM + ) != get_md5_hash_password(user.password): + # If the password has changed, we blacklist the token + # to prevent any further use. + if ( + "rest_framework_simplejwt.token_blacklist" + in settings.INSTALLED_APPS + ): + try: + token.blacklist() + except AttributeError: + pass + + raise AuthenticationFailed( + self.error_messages["password_changed"], + code="password_changed", + ) # Check that the timestamp in the "refresh_exp" claim has not # passed diff --git a/tests/test_serializers.py b/tests/test_serializers.py index b3cdf4c72..ed8645e54 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -187,6 +187,15 @@ def test_it_should_produce_a_json_web_token_when_valid(self): class TestTokenRefreshSlidingSerializer(TestCase): + def setUp(self): + self.username = "test_user" + self.password = "test_password" + + self.user = User.objects.create_user( + username=self.username, + password=self.password, + ) + def test_it_should_not_validate_if_token_invalid(self): token = SlidingToken() del token["exp"] @@ -268,6 +277,74 @@ def test_it_should_update_token_exp_claim_if_everything_ok(self): self.assertTrue(old_exp < new_exp) + def test_it_should_raise_error_for_deleted_users(self): + token = SlidingToken.for_user(self.user) + self.user.delete() + + s = TokenRefreshSlidingSerializer(data={"token": str(token)}) + + # It should raise AuthenticationFailed instead of ObjectDoesNotExist + with self.assertRaises(drf_exceptions.AuthenticationFailed) as e: + s.is_valid() + + self.assertEqual(e.exception.get_codes(), "no_active_account") + + def test_it_should_raise_error_for_inactive_users(self): + token = SlidingToken.for_user(self.user) + self.user.is_active = False + self.user.save() + + s = TokenRefreshSlidingSerializer(data={"token": str(token)}) + + with self.assertRaises(drf_exceptions.AuthenticationFailed) as e: + s.is_valid() + + self.assertEqual(e.exception.get_codes(), "no_active_account") + + @override_api_settings( + CHECK_REVOKE_TOKEN=True, + REVOKE_TOKEN_CLAIM="hash_password", + BLACKLIST_AFTER_ROTATION=False, + ) + def test_sliding_token_should_fail_after_password_change(self): + """ + Tests that sliding token refresh fails if CHECK_REVOKE_TOKEN is True and the + user's password has changed. + """ + token = SlidingToken.for_user(self.user) + self.user.set_password("new_password") + self.user.save() + + s = TokenRefreshSlidingSerializer(data={"token": str(token)}) + + with self.assertRaises(drf_exceptions.AuthenticationFailed) as e: + s.is_valid(raise_exception=True) + + self.assertEqual(e.exception.get_codes(), "password_changed") + + @override_api_settings( + CHECK_REVOKE_TOKEN=True, + REVOKE_TOKEN_CLAIM="hash_password", + BLACKLIST_AFTER_ROTATION=True, + ) + def test_sliding_token_should_blacklist_after_password_change(self): + """ + Tests that if sliding token refresh fails due to a password change, the + offending token is blacklisted. + """ + token = SlidingToken.for_user(self.user) + self.user.set_password("new_password") + self.user.save() + + s = TokenRefreshSlidingSerializer(data={"token": str(token)}) + with self.assertRaises(drf_exceptions.AuthenticationFailed): + s.is_valid(raise_exception=True) + + # Check that the token is now in the blacklist + jti = token[api_settings.JTI_CLAIM] + self.assertTrue(OutstandingToken.objects.filter(jti=jti).exists()) + self.assertTrue(BlacklistedToken.objects.filter(token__jti=jti).exists()) + class TestTokenRefreshSerializer(TestCase): def setUp(self): @@ -285,10 +362,11 @@ def test_it_should_raise_error_for_deleted_users(self): s = TokenRefreshSerializer(data={"refresh": str(refresh)}) + # It should raise AuthenticationFailed instead of ObjectDoesNotExist with self.assertRaises(drf_exceptions.AuthenticationFailed) as e: s.is_valid() - self.assertIn("No active account", str(e.exception)) + self.assertEqual(e.exception.get_codes(), "no_active_account") def test_it_should_raise_error_for_inactive_users(self): refresh = RefreshToken.for_user(self.user) @@ -482,6 +560,50 @@ def test_blacklist_app_not_installed_should_pass(self): reload(tokens) reload(serializers) + @override_api_settings( + CHECK_REVOKE_TOKEN=True, + REVOKE_TOKEN_CLAIM="hash_password", + BLACKLIST_AFTER_ROTATION=False, + ) + def test_refresh_token_should_fail_after_password_change(self): + """ + Tests that token refresh fails if CHECK_REVOKE_TOKEN is True and the + user's password has changed. + """ + refresh = RefreshToken.for_user(self.user) + self.user.set_password("new_password") + self.user.save() + + s = TokenRefreshSerializer(data={"refresh": str(refresh)}) + + with self.assertRaises(drf_exceptions.AuthenticationFailed) as e: + s.is_valid(raise_exception=True) + + self.assertEqual(e.exception.get_codes(), "password_changed") + + @override_api_settings( + CHECK_REVOKE_TOKEN=True, + REVOKE_TOKEN_CLAIM="hash_password", + BLACKLIST_AFTER_ROTATION=True, + ) + def test_refresh_token_should_blacklist_after_password_change(self): + """ + Tests that if token refresh fails due to a password change, the + offending refresh token is blacklisted. + """ + refresh = RefreshToken.for_user(self.user) + self.user.set_password("new_password") + self.user.save() + + s = TokenRefreshSerializer(data={"refresh": str(refresh)}) + with self.assertRaises(drf_exceptions.AuthenticationFailed): + s.is_valid(raise_exception=True) + + # Check that the token is now in the blacklist + jti = refresh[api_settings.JTI_CLAIM] + self.assertTrue(OutstandingToken.objects.filter(jti=jti).exists()) + self.assertTrue(BlacklistedToken.objects.filter(token__jti=jti).exists()) + class TestTokenVerifySerializer(TestCase): def test_it_should_raise_token_error_if_token_invalid(self): From 309b6b605412b5b654e25726e148d3a5cb1bd07a Mon Sep 17 00:00:00 2001 From: q0w <43147888+q0w@users.noreply.github.com> Date: Tue, 26 Aug 2025 11:08:03 +0300 Subject: [PATCH 160/171] Fix typo in changelog (#930) * Fix typo in changelog * Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8839c4889..3504ffd2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,7 +38,7 @@ python manage.py migrate * fix: Do not copy `iat` claim from refresh token by @vgrozdanic in https://github.com/jazzband/djangorestframework-simplejwt/pull/888 * fix: add missing migration for token_blacklist app by @juanbailon in https://github.com/jazzband/djangorestframework-simplejwt/pull/894 * Update Persian translations (fa, fa_IR) for Django application by @mahdirahimi1999 in https://github.com/jazzband/djangorestframework-simplejwt/pull/897 -* fix: always stringify user_id claim ([#887](https://github.com/jazzband/djangorestframework-simplejwt/pull/897)) +* fix: always stringify user_id claim in https://github.com/jazzband/djangorestframework-simplejwt/pull/887 ## 5.5.0 * Cap PyJWT version to <2.10.0 to avoid incompatibility with subject claim type requirement by @grayver in https://github.com/jazzband/djangorestframework-simplejwt/pull/843 From cf740f67c7122a8c1c49df3fee8c2f5a63d1e053 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 04:12:54 -0400 Subject: [PATCH 161/171] [pre-commit.ci] pre-commit autoupdate (#922) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/pre-commit-hooks: v5.0.0 → v6.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v5.0.0...v6.0.0) - [github.com/astral-sh/ruff-pre-commit: v0.12.4 → v0.12.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.4...v0.12.10) - [github.com/pre-commit/pre-commit-hooks: v5.0.0 → v6.0.0](https://github.com/pre-commit/pre-commit-hooks/compare/v5.0.0...v6.0.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6cda928b4..ad394e279 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,10 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v5.0.0' + rev: 'v6.0.0' hooks: - id: check-merge-conflict - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.4 + rev: v0.12.10 hooks: - id: ruff types_or: [ python, pyi ] @@ -18,7 +18,7 @@ repos: hooks: - id: yesqa - repo: https://github.com/pre-commit/pre-commit-hooks - rev: 'v5.0.0' + rev: 'v6.0.0' hooks: - id: end-of-file-fixer exclude: >- From da5d4f27254434a574d62815ccf4d4e9a4af1f0f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 26 Aug 2025 04:13:37 -0400 Subject: [PATCH 162/171] Update locale files (#929) Co-authored-by: Andrew-Chen-Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- .../locale/ar/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/cs/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/de/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/es/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/es_AR/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/es_CL/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/fa/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/fa_IR/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/fr/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/he_IL/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/id_ID/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/it_IT/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/ko_KR/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/nl_NL/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/pl_PL/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/pt_BR/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/ro/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/ru_RU/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/sl/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/sv/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/tr/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/uk_UA/LC_MESSAGES/django.po | 24 +++++++++---------- .../locale/zh_Hans/LC_MESSAGES/django.po | 24 +++++++++---------- 23 files changed, 276 insertions(+), 276 deletions(-) diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po index 1c83868c1..5ba7de8fd 100644 --- a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po @@ -13,30 +13,30 @@ msgstr "" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "يجب أن يحتوي رأس التفويض على قيمتين مفصولتين بمسافات" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "تأشيرة المرور غير صالحة لأي نوع من أنواع التأشيرات" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "لا تحتوي تأشيرة المرور على هوية مستخدم يمكن التعرف عليها" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "لم يتم العثور على المستخدم" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "الحساب غير مفعل" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الخوارزمية غير معروف '{}'" @@ -71,17 +71,17 @@ msgstr "تأشيرة المرور غير صالحة أو منتهية الصلا msgid "Token is invalid or expired" msgstr "تأشيرة المرور غير صالحة أو منتهية الصلاحية" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "التأشيرة مدرجة في القائمة السوداء" diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index be0db1b33..8a81ce782 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -11,30 +11,30 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "Autorizační hlavička musí obsahovat dvě hodnoty oddělené mezerou" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Daný token není validní pro žádný typ tokenu" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Token neobsahoval žádnou rozpoznatelnou identifikaci uživatele" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Uživatel nenalezen" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Uživatel není aktivní" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Nerozpoznaný typ algoritmu '{}'" @@ -68,17 +68,17 @@ msgstr "Token není validní nebo vypršela jeho platnost" msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token je na černé listině" diff --git a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po index 6b614adab..991214217 100644 --- a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po @@ -12,31 +12,31 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "Der Authorizationheader muss zwei leerzeichen-getrennte Werte enthalten" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Der Token ist für keinen Tokentyp gültig" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Token enthält keine erkennbare Benutzeridentifikation" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Benutzer nicht gefunden" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Inaktiver Benutzer" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Unerkannter Algorithmustyp '{}'" @@ -70,17 +70,17 @@ msgstr "Ungültiger oder abgelaufener Token" msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 4bb9e0bea..4a885675c 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -12,31 +12,31 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "El encabezado 'Authorization' debe contener valores delimitados por espacios" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "El token dado no es valido para ningun tipo de token" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "El token no contenía identificación de usuario reconocible" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "El usuario está inactivo" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" @@ -70,17 +70,17 @@ msgstr "El token es inválido o ha expirado" msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "La combinación de credenciales no tiene una cuenta activa" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "La combinación de credenciales no tiene una cuenta activa" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "El token está en lista negra" diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index aeca82b76..42ab2ec55 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -17,31 +17,31 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "La contraseña del usuario ha sido cambiada." + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "El header de autorización debe contener dos valores delimitados por espacio" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "El token proporcionado no es válido para ningún tipo." -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "El token no contiene ninguna identificación de usuario válida." -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "No se encontró el usuario." -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "El usuario está inactivo" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "La contraseña del usuario ha sido cambiada." - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" @@ -75,17 +75,17 @@ msgstr "El token es inválido o ha expirado" msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "No se encontró una cuenta activa con las credenciales proporcionadas." -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "No se encontró una cuenta activa para el token proporcionado" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "El token ha sido revocado" diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index 3c812f6a7..27bacc099 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -12,31 +12,31 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "El header de autorización debe contener dos valores delimitados por espacio" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "El token provisto no es válido para ningún tipo de token" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "El token no contiene identificación de usuario reconocible" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Usuario no encontrado" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "El usuario está inactivo" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo no reconocido '{}'" @@ -70,19 +70,19 @@ msgstr "Token inválido o expirado" msgid "Token is invalid or expired" msgstr "Token inválido o expirado" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token está en la blacklist" diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po index 589a12da1..67cd7caa1 100644 --- a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po @@ -16,30 +16,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "رمز عبور کاربر تغییر کرده است" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا شده با فاصله باشد" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "کاربر یافت نشد" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "رمز عبور کاربر تغییر کرده است" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" @@ -69,15 +69,15 @@ msgstr "توکن منقضی شده است" msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 msgid "No active account found for the given token." msgstr "هیچ اکانت فعالی برای این توکن یافت نشد" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "توکن در لیست سیاه قرار گرفته است" diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index e42d27d46..e6cc74898 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -11,30 +11,30 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "رمز عبور کاربر تغییر کرده است" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "هدر اعتبارسنجی باید شامل دو مقدار جدا شده با فاصله باشد" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "توکن داده شده برای هیچ نوع توکنی معتبر نمی‌باشد" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "توکن شامل هیچ شناسه قابل تشخیصی از کاربر نیست" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "کاربر یافت نشد" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "کاربر غیرفعال است" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "رمز عبور کاربر تغییر کرده است" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "نوع الگوریتم ناشناخته '{}'" @@ -64,15 +64,15 @@ msgstr "توکن منقضی شده است" msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 msgid "No active account found for the given token." msgstr "هیچ اکانت فعالی برای توکن داده شده یافت نشد" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index 78536c27b..6cb99de26 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -11,32 +11,32 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "L'en-tête 'Authorization' doit contenir deux valeurs séparées par des espaces" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Le type de jeton fourni n'est pas valide" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "" "Le jeton ne contient aucune information permettant d'identifier l'utilisateur" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "L'utilisateur n'a pas été trouvé" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "L'utilisateur est désactivé" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Type d'algorithme non reconnu '{}'" @@ -70,17 +70,17 @@ msgstr "Le jeton est invalide ou expiré" msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Le jeton a été banni" diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po index 48c3f7d10..7c451a7d9 100644 --- a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po @@ -16,30 +16,30 @@ msgstr "" "2 : 3);\n" "X-Generator: Poedit 3.2.2\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "Authorization Header חייבת להכיל שני ערכים מופרדים ברווח" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "המזהה הנתון אינו תקף עבור אף סיווג" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "המזהה לא הכיל זיהוי משתמש שניתן לזהות" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "משתמש לא נמצא" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "המשתמש אינו פעיל" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "סוג אלגוריתם לא מזוהה '{}'" @@ -73,17 +73,17 @@ msgstr "המזהה אינו חוקי או שפג תוקפו" msgid "Token is invalid or expired" msgstr "המזהה אינו חוקי או שפג תוקפו" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "המזהה ברשימה השחורה." diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index f4ac200d5..42606991d 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -16,30 +16,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "Header otorisasi harus berisi dua nilai yang dipisahkan spasi" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Token yang diberikan tidak valid untuk semua jenis token" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Token tidak mengandung identifikasi pengguna yang dapat dikenali" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Pengguna tidak ditemukan" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Pengguna tidak aktif" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Jenis algoritma tidak dikenal '{}'" @@ -74,17 +74,17 @@ msgstr "Token tidak valid atau kedaluwarsa" msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index 9389d8b06..2389e7eeb 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -15,31 +15,31 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "L'header di autorizzazione deve contenere due valori delimitati da uno spazio" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Il token dato non è valido per qualsiasi tipo di token" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Il token non conteneva nessuna informazione riconoscibile dell'utente" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Utente non trovato" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Utente non attivo" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Algoritmo di tipo '{}' non riconosciuto" @@ -73,17 +73,17 @@ msgstr "Il token non è valido o è scaduto" msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Nessun account attivo trovato con queste credenziali" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Nessun account attivo trovato con queste credenziali" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index 350bd3512..6a8214f2c 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -12,30 +12,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "사용자의 비밀번호가 바뀌었습니다." + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "인증 헤더에는 공백으로 구분 된 두 개의 값이 포함되어야 합니다" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "이 토큰은 모든 타입의 토큰에 대해 유효하지 않습니다" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "토큰에 사용자 식별자가 포함되어 있지 않습니다" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "찾을 수 없는 사용자입니다" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "비활성화된 사용자입니다" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "사용자의 비밀번호가 바뀌었습니다." - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "'{}' 는 알 수 없는 알고리즘 유형입니다" @@ -71,17 +71,17 @@ msgstr "유효하지 않거나 만료된 토큰입니다" msgid "Token is invalid or expired" msgstr "유효하지 않거나 만료된 토큰입니다" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "블랙리스트에 추가된 토큰입니다" diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index b87b5da79..42c818963 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -11,31 +11,31 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "Authorisatie header moet twee waarden bevatten, gescheiden door een spatie" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Het token is voor geen enkel token-type geldig" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Token bevat geen herkenbare gebruikersidentificatie" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Gebruiker niet gevonden" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Gebruiker is inactief" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Niet herkend algoritme type '{}" @@ -69,17 +69,17 @@ msgstr "Token is niet geldig of verlopen" msgid "Token is invalid or expired" msgstr "Token is niet geldig of verlopen" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Geen actief account gevonden voor deze gegevens" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Geen actief account gevonden voor deze gegevens" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index 0ec26bc85..8c00b15f2 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -11,30 +11,30 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "Nagłówek autoryzacji musi zawierać dwie wartości rodzielone spacjami" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Podany token jest błędny dla każdego typu tokena" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Token nie zawierał rozpoznawalnej identyfikacji użytkownika" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Użytkownik nie znaleziony" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Użytkownik jest nieaktywny" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Nierozpoznany typ algorytmu '{}'" @@ -68,17 +68,17 @@ msgstr "Token jest niepoprawny lub wygasł" msgid "Token is invalid or expired" msgstr "Token jest niepoprawny lub wygasł" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index a7aabb13d..42e656aec 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -12,31 +12,31 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "A senha do usuário foi alterada." + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "Cabeçalho de autorização deve conter dois valores delimitados por espaço" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "O token informado não é válido para qualquer tipo de token" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "O token não continha nenhuma identificação reconhecível do usuário" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Usuário não encontrado" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Usuário está inativo" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "A senha do usuário foi alterada." - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipo de algoritmo '{}' não reconhecido" @@ -67,15 +67,15 @@ msgstr "Token expirado" msgid "Token is invalid or expired" msgstr "Token inválido ou expirado" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 msgid "No active account found for the given token." msgstr "Nenhuma conta ativa encontrada para o token fornecido." -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token está na blacklist" diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po index 1dcfc1235..9030644fc 100644 --- a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -12,32 +12,32 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "Header-ul(antetul) de autorizare trebuie să conțină două valori separate " "prin spațiu" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Tokenul dat nu este valid pentru niciun tip de token" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Tokenul nu conține date de identificare a utilizatorului" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Utilizatorul nu a fost găsit" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Utilizatorul este inactiv" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tipul de algoritm '{}' nu este recunoscut" @@ -73,17 +73,17 @@ msgstr "Token nu este valid sau a expirat" msgid "Token is invalid or expired" msgstr "Token nu este valid sau a expirat" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Tokenul este în listă de tokenuri blocate" diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index 9a1c55723..e666bcb44 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -16,31 +16,31 @@ msgstr "" "n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" "X-Generator: Poedit 2.2.1\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "Заголовок авторизации должен содержать два значения, разделенных пробелом" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Данный токен недействителен для любого типа токена" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Токен не содержит идентификатор пользователя" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Пользователь не найден" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Пользователь неактивен" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Нераспознанный тип алгоритма '{}'" @@ -74,17 +74,17 @@ msgstr "Токен недействителен или просрочен" msgid "Token is invalid or expired" msgstr "Токен недействителен или просрочен" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Не найдено активной учетной записи с указанными данными" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Не найдено активной учетной записи с указанными данными" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po index 91d7fa88a..3608c1069 100644 --- a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po @@ -15,31 +15,31 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "Glava 'Authorization' mora vsebovati dve vrednosti, ločeni s presledkom" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Podan žeton ni veljaven za nobeno vrsto žetona" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Žeton ni vseboval prepoznavne identifikacije uporabnika" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Uporabnik ni najden" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Uporabnik je neaktiven" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Neprepoznana vrsta algoritma'{}'" @@ -74,17 +74,17 @@ msgstr "Žeton je neveljaven ali potekel" msgid "Token is invalid or expired" msgstr "Žeton je neveljaven ali potekel" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Aktiven račun s podanimi poverilnicami ni najden" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Aktiven račun s podanimi poverilnicami ni najden" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Žeton je na črnem seznamu" diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po index 3928eeed4..b927f990f 100644 --- a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -12,30 +12,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "Auktoriseringshuvudet måste innehålla två mellanslagsavgränsade värden" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Givet token är inte giltigt för någon tokentyp" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Token innehöll ingen identifiering av användaren" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Användaren hittades inte" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Användaren är inaktiv" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Okänd algoritmtyp '{}'" @@ -69,17 +69,17 @@ msgstr "Token är ogiltig eller har löpt ut" msgid "Token is invalid or expired" msgstr "Token är ogiltig eller har löpt ut" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token är svartlistad" diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 82604445c..9eb196bb5 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -12,32 +12,32 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "" "Yetkilendirme header'i boşlukla sınırlandırılmış iki değer bulundurmak " "zorunda" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Verilen token hiçbir token tipi için geçerli değil" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Token tanınabilir bir kullanıcı kimliği içermiyor" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Kullanıcı bulunamadı" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Kullanıcı etkin değil" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Tanınmayan algortima tipi '{}'" @@ -71,17 +71,17 @@ msgstr "Token geçersiz veya süresi geçmiş" msgid "Token is invalid or expired" msgstr "Token geçersiz veya süresi geçmiş" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Token kara listeye alınmış" diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index 92b53187b..59018eabd 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -15,30 +15,30 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "Авторизаційний заголовок має містити два значення розділені пробілом" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Наданий токен не відповідає жодному типу ключа" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Наданий токен не мітить жодної ідентифікаційної інформації" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Користувач не знайдений" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Користувач неактивний" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Тип алгоритму '{}' не розпізнаний" @@ -72,17 +72,17 @@ msgstr "Токен некоректний або термін його дії в msgid "Token is invalid or expired" msgstr "Токен некоректний або термін його дії вичерпаний" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index cf4de1ada..ab5bb67fa 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -15,30 +15,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:89 +#: authentication.py:37 serializers.py:110 serializers.py:180 +msgid "The user's password has been changed." +msgstr "" + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "授权头必须包含两个用空格分隔的值" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "此令牌对任何类型的令牌无效" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "令牌未包含用户标识符" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "未找到该用户" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "该用户已禁用" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "" - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "未知算法类型 '{}'" @@ -72,17 +72,17 @@ msgstr "令牌无效或已过期" msgid "Token is invalid or expired" msgstr "令牌无效或已过期" -#: serializers.py:35 +#: serializers.py:36 msgid "No active account found with the given credentials" msgstr "找不到指定凭据对应的有效用户" -#: serializers.py:108 +#: serializers.py:109 serializers.py:179 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "找不到指定凭据对应的有效用户" -#: serializers.py:178 tokens.py:280 +#: serializers.py:245 tokens.py:280 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" From 529f8bb780767ae300b288399ed95aeb643fe897 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 30 Aug 2025 18:14:04 +0200 Subject: [PATCH 163/171] Add hook mechanism when a login attempt fails or succeeds (#904) * Add hook mechanism when a login attempt fails or succeeds * Add doc on ON_LOGIN_SUCCESS and ON_LOGIN_FAILED --------- Co-authored-by: mdefeche --- docs/settings.rst | 16 ++++++++++++++++ rest_framework_simplejwt/serializers.py | 18 +++++++++++++++--- rest_framework_simplejwt/settings.py | 4 ++++ tests/test_views.py | 20 ++++++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index 03219f7c1..c99fb45c3 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -34,6 +34,8 @@ Some of Simple JWT's behavior can be customized through settings variables in "USER_ID_FIELD": "id", "USER_ID_CLAIM": "user_id", "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule", + "ON_LOGIN_SUCCESS": "rest_framework_simplejwt.serializers.default_on_login_success", + "ON_LOGIN_FAILED": "rest_framework_simplejwt.serializers.default_on_login_failed", "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), "TOKEN_TYPE_CLAIM": "token_type", @@ -223,6 +225,20 @@ to the callable as an argument. The default rule is to check that the ``is_activ flag is still ``True``. The callable must return a boolean, ``True`` if authorized, ``False`` otherwise resulting in a 401 status code. +``ON_LOGIN_SUCCESS`` +---------------------------- + +Callable to add logic whenever a login attempt succeeded. ``UPDATE_LAST_LOGIN`` +must be set to ``True``. The callable does not return anything. +The default callable updates last_login field in the auth_user table upon login +(TokenObtainPairView). + +``ON_LOGIN_FAILED`` +---------------------------- + +Callable to add logic whenever a login attempt failed. The callable does not +return anything. The default callable does nothing (``pass``) + ``AUTH_TOKEN_CLASSES`` ---------------------- diff --git a/rest_framework_simplejwt/serializers.py b/rest_framework_simplejwt/serializers.py index 04c8be43b..ab76a0ff7 100644 --- a/rest_framework_simplejwt/serializers.py +++ b/rest_framework_simplejwt/serializers.py @@ -1,11 +1,12 @@ from typing import Any, Optional, TypeVar from django.conf import settings -from django.contrib.auth import authenticate, get_user_model +from django.contrib.auth import _clean_credentials, authenticate, get_user_model from django.contrib.auth.models import AbstractBaseUser, update_last_login from django.utils.translation import gettext_lazy as _ from rest_framework import exceptions, serializers from rest_framework.exceptions import AuthenticationFailed, ValidationError +from rest_framework.request import Request from .models import TokenUser from .settings import api_settings @@ -55,6 +56,9 @@ def validate(self, attrs: dict[str, Any]) -> dict[Any, Any]: self.user = authenticate(**authenticate_kwargs) if not api_settings.USER_AUTHENTICATION_RULE(self.user): + api_settings.ON_LOGIN_FAILED( + _clean_credentials(attrs), self.context.get("request") + ) raise exceptions.AuthenticationFailed( self.error_messages["no_active_account"], "no_active_account", @@ -79,7 +83,7 @@ def validate(self, attrs: dict[str, Any]) -> dict[str, str]: data["access"] = str(refresh.access_token) if api_settings.UPDATE_LAST_LOGIN: - update_last_login(None, self.user) + api_settings.ON_LOGIN_SUCCESS(self.user, self.context.get("request")) return data @@ -95,7 +99,7 @@ def validate(self, attrs: dict[str, Any]) -> dict[str, str]: data["token"] = str(token) if api_settings.UPDATE_LAST_LOGIN: - update_last_login(None, self.user) + api_settings.ON_LOGIN_SUCCESS(self.user, self.context.get("request")) return data @@ -258,3 +262,11 @@ def validate(self, attrs: dict[str, Any]) -> dict[Any, Any]: except AttributeError: pass return {} + + +def default_on_login_success(user: AuthUser, request: Optional[Request]) -> None: + update_last_login(None, user) + + +def default_on_login_failed(credentials: dict, request: Optional[Request]) -> None: + pass diff --git a/rest_framework_simplejwt/settings.py b/rest_framework_simplejwt/settings.py index 518a9ad66..5c4d9fc4a 100644 --- a/rest_framework_simplejwt/settings.py +++ b/rest_framework_simplejwt/settings.py @@ -29,6 +29,8 @@ "USER_ID_FIELD": "id", "USER_ID_CLAIM": "user_id", "USER_AUTHENTICATION_RULE": "rest_framework_simplejwt.authentication.default_user_authentication_rule", + "ON_LOGIN_SUCCESS": "rest_framework_simplejwt.serializers.default_on_login_success", + "ON_LOGIN_FAILED": "rest_framework_simplejwt.serializers.default_on_login_failed", "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), "TOKEN_TYPE_CLAIM": "token_type", "JTI_CLAIM": "jti", @@ -52,6 +54,8 @@ "JSON_ENCODER", "TOKEN_USER_CLASS", "USER_AUTHENTICATION_RULE", + "ON_LOGIN_SUCCESS", + "ON_LOGIN_FAILED", ) REMOVED_SETTINGS = ( diff --git a/tests/test_views.py b/tests/test_views.py index 4927e6ffd..0f67f81b0 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -1,4 +1,5 @@ from datetime import timedelta +from unittest import mock from unittest.mock import patch from django.contrib.auth import get_user_model @@ -105,6 +106,25 @@ def test_update_last_login_updated(self): self.assertIsNotNone(user.last_login) self.assertGreaterEqual(timezone.now(), user.last_login) + def test_on_login_failed_is_called(self): + # Patch the ON_LOGIN_FAILED setting + with mock.patch( + "rest_framework_simplejwt.settings.api_settings.ON_LOGIN_FAILED" + ) as mocked_hook: + self.test_credentials_wrong() + mocked_hook.assert_called_once() + + # Optional: check exact arguments + args, kwargs = mocked_hook.call_args + credentials, request = args + self.assertEqual( + credentials, + { + User.USERNAME_FIELD: self.username, + "password": "********************", + }, + ) + class TestTokenRefreshView(APIViewTestCase): view_name = "token_refresh" From 9438ade2aa5ad26ba62979905cd856e234305461 Mon Sep 17 00:00:00 2001 From: Dulat Kushibayev <4339845+kushibayev@users.noreply.github.com> Date: Sat, 30 Aug 2025 19:15:50 +0300 Subject: [PATCH 164/171] Add Kazakh (kk) translations for drf-simplejwt (#916) --- .../locale/kk/LC_MESSAGES/django.mo | Bin 0 -> 4213 bytes .../locale/kk/LC_MESSAGES/django.po | 155 ++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.mo create mode 100644 rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.po diff --git a/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.mo b/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..a3cc991a6b90911616d0b5dbf3bc1ee632601ff4 GIT binary patch literal 4213 zcmbuBU2Ggz6~`~7Kx-%;Z6W3RmJ)2YS=VtXL{7p-+8P-e5>-wq2!h7D*Siz%&MY&t zcAY4~b}AIrLIp)wq7g!*?L(hp6I`c`w|U_i&1_!afr_UJA$Z^g9?Ap1bMNej?U+Vl zq`UvQ_nvd^`S_nZ`{v!Z|3dLR!1xs7i|nFg3ud64|8MX^;Jxor>JjkspsYUw z?g1O1?Ee%Le|`nt3trCg_uz+_|0&16f#T2Gpa%E6SE+IE04Q>c;0M7Apu~L%>;qdl z{uv|$^;Zzr)Zf8xlB0iui_8z*q0|?^>!9S}E$|26J$EYg9QY$p;`|qQ035^kN$|(u zEchn)0QmI#$q{%OjKG({F>ucZlsW>Q1jYVuz;W;opqzW(UDOQxDmV-#pyc}%@N?iF z!7qbvgAam_5Uk|mBq(-IgA#WW6o38!?gb4=7Jrt&?|^IIr@^~O+7S2TYFNvExk2IUd%NWH}ud4vP^ z*f&=@^zli%G=i)NhOT@(_Z3-fvy;@WFlQ_#ECA3 zLE`y=PG&{t`bk9xp-$%NMk8GHr%dA4jQWN@gT50IE&T9H)}9y4rWVea(vUu0HC}9(Pf?O2 zbmEdbZ^rYh-elFZmE$36Pcqsc>$(@mvtd-~nk-hlpo~dni{uOytDax8BIen;kNf#% zr>6NlrvVkFAdxACV zJCe)Uayq|dWi|>)R?nhO+PXB%ZLzpDDi(Z4iLOMxAOvd*p9tC!5^t9~mWSf7+9J?d z-lzMk#>{$i{jPN;VeOP-uOB4)^i(zU5;;dmOcy2IkUC+rCvG`1x&m;F-VNTVDVCc;tOcl=o4 zDKq1Xg~H>s?5G|Y9(lAd{H4P1h#npueRTgr!#sUYdT~;ih`b=KdPx|K>c<5uEQrL#tH|za^eylRd^yOhSH;>`oN^0^c}A@BClE) z3!_>*s)M?n#)n4^YWI40Ah`eV{=tKND*ajd+iWp?Bb!gJrt9fS_LKB#_JU?_|8XF-diUE568(k81nUQMrM%LrX@3v1~{wye|58^5&M z=^JdH%a(Myk*;wj+p6^mrfc zIBis-uyNy6G!eJKUX$%SRozfgM^daUFwSA4bs0etDLKp!RO!#fvN*oO07BXMbTwPf z=6f>8t8-ht?(xRta!5y0~p%vb5Sc6b+ z)iQt@txEEUcSX`Tw3}a|3~PiN_$LXom1nxa$u=|p-?`8dvRdXeEn}o5E;!;>?c`{F?Ap8qUcZtKp!7u~kcw$xv~Y&$+uyLFQ!iWa0} z&dCR4m!9JYqS|t=sWWG9LhWuxZ~2d8Z{Ma6TrLXNRJ-{pjg329IXrWpa+KA!GGnsS StGW56?kd=STsQxMs{aB^5|JGM literal 0 HcmV?d00001 diff --git a/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.po new file mode 100644 index 000000000..22e37b238 --- /dev/null +++ b/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.po @@ -0,0 +1,155 @@ +# This file is distributed under the same license as the djangorestframework_simplejwt package. +# Dulat Kushibayev , 2025. +msgid "" +msgstr "" +"Project-Id-Version: djangorestframework_simplejwt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2025-06-02 02:51+0300\n" +"PO-Revision-Date: 2025-06-02 00:51+0000\n" +"Last-Translator: Dulat Kushibayev \n" +"Language-Team: \n" +"Language: kk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +#: authentication.py:89 +msgid "Authorization header must contain two space-delimited values" +msgstr "Авторизация тақырыптамасында бос орынмен бөлінген екі мән болуы керек" + +#: authentication.py:115 +msgid "Given token not valid for any token type" +msgstr "Берілген токен ешбір токен түріне жарамсыз" + +#: authentication.py:128 authentication.py:166 +msgid "Token contained no recognizable user identification" +msgstr "Токенде пайдаланушы идентификаторы жоқ" + +#: authentication.py:135 +msgid "User not found" +msgstr "Пайдаланушы табылмады" + +#: authentication.py:139 +msgid "User is inactive" +msgstr "Пайдаланушы өшірулі" + +#: authentication.py:146 +msgid "The user's password has been changed." +msgstr "Пайдаланушының құпия сөзі өзгертілді." + +#: backends.py:90 +msgid "Unrecognized algorithm type '{}'" +msgstr "Белгісіз алгоритм түрі '{}'" + +#: backends.py:96 +msgid "You must have cryptography installed to use {}." +msgstr "{} пайдалану үшін cryptography орнатылған болуы керек." + +#: backends.py:111 +msgid "" +"Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." +msgstr "Белгісіз түр '{}', 'leeway' мәні int, float немесе timedelta түрінде болуы керек." + +#: backends.py:125 backends.py:177 tokens.py:69 +msgid "Token is invalid" +msgstr "Токен жарамсыз" + +#: backends.py:173 +msgid "Invalid algorithm specified" +msgstr "Көрсетілген алгоритм жарамсыз" + +#: backends.py:175 tokens.py:67 +msgid "Token is expired" +msgstr "Токеннің мерзімі өткен" + +#: exceptions.py:55 +msgid "Token is invalid or expired" +msgstr "Токен жарамсыз немесе мерзімі өткен" + +#: serializers.py:35 +msgid "No active account found with the given credentials" +msgstr "Көрсетілген тіркелгі деректері бойынша есептік жазба табылмады." + +#: serializers.py:108 +msgid "No active account found for the given token." +msgstr "Көрсетілген токен бойынша есептік жазба табылмады." + +#: serializers.py:178 tokens.py:281 +msgid "Token is blacklisted" +msgstr "Токен қара тізімге енгізілген" + +#: settings.py:74 +msgid "" +"The '{}' setting has been removed. Please refer to '{}' for available " +"settings." +msgstr "'{}' параметрі жойылды. Қол жетімді параметрлер үшін '{}' қараңыз." + +#: token_blacklist/admin.py:79 +msgid "jti" +msgstr "jti" + +#: token_blacklist/admin.py:85 +msgid "user" +msgstr "пайдаланушы" + +#: token_blacklist/admin.py:91 +msgid "created at" +msgstr "құрылған уақыты" + +#: token_blacklist/admin.py:97 +msgid "expires at" +msgstr "мерзімі аяқталатын уақыт" + +#: token_blacklist/apps.py:7 +msgid "Token Blacklist" +msgstr "Токендердің қара тізімі" + +#: token_blacklist/models.py:19 +msgid "Outstanding Token" +msgstr "Қолданыстағы токен" + +#: token_blacklist/models.py:20 +msgid "Outstanding Tokens" +msgstr "Қолданыстағы токендер" + +#: token_blacklist/models.py:32 +#, python-format +msgid "Token for %(user)s (%(jti)s)" +msgstr "%(user)s үшін токен (%(jti)s)" + +#: token_blacklist/models.py:45 +msgid "Blacklisted Token" +msgstr "Қара тізімдегі токен" + +#: token_blacklist/models.py:46 +msgid "Blacklisted Tokens" +msgstr "Қара тізімдегі токендер" + +#: token_blacklist/models.py:57 +#, python-format +msgid "Blacklisted token for %(user)s" +msgstr "%(user)s пайдаланушысына тиесілі қара тізімдегі токен" + +#: tokens.py:53 +msgid "Cannot create token with no type or lifetime" +msgstr "Түрі немесе жарамдылық мерзімі көрсетілмеген токенді жасау мүмкін емес" + +#: tokens.py:127 +msgid "Token has no id" +msgstr "Токенде идентификатор жоқ" + +#: tokens.py:139 +msgid "Token has no type" +msgstr "Токенде түрі көрсетілмеген" + +#: tokens.py:142 +msgid "Token has wrong type" +msgstr "Токеннің түрі қате" + +#: tokens.py:201 +msgid "Token has no '{}' claim" +msgstr "Токенде '{}' талап мерзімі жоқ" + +#: tokens.py:206 +msgid "Token '{}' claim has expired" +msgstr "Токеннің '{}' талап мерзімі аяқталған" From 32ca51bd7130ad1d997502112ba9ab1d886a1ec9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 30 Aug 2025 12:21:47 -0400 Subject: [PATCH 165/171] Update locale files (#935) Co-authored-by: Andrew-Chen-Wang <60190294+Andrew-Chen-Wang@users.noreply.github.com> --- .../locale/ar/LC_MESSAGES/django.po | 10 +++--- .../locale/cs/LC_MESSAGES/django.po | 10 +++--- .../locale/de/LC_MESSAGES/django.po | 10 +++--- .../locale/es/LC_MESSAGES/django.po | 10 +++--- .../locale/es_AR/LC_MESSAGES/django.po | 10 +++--- .../locale/es_CL/LC_MESSAGES/django.po | 10 +++--- .../locale/fa/LC_MESSAGES/django.po | 10 +++--- .../locale/fa_IR/LC_MESSAGES/django.po | 10 +++--- .../locale/fr/LC_MESSAGES/django.po | 10 +++--- .../locale/he_IL/LC_MESSAGES/django.po | 10 +++--- .../locale/id_ID/LC_MESSAGES/django.po | 10 +++--- .../locale/it_IT/LC_MESSAGES/django.po | 10 +++--- .../locale/kk/LC_MESSAGES/django.po | 31 ++++++++++--------- .../locale/ko_KR/LC_MESSAGES/django.po | 10 +++--- .../locale/nl_NL/LC_MESSAGES/django.po | 10 +++--- .../locale/pl_PL/LC_MESSAGES/django.po | 10 +++--- .../locale/pt_BR/LC_MESSAGES/django.po | 10 +++--- .../locale/ro/LC_MESSAGES/django.po | 10 +++--- .../locale/ru_RU/LC_MESSAGES/django.po | 10 +++--- .../locale/sl/LC_MESSAGES/django.po | 10 +++--- .../locale/sv/LC_MESSAGES/django.po | 10 +++--- .../locale/tr/LC_MESSAGES/django.po | 10 +++--- .../locale/uk_UA/LC_MESSAGES/django.po | 10 +++--- .../locale/zh_Hans/LC_MESSAGES/django.po | 10 +++--- 24 files changed, 132 insertions(+), 129 deletions(-) diff --git a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po index 5ba7de8fd..d65afec93 100644 --- a/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ar/LC_MESSAGES/django.po @@ -13,7 +13,7 @@ msgstr "" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -71,21 +71,21 @@ msgstr "تأشيرة المرور غير صالحة أو منتهية الصلا msgid "Token is invalid or expired" msgstr "تأشيرة المرور غير صالحة أو منتهية الصلاحية" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "لم يتم العثور على حساب نشط للبيانات المقدمة" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "التأشيرة مدرجة في القائمة السوداء" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po index 8a81ce782..620775fc0 100644 --- a/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/cs/LC_MESSAGES/django.po @@ -11,7 +11,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -68,21 +68,21 @@ msgstr "Token není validní nebo vypršela jeho platnost" msgid "Token is invalid or expired" msgstr "Token není validní nebo vypršela jeho platnost" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Žádný aktivní účet s danými údaji nebyl nalezen" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token je na černé listině" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po index 991214217..60e4df2cf 100644 --- a/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/de/LC_MESSAGES/django.po @@ -12,7 +12,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -70,21 +70,21 @@ msgstr "Ungültiger oder abgelaufener Token" msgid "Token is invalid or expired" msgstr "Ungültiger oder abgelaufener Token" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Kein aktiver Account mit diesen Zugangsdaten gefunden" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token steht auf der Blacklist" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po index 4a885675c..20d54f556 100644 --- a/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es/LC_MESSAGES/django.po @@ -12,7 +12,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -70,21 +70,21 @@ msgstr "El token es inválido o ha expirado" msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "La combinación de credenciales no tiene una cuenta activa" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "La combinación de credenciales no tiene una cuenta activa" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "El token está en lista negra" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po index 42ab2ec55..c0a193227 100644 --- a/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_AR/LC_MESSAGES/django.po @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "La contraseña del usuario ha sido cambiada." @@ -75,21 +75,21 @@ msgstr "El token es inválido o ha expirado" msgid "Token is invalid or expired" msgstr "El token es inválido o ha expirado" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "No se encontró una cuenta activa con las credenciales proporcionadas." -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "No se encontró una cuenta activa para el token proporcionado" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "El token ha sido revocado" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po index 27bacc099..abde07514 100644 --- a/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/es_CL/LC_MESSAGES/django.po @@ -12,7 +12,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -70,23 +70,23 @@ msgstr "Token inválido o expirado" msgid "Token is invalid or expired" msgstr "Token inválido o expirado" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "" "No se encontró una cuenta de usuario activa para las credenciales provistas" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token está en la blacklist" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po index 67cd7caa1..5cd24c1da 100644 --- a/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa/LC_MESSAGES/django.po @@ -16,7 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "رمز عبور کاربر تغییر کرده است" @@ -69,19 +69,19 @@ msgstr "توکن منقضی شده است" msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 msgid "No active account found for the given token." msgstr "هیچ اکانت فعالی برای این توکن یافت نشد" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "توکن در لیست سیاه قرار گرفته است" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po index e6cc74898..adb04da96 100644 --- a/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fa_IR/LC_MESSAGES/django.po @@ -11,7 +11,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "رمز عبور کاربر تغییر کرده است" @@ -64,19 +64,19 @@ msgstr "توکن منقضی شده است" msgid "Token is invalid or expired" msgstr "توکن نامعتبر است یا منقضی شده است" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "هیچ اکانت فعالی برای اطلاعات داده شده یافت نشد" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 msgid "No active account found for the given token." msgstr "هیچ اکانت فعالی برای توکن داده شده یافت نشد" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "توکن به لیست سیاه رفته است" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po index 6cb99de26..f750ea26a 100644 --- a/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/fr/LC_MESSAGES/django.po @@ -11,7 +11,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -70,21 +70,21 @@ msgstr "Le jeton est invalide ou expiré" msgid "Token is invalid or expired" msgstr "Le jeton est invalide ou expiré" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Aucun compte actif n'a été trouvé avec les identifiants fournis" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Le jeton a été banni" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po index 7c451a7d9..3d07c2903 100644 --- a/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/he_IL/LC_MESSAGES/django.po @@ -16,7 +16,7 @@ msgstr "" "2 : 3);\n" "X-Generator: Poedit 3.2.2\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -73,21 +73,21 @@ msgstr "המזהה אינו חוקי או שפג תוקפו" msgid "Token is invalid or expired" msgstr "המזהה אינו חוקי או שפג תוקפו" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "לא נמצא חשבון עם פרטי זיהוי אלו" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "המזהה ברשימה השחורה." -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po index 42606991d..bc8cdb9d8 100644 --- a/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/id_ID/LC_MESSAGES/django.po @@ -16,7 +16,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -74,21 +74,21 @@ msgstr "Token tidak valid atau kedaluwarsa" msgid "Token is invalid or expired" msgstr "Token tidak valid atau kedaluwarsa" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Tidak ada akun aktif yang ditemukan dengan kredensial yang diberikan" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token masuk daftar hitam" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po index 2389e7eeb..ce8e30739 100644 --- a/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/it_IT/LC_MESSAGES/django.po @@ -15,7 +15,7 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -73,21 +73,21 @@ msgstr "Il token non è valido o è scaduto" msgid "Token is invalid or expired" msgstr "Il token non è valido o è scaduto" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Nessun account attivo trovato con queste credenziali" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Nessun account attivo trovato con queste credenziali" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Il token è stato inserito nella blacklist" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.po index 22e37b238..22a638a73 100644 --- a/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/kk/LC_MESSAGES/django.po @@ -13,30 +13,31 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" -#: authentication.py:89 + +#: authentication.py:37 serializers.py:114 serializers.py:184 +msgid "The user's password has been changed." +msgstr "Пайдаланушының құпия сөзі өзгертілді." + +#: authentication.py:93 msgid "Authorization header must contain two space-delimited values" msgstr "Авторизация тақырыптамасында бос орынмен бөлінген екі мән болуы керек" -#: authentication.py:115 +#: authentication.py:119 msgid "Given token not valid for any token type" msgstr "Берілген токен ешбір токен түріне жарамсыз" -#: authentication.py:128 authentication.py:166 +#: authentication.py:132 authentication.py:171 msgid "Token contained no recognizable user identification" msgstr "Токенде пайдаланушы идентификаторы жоқ" -#: authentication.py:135 +#: authentication.py:139 msgid "User not found" msgstr "Пайдаланушы табылмады" -#: authentication.py:139 +#: authentication.py:143 msgid "User is inactive" msgstr "Пайдаланушы өшірулі" -#: authentication.py:146 -msgid "The user's password has been changed." -msgstr "Пайдаланушының құпия сөзі өзгертілді." - #: backends.py:90 msgid "Unrecognized algorithm type '{}'" msgstr "Белгісіз алгоритм түрі '{}'" @@ -48,7 +49,9 @@ msgstr "{} пайдалану үшін cryptography орнатылған бол #: backends.py:111 msgid "" "Unrecognized type '{}', 'leeway' must be of type int, float or timedelta." -msgstr "Белгісіз түр '{}', 'leeway' мәні int, float немесе timedelta түрінде болуы керек." +msgstr "" +"Белгісіз түр '{}', 'leeway' мәні int, float немесе timedelta түрінде болуы " +"керек." #: backends.py:125 backends.py:177 tokens.py:69 msgid "Token is invalid" @@ -66,19 +69,19 @@ msgstr "Токеннің мерзімі өткен" msgid "Token is invalid or expired" msgstr "Токен жарамсыз немесе мерзімі өткен" -#: serializers.py:35 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Көрсетілген тіркелгі деректері бойынша есептік жазба табылмады." -#: serializers.py:108 +#: serializers.py:113 serializers.py:183 msgid "No active account found for the given token." msgstr "Көрсетілген токен бойынша есептік жазба табылмады." -#: serializers.py:178 tokens.py:281 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Токен қара тізімге енгізілген" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po index 6a8214f2c..07003205b 100644 --- a/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ko_KR/LC_MESSAGES/django.po @@ -12,7 +12,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "사용자의 비밀번호가 바뀌었습니다." @@ -71,21 +71,21 @@ msgstr "유효하지 않거나 만료된 토큰입니다" msgid "Token is invalid or expired" msgstr "유효하지 않거나 만료된 토큰입니다" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "지정된 자격 증명에 해당하는 활성화된 사용자를 찾을 수 없습니다" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "블랙리스트에 추가된 토큰입니다" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po index 42c818963..31b1172dc 100644 --- a/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/nl_NL/LC_MESSAGES/django.po @@ -11,7 +11,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -69,21 +69,21 @@ msgstr "Token is niet geldig of verlopen" msgid "Token is invalid or expired" msgstr "Token is niet geldig of verlopen" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Geen actief account gevonden voor deze gegevens" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Geen actief account gevonden voor deze gegevens" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token is ge-blacklist" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po index 8c00b15f2..6f088501c 100644 --- a/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pl_PL/LC_MESSAGES/django.po @@ -11,7 +11,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -68,21 +68,21 @@ msgstr "Token jest niepoprawny lub wygasł" msgid "Token is invalid or expired" msgstr "Token jest niepoprawny lub wygasł" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Nie znaleziono aktywnego konta dla podanych danych uwierzytelniających" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token znajduję się na czarnej liście" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po index 42e656aec..3c8258974 100644 --- a/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/pt_BR/LC_MESSAGES/django.po @@ -12,7 +12,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "A senha do usuário foi alterada." @@ -67,19 +67,19 @@ msgstr "Token expirado" msgid "Token is invalid or expired" msgstr "Token inválido ou expirado" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Usuário e/ou senha incorreto(s)" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 msgid "No active account found for the given token." msgstr "Nenhuma conta ativa encontrada para o token fornecido." -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token está na blacklist" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po index 9030644fc..1ff81c5f2 100644 --- a/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ro/LC_MESSAGES/django.po @@ -12,7 +12,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -73,21 +73,21 @@ msgstr "Token nu este valid sau a expirat" msgid "Token is invalid or expired" msgstr "Token nu este valid sau a expirat" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Nu a fost găsit cont activ cu aceste date de autentificare" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Tokenul este în listă de tokenuri blocate" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po index e666bcb44..6f6a7a5e2 100644 --- a/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/ru_RU/LC_MESSAGES/django.po @@ -16,7 +16,7 @@ msgstr "" "n%10<=4 && (n%100<12 || n%100>14) ? 1 : 2);\n" "X-Generator: Poedit 2.2.1\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -74,21 +74,21 @@ msgstr "Токен недействителен или просрочен" msgid "Token is invalid or expired" msgstr "Токен недействителен или просрочен" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Не найдено активной учетной записи с указанными данными" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Не найдено активной учетной записи с указанными данными" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Токен занесен в черный список" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po index 3608c1069..2a7634337 100644 --- a/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sl/LC_MESSAGES/django.po @@ -15,7 +15,7 @@ msgstr "" "X-Generator: Poedit 2.0.6\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -74,21 +74,21 @@ msgstr "Žeton je neveljaven ali potekel" msgid "Token is invalid or expired" msgstr "Žeton je neveljaven ali potekel" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Aktiven račun s podanimi poverilnicami ni najden" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Aktiven račun s podanimi poverilnicami ni najden" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Žeton je na črnem seznamu" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po index b927f990f..d9520ddea 100644 --- a/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/sv/LC_MESSAGES/django.po @@ -12,7 +12,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -69,21 +69,21 @@ msgstr "Token är ogiltig eller har löpt ut" msgid "Token is invalid or expired" msgstr "Token är ogiltig eller har löpt ut" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Inget aktivt konto hittades med de angivna användaruppgifterna" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token är svartlistad" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po index 9eb196bb5..91f135247 100644 --- a/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/tr/LC_MESSAGES/django.po @@ -12,7 +12,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -71,21 +71,21 @@ msgstr "Token geçersiz veya süresi geçmiş" msgid "Token is invalid or expired" msgstr "Token geçersiz veya süresi geçmiş" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Verilen kimlik bilgileriyle aktif bir hesap bulunamadı" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Token kara listeye alınmış" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po index 59018eabd..a4657ce80 100644 --- a/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/uk_UA/LC_MESSAGES/django.po @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -72,21 +72,21 @@ msgstr "Токен некоректний або термін його дії в msgid "Token is invalid or expired" msgstr "Токен некоректний або термін його дії вичерпаний" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "Не знайдено жодного облікового запису по наданих облікових даних" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "Токен занесений у чорний список" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." diff --git a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po index ab5bb67fa..93224f6e4 100644 --- a/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po +++ b/rest_framework_simplejwt/locale/zh_Hans/LC_MESSAGES/django.po @@ -15,7 +15,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: authentication.py:37 serializers.py:110 serializers.py:180 +#: authentication.py:37 serializers.py:114 serializers.py:184 msgid "The user's password has been changed." msgstr "" @@ -72,21 +72,21 @@ msgstr "令牌无效或已过期" msgid "Token is invalid or expired" msgstr "令牌无效或已过期" -#: serializers.py:36 +#: serializers.py:37 msgid "No active account found with the given credentials" msgstr "找不到指定凭据对应的有效用户" -#: serializers.py:109 serializers.py:179 +#: serializers.py:113 serializers.py:183 #, fuzzy #| msgid "No active account found with the given credentials" msgid "No active account found for the given token." msgstr "找不到指定凭据对应的有效用户" -#: serializers.py:245 tokens.py:280 +#: serializers.py:249 tokens.py:280 msgid "Token is blacklisted" msgstr "令牌已被加入黑名单" -#: settings.py:74 +#: settings.py:78 msgid "" "The '{}' setting has been removed. Please refer to '{}' for available " "settings." From 5db4adf6303e4b5a8f271a1ba62e56394f2395bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Corbin?= Date: Mon, 1 Sep 2025 22:56:37 +0200 Subject: [PATCH 166/171] Fix log message to use user.pk instead of user.id (#936) When using a custom user model, the (auto) `id` column may be missing (e.g. being called `uuid` instead --- rest_framework_simplejwt/tokens.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework_simplejwt/tokens.py b/rest_framework_simplejwt/tokens.py index 3d9e363b4..11a05770a 100644 --- a/rest_framework_simplejwt/tokens.py +++ b/rest_framework_simplejwt/tokens.py @@ -221,7 +221,7 @@ def for_user(cls: type[T], user: AuthUser) -> T: if hasattr(user, "is_active") and not user.is_active: logger.warning( - f"Creating token for inactive user: {user.id}. If this is not intentional, consider checking the user's status before calling the `for_user` method." + f"Creating token for inactive user: {user.pk}. If this is not intentional, consider checking the user's status before calling the `for_user` method." ) user_id = getattr(user, api_settings.USER_ID_FIELD) From 657a73cadc24f3b3c163858b6196ee97bbbd51e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Sep 2025 17:44:07 -0400 Subject: [PATCH 167/171] Bump actions/setup-python from 5 to 6 (#938) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/setup-python dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/i18n.yml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/i18n.yml b/.github/workflows/i18n.yml index 3712f67e0..8281e90c9 100644 --- a/.github/workflows/i18n.yml +++ b/.github/workflows/i18n.yml @@ -20,7 +20,7 @@ jobs: uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' cache: 'pip' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f115c638d..d8b94e307 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.9' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a8a282a81..4a15d7f3f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: - uses: actions/checkout@v5 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} From 51eb7f241b5b642575bd1df6243846831df25d3e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 20 Sep 2025 10:05:06 +0200 Subject: [PATCH 168/171] [pre-commit.ci] pre-commit autoupdate (#937) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.10 → v0.13.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.12.10...v0.13.0) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ad394e279..589335134 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-merge-conflict - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.10 + rev: v0.13.0 hooks: - id: ruff types_or: [ python, pyi ] From 2fab70ef4823ade83b0f699a0057d474b2a4ad77 Mon Sep 17 00:00:00 2001 From: Vjeran Grozdanic Date: Sat, 20 Sep 2025 10:40:57 +0200 Subject: [PATCH 169/171] deps: add mypy and stubs packages --- setup.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/setup.py b/setup.py index 81982ba42..675f07f67 100755 --- a/setup.py +++ b/setup.py @@ -19,6 +19,12 @@ "pyupgrade", "pre-commit", ], + "typing": [ + "mypy", + "django-stubs", + "djangorestframework-stubs", + "types-pytz", + ], "doc": [ "Sphinx", "sphinx_rtd_theme>=0.1.9", @@ -41,6 +47,7 @@ extras_require["dev"] + extras_require["test"] + extras_require["lint"] + + extras_require["typing"] + extras_require["doc"] + extras_require["python-jose"] ) From 251d46b579abf8328cc55234e29f4122036976c1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 3 Oct 2025 17:56:44 +0200 Subject: [PATCH 170/171] [pre-commit.ci] pre-commit autoupdate (#942) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.13.0 → v0.13.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.13.0...v0.13.2) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 589335134..bb2c53fba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ repos: hooks: - id: check-merge-conflict - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.13.0 + rev: v0.13.2 hooks: - id: ruff types_or: [ python, pyi ] From 5c067b2c7e9bdf83d958a89b2841bf382c411713 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vjeran=20Grozdani=C4=87?= Date: Fri, 3 Oct 2025 18:00:12 +0200 Subject: [PATCH 171/171] fix: stop using deprecated set-output (#944) --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4a15d7f3f..49ea9370e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,7 +35,7 @@ jobs: - name: Get pip cache dir id: pip-cache run: | - echo "::set-output name=dir::$(pip cache dir)" + echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT - name: Cache uses: actions/cache@v4