Skip to content

Commit

Permalink
Merge branch 'develop' into add-text-mode-webbrowser-note
Browse files Browse the repository at this point in the history
  • Loading branch information
blag authored Nov 25, 2024
2 parents e67de54 + e7996e7 commit fada249
Show file tree
Hide file tree
Showing 24 changed files with 506 additions and 17 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13.0-rc.2']

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
repos:
- repo: https://github.com/psf/black
rev: 24.1.1
rev: 24.8.0
hooks:
- id: black
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<a href="https://pypi.org/project/httpx-auth/"><img alt="Number of downloads" src="https://img.shields.io/pypi/dm/httpx_auth"></a>
</p>

> [!NOTE]
> Version 1.0.0 will be released once httpx is considered as stable (release of 1.0.0).
>
> However, current state can be considered as stable.
Expand Down
13 changes: 6 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,21 @@ testing = [
# Used to generate test tokens
"pyjwt==2.*",
# Used to mock httpx
"pytest_httpx==0.30.*",
"pytest_httpx==0.32.*",
# Used to mock date and time
"time-machine==2.*",
# Used to check coverage
"pytest-cov==4.*",
"pytest-cov==5.*",
# Used to run async tests
"pytest-asyncio==0.23.*",
"pytest-asyncio==0.24.*",
]

[tool.setuptools.packages.find]
exclude = ["tests*"]

[tool.setuptools.dynamic]
version = {attr = "httpx_auth.version.__version__"}

[tool.pytest.ini_options]
filterwarnings = [
"error",
]
]
# Silence deprecation warnings about option "asyncio_default_fixture_loop_scope"
asyncio_default_fixture_loop_scope = "function"
8 changes: 4 additions & 4 deletions tests/aws_signature_v4/test_aws4auth_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,7 @@ async def test_aws_auth_query_reserved_with_fragment(httpx_mock: HTTPXMock):
)

httpx_mock.add_response(
url="https://authorized_only/?@#$%25%5E&+=/,?%3E%3C%60%22;:%5C%7C][%7B%7D%20=@#$%25%5E&+=/,?%3E%3C%60%22;:%5C%7C][%7B%7D",
url=r'https://authorized_only/?@#$%^&+=/,?%3E%3C`";:\|][{}%20=@#$%^&+=/,?%3E%3C`";:\|][{}',
method="POST",
match_headers={
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand Down Expand Up @@ -760,7 +760,7 @@ async def test_aws_auth_path_quoting(httpx_mock: HTTPXMock):
)

httpx_mock.add_response(
url="https://authorized_only/test/hello-*.&%5E~+%7B%7D!$%C2%A3_%20",
url="https://authorized_only/test/hello-*.&^~+{}!$%C2%A3_%20",
method="POST",
match_headers={
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand All @@ -784,7 +784,7 @@ async def test_aws_auth_path_percent_encode_non_s3(httpx_mock: HTTPXMock):
)

httpx_mock.add_response(
url="https://authorized_only/test/%2a%2b%25/~-_%5E&%20%25%25",
url="https://authorized_only/test/%2a%2b%25/~-_^&%20%%",
method="POST",
match_headers={
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand All @@ -808,7 +808,7 @@ async def test_aws_auth_path_percent_encode_s3(httpx_mock: HTTPXMock):
)

httpx_mock.add_response(
url="https://authorized_only/test/%2a%2b%25/~-_%5E&%20%25%25",
url="https://authorized_only/test/%2a%2b%25/~-_^&%20%%",
method="POST",
match_headers={
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand Down
8 changes: 4 additions & 4 deletions tests/aws_signature_v4/test_aws4auth_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,7 +659,7 @@ def test_aws_auth_query_reserved_with_fragment(httpx_mock: HTTPXMock):
)

httpx_mock.add_response(
url="https://authorized_only/?@#$%25%5E&+=/,?%3E%3C%60%22;:%5C%7C][%7B%7D%20=@#$%25%5E&+=/,?%3E%3C%60%22;:%5C%7C][%7B%7D",
url=r'https://authorized_only/?@#$%^&+=/,?%3E%3C`";:\|][{}%20=@#$%^&+=/,?%3E%3C`";:\|][{}',
method="POST",
match_headers={
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand Down Expand Up @@ -734,7 +734,7 @@ def test_aws_auth_path_quoting(httpx_mock: HTTPXMock):
)

httpx_mock.add_response(
url="https://authorized_only/test/hello-*.&%5E~+%7B%7D!$%C2%A3_%20",
url="https://authorized_only/test/hello-*.&^~+{}!$%C2%A3_%20",
method="POST",
match_headers={
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand All @@ -757,7 +757,7 @@ def test_aws_auth_path_percent_encode_non_s3(httpx_mock: HTTPXMock):
)

httpx_mock.add_response(
url="https://authorized_only/test/%2a%2b%25/~-_%5E&%20%25%25",
url="https://authorized_only/test/%2a%2b%25/~-_^&%20%%",
method="POST",
match_headers={
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand All @@ -780,7 +780,7 @@ def test_aws_auth_path_percent_encode_s3(httpx_mock: HTTPXMock):
)

httpx_mock.add_response(
url="https://authorized_only/test/%2a%2b%25/~-_%5E&%20%25%25",
url="https://authorized_only/test/%2a%2b%25/~-_^& %%",
method="POST",
match_headers={
"x-amz-content-sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,18 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid(
opened_url="https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F",
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b",
)
httpx_mock.add_response(
method="POST",
url="https://testserver.okta-emea.com/oauth2/default/v1/token",
json={
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": "0",
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter": "example_value",
},
match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
)

httpx_mock.add_response(
url="https://authorized_only",
Expand Down Expand Up @@ -423,6 +435,13 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp

tab.assert_success()

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA",
},
)
# expect Bearer token to remain the same
async with httpx.AsyncClient() as client:
await client.get("https://authorized_only", auth=auth)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,18 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid(
opened_url="https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F",
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b",
)
httpx_mock.add_response(
method="POST",
url="https://testserver.okta-emea.com/oauth2/default/v1/token",
json={
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": "0",
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter": "example_value",
},
match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
)

httpx_mock.add_response(
url="https://authorized_only",
Expand Down Expand Up @@ -413,6 +425,13 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired(

tab.assert_success()

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA",
},
)
# expect Bearer token to remain the same
with httpx.Client() as client:
client.get("https://authorized_only", auth=auth)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,26 @@ async def test_oauth2_authorization_code_flow_is_able_to_reuse_client(
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5",
)

httpx_mock.add_response(
method="POST",
url="https://provide_access_token",
json={
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": 10,
"example_parameter": "example_value",
},
match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
match_headers={"x-test": "Test value"},
)

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA",
},
)
async with httpx.AsyncClient() as client:
await client.get("https://authorized_only", auth=auth)

Expand Down Expand Up @@ -519,6 +539,18 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid(
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5",
)

httpx_mock.add_response(
method="POST",
url="https://provide_access_token",
json={
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": "0",
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter": "example_value",
},
match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
)
httpx_mock.add_response(
url="https://authorized_only",
method="GET",
Expand Down Expand Up @@ -570,6 +602,13 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp

tab.assert_success()

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA",
},
)
# expect Bearer token to remain the same
async with httpx.AsyncClient() as client:
await client.get("https://authorized_only", auth=auth)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,26 @@ def test_oauth2_authorization_code_flow_is_able_to_reuse_client(
opened_url="https://provide_code?response_type=code&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F",
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5",
)
httpx_mock.add_response(
method="POST",
url="https://provide_access_token",
json={
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": 10,
"example_parameter": "example_value",
},
match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
match_headers={"x-test": "Test value"},
)

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA",
},
)

with httpx.Client() as client:
client.get("https://authorized_only", auth=auth)
Expand Down Expand Up @@ -507,6 +527,18 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid(
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=ce9c755b41b5e3c5b64c70598715d5de271023a53f39a67a70215d265d11d2bfb6ef6e9c701701e998e69cbdbf2cee29fd51d2a950aa05f59a20cf4a646099d5",
)

httpx_mock.add_response(
method="POST",
url="https://provide_access_token",
json={
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": "0",
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter": "example_value",
},
match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
)
httpx_mock.add_response(
url="https://authorized_only",
method="GET",
Expand Down Expand Up @@ -557,6 +589,13 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired(

tab.assert_success()

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA",
},
)
# expect Bearer token to remain the same
with httpx.Client() as client:
client.get("https://authorized_only", auth=auth)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,12 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid(
opened_url="https://wakatime.com/oauth/authorize?client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F",
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a",
)
httpx_mock.add_response(
method="POST",
url="https://wakatime.com/oauth/token",
html="access_token=waka_tok_12345&token_type=bearer&expires_in=0&refresh_token=waka_ref_12345&scope=email&example_parameter=example_value",
match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
)

httpx_mock.add_response(
url="https://authorized_only",
Expand Down Expand Up @@ -457,6 +463,13 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp

tab.assert_success()

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer waka_tok_12345",
},
)
# expect Bearer token to remain the same
async with httpx.AsyncClient() as client:
await client.get("https://authorized_only", auth=auth)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,12 @@ def test_oauth2_authorization_code_flow_refresh_token_invalid(
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5d0adb208bdbecaf5cfb6de0bf4ba0aea52986f3fc5ea7bc30c4b2db449c17e5c9d15f9a3926476cdaf1c72e9f73c7cfdc624dde0187c38d8c6b04532770df2a",
)

httpx_mock.add_response(
method="POST",
url="https://wakatime.com/oauth/token",
html="access_token=waka_tok_12345&token_type=bearer&expires_in=0&refresh_token=waka_ref_12345&scope=email&example_parameter=example_value",
match_content=b"grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&client_id=jPJQV0op6Pu3b66MWDi8b1wD&client_secret=waka_sec_0c4MBGeR9LN74LzV5uelF9SgeQ32CqfeWpIuieneBbsL57dAAlqqJWDiVDJOlsSx61pVwHMKlsb3uMvU&scope=email&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
)
httpx_mock.add_response(
url="https://authorized_only",
method="GET",
Expand Down Expand Up @@ -445,6 +451,13 @@ def test_oauth2_authorization_code_flow_refresh_token_access_token_not_expired(

tab.assert_success()

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer waka_tok_12345",
},
)
# expect Bearer token to remain the same
with httpx.Client() as client:
client.get("https://authorized_only", auth=auth)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,18 @@ async def test_oauth2_authorization_code_flow_refresh_token_invalid(
opened_url="https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256",
reply_url="http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b",
)
httpx_mock.add_response(
method="POST",
url="https://testserver.okta-emea.com/oauth2/default/v1/token",
json={
"access_token": "2YotnFZFEjr1zCsicMWpAA",
"token_type": "example",
"expires_in": "0",
"refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter": "example_value",
},
match_content=b"code_verifier=MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA",
)

httpx_mock.add_response(
url="https://authorized_only",
Expand Down Expand Up @@ -423,6 +435,13 @@ async def test_oauth2_authorization_code_flow_refresh_token_access_token_not_exp

tab.assert_success()

httpx_mock.add_response(
url="https://authorized_only",
method="GET",
match_headers={
"Authorization": "Bearer 2YotnFZFEjr1zCsicMWpAA",
},
)
# expect Bearer token to remain the same
async with httpx.AsyncClient() as client:
await client.get("https://authorized_only", auth=auth)
Expand Down
Loading

0 comments on commit fada249

Please sign in to comment.