From 30a57c5d5ccf5d3394fbe85d00f28712a6430522 Mon Sep 17 00:00:00 2001 From: Chaoren Liu Date: Fri, 25 Jun 2021 13:29:20 -0400 Subject: [PATCH 1/7] Service account can use a private token endpoint in Private Service Connect --- google/oauth2/service_account.py | 23 ++++++++-- tests/oauth2/test_service_account.py | 65 ++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/google/oauth2/service_account.py b/google/oauth2/service_account.py index dd3658994..40a77485e 100644 --- a/google/oauth2/service_account.py +++ b/google/oauth2/service_account.py @@ -125,6 +125,7 @@ def __init__( signer, service_account_email, token_uri, + private_token_uri=None, scopes=None, default_scopes=None, subject=None, @@ -142,6 +143,8 @@ def __init__( default_scopes (Sequence[str]): Default scopes passed by a Google client library. Use 'scopes' for user-defined scopes. token_uri (str): The OAuth 2.0 Token URI. + private_token_uri (str): The Token URI in a Private Service Connect + network. subject (str): For domain-wide delegation, the email address of the user to for which to request delegated access. project_id (str): Project ID associated with the service account @@ -168,6 +171,7 @@ def __init__( self._project_id = project_id self._quota_project_id = quota_project_id self._token_uri = token_uri + self._private_token_uri = private_token_uri self._always_use_jwt_access = always_use_jwt_access self._jwt_credentials = None @@ -266,6 +270,7 @@ def with_scopes(self, scopes, default_scopes=None): scopes=scopes, default_scopes=default_scopes, token_uri=self._token_uri, + private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -289,6 +294,7 @@ def with_always_use_jwt_access(self, always_use_jwt_access): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, + private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -312,6 +318,7 @@ def with_subject(self, subject): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, + private_token_uri=self._private_token_uri, subject=subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -340,6 +347,7 @@ def with_claims(self, additional_claims): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, + private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -356,6 +364,7 @@ def with_quota_project(self, quota_project_id): default_scopes=self._default_scopes, scopes=self._scopes, token_uri=self._token_uri, + private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=quota_project_id, @@ -404,9 +413,8 @@ def refresh(self, request): self.expiry = self._jwt_credentials.expiry else: assertion = self._make_authorization_grant_assertion() - access_token, expiry, _ = _client.jwt_grant( - request, self._token_uri, assertion - ) + token_uri = self._private_token_uri or self._token_uri + access_token, expiry, _ = _client.jwt_grant(request, token_uri, assertion) self.token = access_token self.expiry = expiry @@ -503,6 +511,7 @@ def __init__( service_account_email, token_uri, target_audience, + private_token_uri=None, additional_claims=None, quota_project_id=None, ): @@ -514,6 +523,8 @@ def __init__( target_audience (str): The intended audience for these credentials, used when requesting the ID Token. The ID Token's ``aud`` claim will be set to this string. + private_token_uri (str): The Token URI in a Private Service Connect + network. additional_claims (Mapping[str, str]): Any additional claims for the JWT assertion used in the authorization grant. quota_project_id (Optional[str]): The project ID used for quota and billing. @@ -526,6 +537,7 @@ def __init__( self._signer = signer self._service_account_email = service_account_email self._token_uri = token_uri + self._private_token_uri = private_token_uri self._target_audience = target_audience self._quota_project_id = quota_project_id @@ -609,6 +621,7 @@ def with_target_audience(self, target_audience): service_account_email=self._service_account_email, token_uri=self._token_uri, target_audience=target_audience, + private_token_uri=self._private_token_uri, additional_claims=self._additional_claims.copy(), quota_project_id=self.quota_project_id, ) @@ -620,6 +633,7 @@ def with_quota_project(self, quota_project_id): service_account_email=self._service_account_email, token_uri=self._token_uri, target_audience=self._target_audience, + private_token_uri=self._private_token_uri, additional_claims=self._additional_claims.copy(), quota_project_id=quota_project_id, ) @@ -658,8 +672,9 @@ def _make_authorization_grant_assertion(self): @_helpers.copy_docstring(credentials.Credentials) def refresh(self, request): assertion = self._make_authorization_grant_assertion() + token_uri = self._private_token_uri or self._token_uri access_token, expiry, _ = _client.id_token_jwt_grant( - request, self._token_uri, assertion + request, token_uri, assertion ) self.token = access_token self.expiry = expiry diff --git a/tests/oauth2/test_service_account.py b/tests/oauth2/test_service_account.py index 5852d3714..2725dac05 100644 --- a/tests/oauth2/test_service_account.py +++ b/tests/oauth2/test_service_account.py @@ -47,6 +47,7 @@ class TestCredentials(object): SERVICE_ACCOUNT_EMAIL = "service-account@example.com" TOKEN_URI = "https://example.com/oauth2/token" + PRIVATE_TOKEN_URI = "https://another-example.com/oauth2/token" @classmethod def make_credentials(cls): @@ -185,6 +186,14 @@ def test__make_authorization_grant_assertion_subject(self): payload = jwt.decode(token, PUBLIC_CERT_BYTES) assert payload["sub"] == subject + def test__make_authorization_grant_assertion_private_token_uri(self): + credentials = self.make_credentials() + credentials._private_token_uri = self.PRIVATE_TOKEN_URI + + token=credentials._make_authorization_grant_assertion() + payload = jwt.decode(token, PUBLIC_CERT_BYTES) + assert payload['aud'] == credentials._token_uri + def test_apply_with_quota_project_id(self): credentials = service_account.Credentials( SIGNER, @@ -322,6 +331,30 @@ def test_refresh_success(self, jwt_grant): # expired) assert credentials.valid + @mock.patch("google.oauth2._client.jwt_grant", autospec=True) + def test_refresh_private_token_uri(self, jwt_grant): + credentials = self.make_credentials() + credentials._private_token_uri = self.PRIVATE_TOKEN_URI + request = mock.create_autospec(transport.Request, instance=True) + token = "token" + jwt_grant.return_value = ( + token, + _helpers.utcnow() + datetime.timedelta(seconds=500), + {}, + ) + + # Refresh credentials + credentials.refresh(request) + + # Check jwt grant call. + assert jwt_grant.called + + _, token_uri, assertion = jwt_grant.call_args[0] + assert token_uri == credentials._private_token_uri + + payload = jwt.decode(assertion, PUBLIC_CERT_BYTES) + assert payload['aud'] == credentials._token_uri + @mock.patch("google.oauth2._client.jwt_grant", autospec=True) def test_before_request_refreshes(self, jwt_grant): credentials = self.make_credentials() @@ -375,6 +408,7 @@ def test_refresh_with_jwt_credentials(self, make_jwt): class TestIDTokenCredentials(object): SERVICE_ACCOUNT_EMAIL = "service-account@example.com" TOKEN_URI = "https://example.com/oauth2/token" + PRIVATE_TOKEN_URI = "https://another-example.com/oauth2/token" TARGET_AUDIENCE = "https://example.com" @classmethod @@ -443,6 +477,13 @@ def test__make_authorization_grant_assertion(self): assert payload["aud"] == self.TOKEN_URI assert payload["target_audience"] == self.TARGET_AUDIENCE + def test__make_authorization_grant_assertion_private_token_uri(self): + credentials = self.make_credentials() + credentials._private_token_uri = self.PRIVATE_TOKEN_URI + token = credentials._make_authorization_grant_assertion() + payload = jwt.decode(token, PUBLIC_CERT_BYTES) + assert payload["aud"] == self.TOKEN_URI + @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True) def test_refresh_success(self, id_token_jwt_grant): credentials = self.make_credentials() @@ -474,6 +515,30 @@ def test_refresh_success(self, id_token_jwt_grant): # expired) assert credentials.valid + @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True) + def test_refresh_private_token_uri(self, id_token_jwt_grant): + credentials = self.make_credentials() + credentials._private_token_uri = self.PRIVATE_TOKEN_URI + token = "token" + id_token_jwt_grant.return_value = ( + token, + _helpers.utcnow() + datetime.timedelta(seconds=500), + {}, + ) + request = mock.create_autospec(transport.Request, instance=True) + + # Refresh credentials + credentials.refresh(request) + + # Check jwt grant call. + assert id_token_jwt_grant.called + + _, token_uri, assertion = id_token_jwt_grant.call_args[0] + assert token_uri == credentials._private_token_uri + payload = jwt.decode(assertion, PUBLIC_CERT_BYTES) + payload['aud'] = credentials._token_uri + + @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True) def test_before_request_refreshes(self, id_token_jwt_grant): credentials = self.make_credentials() From 6645b67e6d2f8771417c8ca19bf68c112f3b8127 Mon Sep 17 00:00:00 2001 From: Chaoren Liu Date: Fri, 25 Jun 2021 13:33:19 -0400 Subject: [PATCH 2/7] Fix format issue --- google/oauth2/service_account.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/google/oauth2/service_account.py b/google/oauth2/service_account.py index 40a77485e..cf862b78c 100644 --- a/google/oauth2/service_account.py +++ b/google/oauth2/service_account.py @@ -414,7 +414,9 @@ def refresh(self, request): else: assertion = self._make_authorization_grant_assertion() token_uri = self._private_token_uri or self._token_uri - access_token, expiry, _ = _client.jwt_grant(request, token_uri, assertion) + access_token, expiry, _ = _client.jwt_grant( + request, token_uri, assertion + ) self.token = access_token self.expiry = expiry From 596b248a7b538266aed6ea8a0e67772e53dda1dc Mon Sep 17 00:00:00 2001 From: Chaoren Liu Date: Fri, 25 Jun 2021 15:55:49 -0400 Subject: [PATCH 3/7] Reformat to be style compliant --- google/oauth2/service_account.py | 4 +--- tests/oauth2/test_service_account.py | 9 ++++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/google/oauth2/service_account.py b/google/oauth2/service_account.py index cf862b78c..40a77485e 100644 --- a/google/oauth2/service_account.py +++ b/google/oauth2/service_account.py @@ -414,9 +414,7 @@ def refresh(self, request): else: assertion = self._make_authorization_grant_assertion() token_uri = self._private_token_uri or self._token_uri - access_token, expiry, _ = _client.jwt_grant( - request, token_uri, assertion - ) + access_token, expiry, _ = _client.jwt_grant(request, token_uri, assertion) self.token = access_token self.expiry = expiry diff --git a/tests/oauth2/test_service_account.py b/tests/oauth2/test_service_account.py index 2725dac05..75fc419ef 100644 --- a/tests/oauth2/test_service_account.py +++ b/tests/oauth2/test_service_account.py @@ -190,9 +190,9 @@ def test__make_authorization_grant_assertion_private_token_uri(self): credentials = self.make_credentials() credentials._private_token_uri = self.PRIVATE_TOKEN_URI - token=credentials._make_authorization_grant_assertion() + token = credentials._make_authorization_grant_assertion() payload = jwt.decode(token, PUBLIC_CERT_BYTES) - assert payload['aud'] == credentials._token_uri + assert payload["aud"] == credentials._token_uri def test_apply_with_quota_project_id(self): credentials = service_account.Credentials( @@ -353,7 +353,7 @@ def test_refresh_private_token_uri(self, jwt_grant): assert token_uri == credentials._private_token_uri payload = jwt.decode(assertion, PUBLIC_CERT_BYTES) - assert payload['aud'] == credentials._token_uri + assert payload["aud"] == credentials._token_uri @mock.patch("google.oauth2._client.jwt_grant", autospec=True) def test_before_request_refreshes(self, jwt_grant): @@ -536,8 +536,7 @@ def test_refresh_private_token_uri(self, id_token_jwt_grant): _, token_uri, assertion = id_token_jwt_grant.call_args[0] assert token_uri == credentials._private_token_uri payload = jwt.decode(assertion, PUBLIC_CERT_BYTES) - payload['aud'] = credentials._token_uri - + payload["aud"] = credentials._token_uri @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True) def test_before_request_refreshes(self, id_token_jwt_grant): From e5217c12537495868132c263a9728828974ad5f0 Mon Sep 17 00:00:00 2001 From: Chaoren Liu Date: Fri, 2 Jul 2021 11:25:26 -0400 Subject: [PATCH 4/7] Hardcode the aud to be https://oauth2.googleapis.com/token --- google/oauth2/service_account.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/google/oauth2/service_account.py b/google/oauth2/service_account.py index 40a77485e..f12ce04cb 100644 --- a/google/oauth2/service_account.py +++ b/google/oauth2/service_account.py @@ -80,6 +80,7 @@ from google.oauth2 import _client _DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds +_GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token" class Credentials( @@ -125,7 +126,6 @@ def __init__( signer, service_account_email, token_uri, - private_token_uri=None, scopes=None, default_scopes=None, subject=None, @@ -143,8 +143,6 @@ def __init__( default_scopes (Sequence[str]): Default scopes passed by a Google client library. Use 'scopes' for user-defined scopes. token_uri (str): The OAuth 2.0 Token URI. - private_token_uri (str): The Token URI in a Private Service Connect - network. subject (str): For domain-wide delegation, the email address of the user to for which to request delegated access. project_id (str): Project ID associated with the service account @@ -171,7 +169,6 @@ def __init__( self._project_id = project_id self._quota_project_id = quota_project_id self._token_uri = token_uri - self._private_token_uri = private_token_uri self._always_use_jwt_access = always_use_jwt_access self._jwt_credentials = None @@ -270,7 +267,6 @@ def with_scopes(self, scopes, default_scopes=None): scopes=scopes, default_scopes=default_scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -294,7 +290,6 @@ def with_always_use_jwt_access(self, always_use_jwt_access): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -318,7 +313,6 @@ def with_subject(self, subject): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -347,7 +341,6 @@ def with_claims(self, additional_claims): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -364,7 +357,6 @@ def with_quota_project(self, quota_project_id): default_scopes=self._default_scopes, scopes=self._scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=quota_project_id, @@ -391,7 +383,7 @@ def _make_authorization_grant_assertion(self): # The issuer must be the service account email. "iss": self._service_account_email, # The audience must be the auth token endpoint's URI - "aud": self._token_uri, + "aud": _GOOGLE_OAUTH2_TOKEN_ENDPOINT, "scope": _helpers.scopes_to_string(self._scopes or ()), } @@ -413,8 +405,9 @@ def refresh(self, request): self.expiry = self._jwt_credentials.expiry else: assertion = self._make_authorization_grant_assertion() - token_uri = self._private_token_uri or self._token_uri - access_token, expiry, _ = _client.jwt_grant(request, token_uri, assertion) + access_token, expiry, _ = _client.jwt_grant( + request, self._token_uri, assertion + ) self.token = access_token self.expiry = expiry @@ -511,7 +504,6 @@ def __init__( service_account_email, token_uri, target_audience, - private_token_uri=None, additional_claims=None, quota_project_id=None, ): @@ -523,8 +515,6 @@ def __init__( target_audience (str): The intended audience for these credentials, used when requesting the ID Token. The ID Token's ``aud`` claim will be set to this string. - private_token_uri (str): The Token URI in a Private Service Connect - network. additional_claims (Mapping[str, str]): Any additional claims for the JWT assertion used in the authorization grant. quota_project_id (Optional[str]): The project ID used for quota and billing. @@ -657,7 +647,7 @@ def _make_authorization_grant_assertion(self): # The issuer must be the service account email. "iss": self.service_account_email, # The audience must be the auth token endpoint's URI - "aud": self._token_uri, + "aud": _GOOGLE_OAUTH2_TOKEN_ENDPOINT, # The target audience specifies which service the ID token is # intended for. "target_audience": self._target_audience, @@ -672,9 +662,8 @@ def _make_authorization_grant_assertion(self): @_helpers.copy_docstring(credentials.Credentials) def refresh(self, request): assertion = self._make_authorization_grant_assertion() - token_uri = self._private_token_uri or self._token_uri access_token, expiry, _ = _client.id_token_jwt_grant( - request, token_uri, assertion + request, self._token_uri, assertion ) self.token = access_token self.expiry = expiry From 725964495cdfe3dd7a89d323eac932dd96b163b7 Mon Sep 17 00:00:00 2001 From: Chaoren Liu Date: Fri, 2 Jul 2021 11:25:26 -0400 Subject: [PATCH 5/7] Hardcode the aud to be https://oauth2.googleapis.com/token --- google/oauth2/service_account.py | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/google/oauth2/service_account.py b/google/oauth2/service_account.py index 40a77485e..f12ce04cb 100644 --- a/google/oauth2/service_account.py +++ b/google/oauth2/service_account.py @@ -80,6 +80,7 @@ from google.oauth2 import _client _DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds +_GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token" class Credentials( @@ -125,7 +126,6 @@ def __init__( signer, service_account_email, token_uri, - private_token_uri=None, scopes=None, default_scopes=None, subject=None, @@ -143,8 +143,6 @@ def __init__( default_scopes (Sequence[str]): Default scopes passed by a Google client library. Use 'scopes' for user-defined scopes. token_uri (str): The OAuth 2.0 Token URI. - private_token_uri (str): The Token URI in a Private Service Connect - network. subject (str): For domain-wide delegation, the email address of the user to for which to request delegated access. project_id (str): Project ID associated with the service account @@ -171,7 +169,6 @@ def __init__( self._project_id = project_id self._quota_project_id = quota_project_id self._token_uri = token_uri - self._private_token_uri = private_token_uri self._always_use_jwt_access = always_use_jwt_access self._jwt_credentials = None @@ -270,7 +267,6 @@ def with_scopes(self, scopes, default_scopes=None): scopes=scopes, default_scopes=default_scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -294,7 +290,6 @@ def with_always_use_jwt_access(self, always_use_jwt_access): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -318,7 +313,6 @@ def with_subject(self, subject): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -347,7 +341,6 @@ def with_claims(self, additional_claims): scopes=self._scopes, default_scopes=self._default_scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=self._quota_project_id, @@ -364,7 +357,6 @@ def with_quota_project(self, quota_project_id): default_scopes=self._default_scopes, scopes=self._scopes, token_uri=self._token_uri, - private_token_uri=self._private_token_uri, subject=self._subject, project_id=self._project_id, quota_project_id=quota_project_id, @@ -391,7 +383,7 @@ def _make_authorization_grant_assertion(self): # The issuer must be the service account email. "iss": self._service_account_email, # The audience must be the auth token endpoint's URI - "aud": self._token_uri, + "aud": _GOOGLE_OAUTH2_TOKEN_ENDPOINT, "scope": _helpers.scopes_to_string(self._scopes or ()), } @@ -413,8 +405,9 @@ def refresh(self, request): self.expiry = self._jwt_credentials.expiry else: assertion = self._make_authorization_grant_assertion() - token_uri = self._private_token_uri or self._token_uri - access_token, expiry, _ = _client.jwt_grant(request, token_uri, assertion) + access_token, expiry, _ = _client.jwt_grant( + request, self._token_uri, assertion + ) self.token = access_token self.expiry = expiry @@ -511,7 +504,6 @@ def __init__( service_account_email, token_uri, target_audience, - private_token_uri=None, additional_claims=None, quota_project_id=None, ): @@ -523,8 +515,6 @@ def __init__( target_audience (str): The intended audience for these credentials, used when requesting the ID Token. The ID Token's ``aud`` claim will be set to this string. - private_token_uri (str): The Token URI in a Private Service Connect - network. additional_claims (Mapping[str, str]): Any additional claims for the JWT assertion used in the authorization grant. quota_project_id (Optional[str]): The project ID used for quota and billing. @@ -657,7 +647,7 @@ def _make_authorization_grant_assertion(self): # The issuer must be the service account email. "iss": self.service_account_email, # The audience must be the auth token endpoint's URI - "aud": self._token_uri, + "aud": _GOOGLE_OAUTH2_TOKEN_ENDPOINT, # The target audience specifies which service the ID token is # intended for. "target_audience": self._target_audience, @@ -672,9 +662,8 @@ def _make_authorization_grant_assertion(self): @_helpers.copy_docstring(credentials.Credentials) def refresh(self, request): assertion = self._make_authorization_grant_assertion() - token_uri = self._private_token_uri or self._token_uri access_token, expiry, _ = _client.id_token_jwt_grant( - request, token_uri, assertion + request, self._token_uri, assertion ) self.token = access_token self.expiry = expiry From 5499faf18c0b23e2cc0861144f35db9eb74e3a4a Mon Sep 17 00:00:00 2001 From: Chaoren Liu Date: Fri, 2 Jul 2021 11:46:04 -0400 Subject: [PATCH 6/7] Revert the change in the test_service_account --- tests/oauth2/test_service_account.py | 64 ---------------------------- 1 file changed, 64 deletions(-) diff --git a/tests/oauth2/test_service_account.py b/tests/oauth2/test_service_account.py index 75fc419ef..5852d3714 100644 --- a/tests/oauth2/test_service_account.py +++ b/tests/oauth2/test_service_account.py @@ -47,7 +47,6 @@ class TestCredentials(object): SERVICE_ACCOUNT_EMAIL = "service-account@example.com" TOKEN_URI = "https://example.com/oauth2/token" - PRIVATE_TOKEN_URI = "https://another-example.com/oauth2/token" @classmethod def make_credentials(cls): @@ -186,14 +185,6 @@ def test__make_authorization_grant_assertion_subject(self): payload = jwt.decode(token, PUBLIC_CERT_BYTES) assert payload["sub"] == subject - def test__make_authorization_grant_assertion_private_token_uri(self): - credentials = self.make_credentials() - credentials._private_token_uri = self.PRIVATE_TOKEN_URI - - token = credentials._make_authorization_grant_assertion() - payload = jwt.decode(token, PUBLIC_CERT_BYTES) - assert payload["aud"] == credentials._token_uri - def test_apply_with_quota_project_id(self): credentials = service_account.Credentials( SIGNER, @@ -331,30 +322,6 @@ def test_refresh_success(self, jwt_grant): # expired) assert credentials.valid - @mock.patch("google.oauth2._client.jwt_grant", autospec=True) - def test_refresh_private_token_uri(self, jwt_grant): - credentials = self.make_credentials() - credentials._private_token_uri = self.PRIVATE_TOKEN_URI - request = mock.create_autospec(transport.Request, instance=True) - token = "token" - jwt_grant.return_value = ( - token, - _helpers.utcnow() + datetime.timedelta(seconds=500), - {}, - ) - - # Refresh credentials - credentials.refresh(request) - - # Check jwt grant call. - assert jwt_grant.called - - _, token_uri, assertion = jwt_grant.call_args[0] - assert token_uri == credentials._private_token_uri - - payload = jwt.decode(assertion, PUBLIC_CERT_BYTES) - assert payload["aud"] == credentials._token_uri - @mock.patch("google.oauth2._client.jwt_grant", autospec=True) def test_before_request_refreshes(self, jwt_grant): credentials = self.make_credentials() @@ -408,7 +375,6 @@ def test_refresh_with_jwt_credentials(self, make_jwt): class TestIDTokenCredentials(object): SERVICE_ACCOUNT_EMAIL = "service-account@example.com" TOKEN_URI = "https://example.com/oauth2/token" - PRIVATE_TOKEN_URI = "https://another-example.com/oauth2/token" TARGET_AUDIENCE = "https://example.com" @classmethod @@ -477,13 +443,6 @@ def test__make_authorization_grant_assertion(self): assert payload["aud"] == self.TOKEN_URI assert payload["target_audience"] == self.TARGET_AUDIENCE - def test__make_authorization_grant_assertion_private_token_uri(self): - credentials = self.make_credentials() - credentials._private_token_uri = self.PRIVATE_TOKEN_URI - token = credentials._make_authorization_grant_assertion() - payload = jwt.decode(token, PUBLIC_CERT_BYTES) - assert payload["aud"] == self.TOKEN_URI - @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True) def test_refresh_success(self, id_token_jwt_grant): credentials = self.make_credentials() @@ -515,29 +474,6 @@ def test_refresh_success(self, id_token_jwt_grant): # expired) assert credentials.valid - @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True) - def test_refresh_private_token_uri(self, id_token_jwt_grant): - credentials = self.make_credentials() - credentials._private_token_uri = self.PRIVATE_TOKEN_URI - token = "token" - id_token_jwt_grant.return_value = ( - token, - _helpers.utcnow() + datetime.timedelta(seconds=500), - {}, - ) - request = mock.create_autospec(transport.Request, instance=True) - - # Refresh credentials - credentials.refresh(request) - - # Check jwt grant call. - assert id_token_jwt_grant.called - - _, token_uri, assertion = id_token_jwt_grant.call_args[0] - assert token_uri == credentials._private_token_uri - payload = jwt.decode(assertion, PUBLIC_CERT_BYTES) - payload["aud"] = credentials._token_uri - @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True) def test_before_request_refreshes(self, id_token_jwt_grant): credentials = self.make_credentials() From 4353bc654b2c8d1b5025f61c1975407ebcee16c3 Mon Sep 17 00:00:00 2001 From: Chaoren Liu Date: Wed, 14 Jul 2021 10:41:07 -0400 Subject: [PATCH 7/7] Fix unit tests --- tests/oauth2/test_service_account.py | 4 ++-- tests_async/oauth2/test_service_account_async.py | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/oauth2/test_service_account.py b/tests/oauth2/test_service_account.py index 5852d3714..370438f48 100644 --- a/tests/oauth2/test_service_account.py +++ b/tests/oauth2/test_service_account.py @@ -167,7 +167,7 @@ def test__make_authorization_grant_assertion(self): token = credentials._make_authorization_grant_assertion() payload = jwt.decode(token, PUBLIC_CERT_BYTES) assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL - assert payload["aud"] == self.TOKEN_URI + assert payload["aud"] == service_account._GOOGLE_OAUTH2_TOKEN_ENDPOINT def test__make_authorization_grant_assertion_scoped(self): credentials = self.make_credentials() @@ -440,7 +440,7 @@ def test__make_authorization_grant_assertion(self): token = credentials._make_authorization_grant_assertion() payload = jwt.decode(token, PUBLIC_CERT_BYTES) assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL - assert payload["aud"] == self.TOKEN_URI + assert payload["aud"] == service_account._GOOGLE_OAUTH2_TOKEN_ENDPOINT assert payload["target_audience"] == self.TARGET_AUDIENCE @mock.patch("google.oauth2._client.id_token_jwt_grant", autospec=True) diff --git a/tests_async/oauth2/test_service_account_async.py b/tests_async/oauth2/test_service_account_async.py index 40794536c..3dce13d82 100644 --- a/tests_async/oauth2/test_service_account_async.py +++ b/tests_async/oauth2/test_service_account_async.py @@ -152,7 +152,10 @@ def test__make_authorization_grant_assertion(self): token = credentials._make_authorization_grant_assertion() payload = jwt.decode(token, test_service_account.PUBLIC_CERT_BYTES) assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL - assert payload["aud"] == self.TOKEN_URI + assert ( + payload["aud"] + == service_account.service_account._GOOGLE_OAUTH2_TOKEN_ENDPOINT + ) def test__make_authorization_grant_assertion_scoped(self): credentials = self.make_credentials() @@ -311,7 +314,10 @@ def test__make_authorization_grant_assertion(self): token = credentials._make_authorization_grant_assertion() payload = jwt.decode(token, test_service_account.PUBLIC_CERT_BYTES) assert payload["iss"] == self.SERVICE_ACCOUNT_EMAIL - assert payload["aud"] == self.TOKEN_URI + assert ( + payload["aud"] + == service_account.service_account._GOOGLE_OAUTH2_TOKEN_ENDPOINT + ) assert payload["target_audience"] == self.TARGET_AUDIENCE @mock.patch("google.oauth2._client_async.id_token_jwt_grant", autospec=True)