From d47d29ef307fbe96c744eb89983c4ae03130fdd8 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 28 Nov 2019 00:58:14 +0100
Subject: [PATCH 1/7] Avoid failure when building on master more than once
---
.travis.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index e7a8d22..8f2ddd3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -11,4 +11,5 @@ deploy:
provider: pypi
username: __token__
edge: true
- distributions: "sdist bdist_wheel"
\ No newline at end of file
+ distributions: "sdist bdist_wheel"
+ skip_existing: true
\ No newline at end of file
From e129a6fdfcfbe78c552b5ac131744a8e4b07be09 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 28 Nov 2019 01:06:02 +0100
Subject: [PATCH 2/7] Link to the travis-ci build and retrieve status
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 176f01d..d2ce498 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,10 @@
-
-
+
+
-
+
From 0659791149380e1dffe439d0d13d06d9c11ecbfb Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 28 Nov 2019 01:07:31 +0100
Subject: [PATCH 3/7] Update the number of test cases (while it's not retrieved
from travis-ci)
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index d2ce498..55e0797 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
-
+
From f95ecd833d52341ebe0e2c974d133577ae124dd9 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 28 Nov 2019 01:20:09 +0100
Subject: [PATCH 4/7] Ensure full coverage
---
.travis.yml | 2 +-
setup.py | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 8f2ddd3..686c11c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,7 @@ python:
install:
- pip install .[testing]
script:
- - pytest
+ - pytest --cov=requests_auth --cov-fail-under=100
deploy:
provider: pypi
username: __token__
diff --git a/setup.py b/setup.py
index ae20ee1..f723750 100644
--- a/setup.py
+++ b/setup.py
@@ -52,6 +52,8 @@
"pyjwt==1.*",
# Used to mock responses to requests
"pytest-responses==0.4.*",
+ # Used to check coverage
+ "pytest-cov==2.*",
]
},
python_requires=">=3.6",
From 77ef8d3d234fab08adac2ff6308faab736b472a2 Mon Sep 17 00:00:00 2001
From: bottoy
Date: Thu, 12 Dec 2019 15:12:40 +0100
Subject: [PATCH 5/7] Bug in ClientCredentials
Hi Colin,
We have a bug on line 68 => TypeError: unsupported type for timedelta seconds component: str
The casting to 'int' is not done so I propose to cast it explicitly to 'int'.
Works locally ;-)
Bram
---
requests_auth/oauth2_tokens.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/requests_auth/oauth2_tokens.py b/requests_auth/oauth2_tokens.py
index fc14c16..6d33dd8 100644
--- a/requests_auth/oauth2_tokens.py
+++ b/requests_auth/oauth2_tokens.py
@@ -65,7 +65,7 @@ def add_access_token(self, key: str, token: str, expires_in: int):
"""
expiry = datetime.datetime.utcnow().replace(
tzinfo=datetime.timezone.utc
- ) + datetime.timedelta(seconds=expires_in)
+ ) + datetime.timedelta(seconds=int(expires_in))
self._add_token(key, token, expiry.timestamp())
def _add_token(self, key: str, token: str, expiry: float):
From 3a52d66128597ecccf63ec9d991529adca40dba1 Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 12 Dec 2019 18:30:03 +0100
Subject: [PATCH 6/7] Reproduce failure due to expires_in sent as str
---
tests/test_oauth2_authorization_code_pkce.py | 35 ++++++++++++++++++++
tests/test_oauth2_client_credential.py | 21 ++++++++++++
tests/test_oauth2_client_credential_okta.py | 21 ++++++++++++
tests/test_oauth2_resource_owner_password.py | 25 ++++++++++++++
4 files changed, 102 insertions(+)
diff --git a/tests/test_oauth2_authorization_code_pkce.py b/tests/test_oauth2_authorization_code_pkce.py
index 0af7224..9a171f0 100644
--- a/tests/test_oauth2_authorization_code_pkce.py
+++ b/tests/test_oauth2_authorization_code_pkce.py
@@ -42,6 +42,41 @@ def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default(
)
+def test_expires_in_sent_as_str(
+ token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock
+):
+ monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63)
+ auth = requests_auth.OAuth2AuthorizationCodePKCE(
+ "http://provide_code", "http://provide_access_token"
+ )
+ tab = browser_mock.add_response(
+ opened_url="http://provide_code?response_type=code&state=163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de&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=163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de",
+ )
+ responses.add(
+ responses.POST,
+ "http://provide_access_token",
+ json={
+ "access_token": "2YotnFZFEjr1zCsicMWpAA",
+ "token_type": "example",
+ "expires_in": "3600",
+ "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
+ "example_parameter": "example_value",
+ },
+ )
+ assert (
+ get_header(responses, auth).get("Authorization")
+ == "Bearer 2YotnFZFEjr1zCsicMWpAA"
+ )
+ assert (
+ get_request(responses, "http://provide_access_token/").body
+ == "code_verifier=MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA"
+ )
+ tab.assert_success(
+ "You are now authenticated on 163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de. You may close this tab."
+ )
+
+
def test_nonce_is_sent_if_provided_in_authorization_url(
token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock
):
diff --git a/tests/test_oauth2_client_credential.py b/tests/test_oauth2_client_credential.py
index 4d71fac..10c8802 100644
--- a/tests/test_oauth2_client_credential.py
+++ b/tests/test_oauth2_client_credential.py
@@ -30,6 +30,27 @@ def test_oauth2_client_credentials_flow_token_is_sent_in_authorization_header_by
)
+def test_expires_in_sent_as_str(token_cache, responses: RequestsMock):
+ auth = requests_auth.OAuth2ClientCredentials(
+ "http://provide_access_token", client_id="test_user", client_secret="test_pwd"
+ )
+ responses.add(
+ responses.POST,
+ "http://provide_access_token",
+ json={
+ "access_token": "2YotnFZFEjr1zCsicMWpAA",
+ "token_type": "example",
+ "expires_in": "3600",
+ "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
+ "example_parameter": "example_value",
+ },
+ )
+ assert (
+ get_header(responses, auth).get("Authorization")
+ == "Bearer 2YotnFZFEjr1zCsicMWpAA"
+ )
+
+
def test_with_invalid_grant_request_no_json(token_cache, responses: RequestsMock):
auth = requests_auth.OAuth2ClientCredentials(
"http://provide_access_token", client_id="test_user", client_secret="test_pwd"
diff --git a/tests/test_oauth2_client_credential_okta.py b/tests/test_oauth2_client_credential_okta.py
index c1a0101..b9330d6 100644
--- a/tests/test_oauth2_client_credential_okta.py
+++ b/tests/test_oauth2_client_credential_okta.py
@@ -26,3 +26,24 @@ def test_okta_client_credentials_flow_token_is_sent_in_authorization_header_by_d
get_header(responses, auth).get("Authorization")
== "Bearer 2YotnFZFEjr1zCsicMWpAA"
)
+
+
+def test_expires_in_sent_as_str(token_cache, responses: RequestsMock):
+ auth = requests_auth.OktaClientCredentials(
+ "test_okta", client_id="test_user", client_secret="test_pwd"
+ )
+ responses.add(
+ responses.POST,
+ "https://test_okta/oauth2/default/v1/token",
+ json={
+ "access_token": "2YotnFZFEjr1zCsicMWpAA",
+ "token_type": "example",
+ "expires_in": "3600",
+ "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
+ "example_parameter": "example_value",
+ },
+ )
+ assert (
+ get_header(responses, auth).get("Authorization")
+ == "Bearer 2YotnFZFEjr1zCsicMWpAA"
+ )
diff --git a/tests/test_oauth2_resource_owner_password.py b/tests/test_oauth2_resource_owner_password.py
index 86d6b0f..852056e 100644
--- a/tests/test_oauth2_resource_owner_password.py
+++ b/tests/test_oauth2_resource_owner_password.py
@@ -34,6 +34,31 @@ def test_oauth2_password_credentials_flow_token_is_sent_in_authorization_header_
)
+def test_expires_in_sent_as_str(token_cache, responses: RequestsMock):
+ auth = requests_auth.OAuth2ResourceOwnerPasswordCredentials(
+ "http://provide_access_token", username="test_user", password="test_pwd"
+ )
+ responses.add(
+ responses.POST,
+ "http://provide_access_token",
+ json={
+ "access_token": "2YotnFZFEjr1zCsicMWpAA",
+ "token_type": "example",
+ "expires_in": "3600",
+ "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA",
+ "example_parameter": "example_value",
+ },
+ )
+ assert (
+ get_header(responses, auth).get("Authorization")
+ == "Bearer 2YotnFZFEjr1zCsicMWpAA"
+ )
+ assert (
+ get_request(responses, "http://provide_access_token/").body
+ == "grant_type=password&username=test_user&password=test_pwd"
+ )
+
+
def test_scope_is_sent_as_is_when_provided_as_str(token_cache, responses: RequestsMock):
auth = requests_auth.OAuth2ResourceOwnerPasswordCredentials(
"http://provide_access_token",
From 01d9500b6600a833b74f7369afaeb8b8dff551df Mon Sep 17 00:00:00 2001
From: Colin-b
Date: Thu, 12 Dec 2019 18:33:00 +0100
Subject: [PATCH 7/7] Report build status from master branch Bump version to
5.0.2 Keep number of tests up to date
---
CHANGELOG.md | 7 ++++++-
README.md | 4 ++--
requests_auth/version.py | 2 +-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e8f57bf..c378f6d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [5.0.2] - 2019-12-12
+### Fixed
+- Handle expires_in sent as str instead of int.
+
## [5.0.1] - 2019-11-28
### Added
- Allow to use & between authentication classes.
@@ -114,7 +118,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Public release
-[Unreleased]: https://github.com/Colin-b/requests_auth/compare/v5.0.1...HEAD
+[Unreleased]: https://github.com/Colin-b/requests_auth/compare/v5.0.2...HEAD
+[5.0.2]: https://github.com/Colin-b/requests_auth/compare/v5.0.1...v5.0.2
[5.0.1]: https://github.com/Colin-b/requests_auth/compare/v5.0.0...v5.0.1
[5.0.0]: https://github.com/Colin-b/requests_auth/compare/v4.1.0...v5.0.0
[4.1.0]: https://github.com/Colin-b/requests_auth/compare/v4.0.1...v4.1.0
diff --git a/README.md b/README.md
index 55e0797..9e5a981 100644
--- a/README.md
+++ b/README.md
@@ -2,10 +2,10 @@
-
+
-
+
diff --git a/requests_auth/version.py b/requests_auth/version.py
index f309563..5269aff 100644
--- a/requests_auth/version.py
+++ b/requests_auth/version.py
@@ -3,4 +3,4 @@
# Major should be incremented in case there is a breaking change. (eg: 2.5.8 -> 3.0.0)
# Minor should be incremented in case there is an enhancement. (eg: 2.5.8 -> 2.6.0)
# Patch should be incremented in case there is a bug fix. (eg: 2.5.8 -> 2.5.9)
-__version__ = "5.0.1"
+__version__ = "5.0.2"