Skip to content

Commit

Permalink
fix: Make external_account resistant to string type 'expires_in' resp…
Browse files Browse the repository at this point in the history
…onses from non-compliant services (#1379)

Make external_account resistant to string type 'expires_in' responses from non-compliant services.

This is to complete [#1208](https://github.com/googleapis/google-auth-library-python/pull/1208/).

A client run into this error.
  • Loading branch information
duzun committed Sep 6, 2023
1 parent 7d453dc commit 01d3770
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 4 deletions.
9 changes: 8 additions & 1 deletion google/auth/external_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,14 @@ def refresh(self, request):
additional_headers=additional_headers,
)
self.token = response_data.get("access_token")
lifetime = datetime.timedelta(seconds=response_data.get("expires_in"))
expires_in = response_data.get("expires_in")
# Some services do not respect the OAUTH2.0 RFC and send expires_in as a
# JSON String.
if isinstance(expires_in, str):
expires_in = int(expires_in)

lifetime = datetime.timedelta(seconds=expires_in)

self.expiry = now + lifetime

@_helpers.copy_docstring(credentials.CredentialsWithQuotaProject)
Expand Down
Binary file modified system_tests/secrets.tar.enc
Binary file not shown.
7 changes: 4 additions & 3 deletions tests/test_external_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,19 +625,20 @@ def test_is_workforce_pool_with_users_and_impersonation(self, audience):
# Even though impersonation is used, is_workforce_pool should still return True.
assert credentials.is_workforce_pool is True

@pytest.mark.parametrize("mock_expires_in", [2800, "2800"])
@mock.patch(
"google.auth.metrics.python_and_auth_lib_version",
return_value=LANG_LIBRARY_METRICS_HEADER_VALUE,
)
@mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min)
def test_refresh_without_client_auth_success(
self, unused_utcnow, mock_auth_lib_value
self, unused_utcnow, mock_auth_lib_value, mock_expires_in
):
response = self.SUCCESS_RESPONSE.copy()
# Test custom expiration to confirm expiry is set correctly.
response["expires_in"] = 2800
response["expires_in"] = mock_expires_in
expected_expiry = datetime.datetime.min + datetime.timedelta(
seconds=response["expires_in"]
seconds=int(mock_expires_in)
)
headers = {
"Content-Type": "application/x-www-form-urlencoded",
Expand Down

0 comments on commit 01d3770

Please sign in to comment.