diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c64ded..ae6150e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Fixed -- Fix `JSONDecodeError` due to Improper Handling of Nested JSON Strings in JWT Payloads +- Bearer tokens with nested JSON string are now properly handled. Thanks to [`Patrick Rodrigues`](https://github.com/pythrick). ### Changed - Requires [`httpx`](https://www.python-httpx.org)==0.28.\* diff --git a/tests/oauth2/implicit/test_oauth2_implicit_async.py b/tests/oauth2/implicit/test_oauth2_implicit_async.py index 4a0f2c7..81b8d0a 100644 --- a/tests/oauth2/implicit/test_oauth2_implicit_async.py +++ b/tests/oauth2/implicit/test_oauth2_implicit_async.py @@ -1,7 +1,9 @@ +import json import time import datetime import httpx +import jwt import pytest from pytest_httpx import HTTPXMock @@ -237,7 +239,13 @@ async def test_oauth2_implicit_flow_post_token_is_sent_in_authorization_header_b expiry_in_1_hour = datetime.datetime.now( datetime.timezone.utc ) + datetime.timedelta(hours=1) - token = create_token(expiry_in_1_hour) + token = jwt.encode( + { + "exp": expiry_in_1_hour, + "data": json.dumps({"something 漢字": ["漢字 else"]}), + }, + "secret", + ) tab = browser_mock.add_response( opened_url="https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F", reply_url="http://localhost:5000", diff --git a/tests/oauth2/implicit/test_oauth2_implicit_sync.py b/tests/oauth2/implicit/test_oauth2_implicit_sync.py index e4b3add..19645de 100644 --- a/tests/oauth2/implicit/test_oauth2_implicit_sync.py +++ b/tests/oauth2/implicit/test_oauth2_implicit_sync.py @@ -1,7 +1,9 @@ +import json import time import datetime import httpx +import jwt import pytest from pytest_httpx import HTTPXMock @@ -230,7 +232,13 @@ def test_oauth2_implicit_flow_post_token_is_sent_in_authorization_header_by_defa expiry_in_1_hour = datetime.datetime.now( datetime.timezone.utc ) + datetime.timedelta(hours=1) - token = create_token(expiry_in_1_hour) + token = jwt.encode( + { + "exp": expiry_in_1_hour, + "data": json.dumps({"something 漢字": ["漢字 else"]}), + }, + "secret", + ) tab = browser_mock.add_response( opened_url="https://provide_token?response_type=token&state=bee505cb6ceb14b9f6ac3573cd700b3b3e965004078d7bb57c7b92df01e448c992a7a46b4804164fc998ea166ece3f3d5849ca2405c4a548f43b915b0677231c&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F", reply_url="http://localhost:5000", diff --git a/tests/oauth2/tokens/__init__.py b/tests/oauth2/tokens/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/oauth2/tokens/test_tokens.py b/tests/oauth2/tokens/test_tokens.py deleted file mode 100644 index a345ec8..0000000 --- a/tests/oauth2/tokens/test_tokens.py +++ /dev/null @@ -1,30 +0,0 @@ -import json -import jwt - -from httpx_auth._oauth2.tokens import decode_base64 - - -def test_decode_base64(): - # Encode a JSON inside the JWT - dummy_token = jwt.encode({"name": "John"}, key="") - header, body, signature = dummy_token.split(".") - - # Decode the body - decoded_bytes = decode_base64(body) - - # Attempt to load JSON - result = json.loads(decoded_bytes) - assert result == {"name": "John"} - - -def test_decode_base64_with_nested_json_string(): - # Encode a JSON inside the JWT - dummy_token = jwt.encode({"data": json.dumps({"something": ["else"]})}, key="") - header, body, signature = dummy_token.split(".") - - # Decode the body - decoded_bytes = decode_base64(body) - - # Attempt to load JSON - result = json.loads(decoded_bytes) - assert result == {"data": '{"something": ["else"]}'}