Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.

Commit a209819

Browse files
author
Jon Wayne Parrott
authored
Fix gRPC to call credentials.before_request (#116)
1 parent 09568fd commit a209819

5 files changed

Lines changed: 46 additions & 23 deletions

File tree

google/auth/credentials.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,9 @@ def before_request(self, request, method, url, headers):
104104
Args:
105105
request (google.auth.transport.Request): The object used to make
106106
HTTP requests.
107-
method (str): The request's HTTP method.
108-
url (str): The request's URI.
107+
method (str): The request's HTTP method or the RPC method being
108+
invoked.
109+
url (str): The request's URI or the RPC service's URI.
109110
headers (Mapping): The request's headers.
110111
"""
111112
# pylint: disable=unused-argument

google/auth/transport/grpc.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from __future__ import absolute_import
1818

1919
import grpc
20+
import six
2021

2122

2223
class AuthMetadataPlugin(grpc.AuthMetadataPlugin):
@@ -40,19 +41,21 @@ def __init__(self, credentials, request):
4041
self._credentials = credentials
4142
self._request = request
4243

43-
def _get_authorization_headers(self):
44+
def _get_authorization_headers(self, context):
4445
"""Gets the authorization headers for a request.
4546
4647
Returns:
4748
Sequence[Tuple[str, str]]: A list of request headers (key, value)
4849
to add to the request.
4950
"""
50-
if self._credentials.expired or not self._credentials.valid:
51-
self._credentials.refresh(self._request)
51+
headers = {}
52+
self._credentials.before_request(
53+
self._request,
54+
context.method_name,
55+
context.service_url,
56+
headers)
5257

53-
return [
54-
('authorization', 'Bearer {}'.format(self._credentials.token))
55-
]
58+
return list(six.iteritems(headers))
5659

5760
def __call__(self, context, callback):
5861
"""Passes authorization metadata into the given callback.
@@ -62,7 +65,7 @@ def __call__(self, context, callback):
6265
callback (grpc.AuthMetadataPluginCallback): The callback that will
6366
be invoked to pass in the authorization metadata.
6467
"""
65-
callback(self._get_authorization_headers(), None)
68+
callback(self._get_authorization_headers(context), None)
6669

6770

6871
def secure_authorized_channel(

system_tests/test_grpc.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,40 @@
1515
import google.auth
1616
import google.auth.credentials
1717
import google.auth.transport.grpc
18-
from google.cloud.gapic.pubsub.v1 import publisher_api
18+
from google.cloud.gapic.pubsub.v1 import publisher_client
1919

2020

21-
def test_grpc_request(http_request):
21+
def test_grpc_request_with_regular_credentials(http_request):
2222
credentials, project_id = google.auth.default()
2323
credentials = google.auth.credentials.with_scopes_if_required(
2424
credentials, ['https://www.googleapis.com/auth/pubsub'])
2525

26-
target = '{}:{}'.format(
27-
publisher_api.PublisherApi.SERVICE_ADDRESS,
28-
publisher_api.PublisherApi.DEFAULT_SERVICE_PORT)
26+
channel = google.auth.transport.grpc.secure_authorized_channel(
27+
credentials,
28+
http_request,
29+
publisher_client.PublisherClient.SERVICE_ADDRESS)
30+
31+
# Create a pub/sub client.
32+
client = publisher_client.PublisherClient(channel=channel)
33+
34+
# list the topics and drain the iterator to test that an authorized API
35+
# call works.
36+
list_topics_iter = client.list_topics(
37+
project='projects/{}'.format(project_id))
38+
list(list_topics_iter)
39+
40+
41+
def test_grpc_request_with_jwt_credentials(http_request):
42+
credentials, project_id = google.auth.default()
43+
credentials = credentials.to_jwt_credentials()
2944

3045
channel = google.auth.transport.grpc.secure_authorized_channel(
31-
credentials, http_request, target)
46+
credentials,
47+
http_request,
48+
publisher_client.PublisherClient.SERVICE_ADDRESS)
3249

3350
# Create a pub/sub client.
34-
client = publisher_api.PublisherApi(channel=channel)
51+
client = publisher_client.PublisherClient(channel=channel)
3552

3653
# list the topics and drain the iterator to test that an authorized API
3754
# call works.

tests/transport/test_grpc.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
import mock
15+
import datetime
1616

17+
import mock
1718
import pytest
1819

20+
from google.auth import credentials
1921
try:
2022
import google.auth.transport.grpc
2123
HAS_GRPC = True
@@ -26,11 +28,11 @@
2628
pytestmark = pytest.mark.skipif(not HAS_GRPC, reason='gRPC is unavailable.')
2729

2830

29-
class MockCredentials(object):
31+
class MockCredentials(credentials.Credentials):
3032
def __init__(self, token='token'):
33+
super(MockCredentials, self).__init__()
3134
self.token = token
32-
self.valid = True
33-
self.expired = False
35+
self.expiry = None
3436

3537
def refresh(self, request):
3638
self.token += '1'
@@ -54,7 +56,7 @@ def test_call_no_refresh(self):
5456

5557
def test_call_refresh(self):
5658
credentials = MockCredentials()
57-
credentials.expired = True
59+
credentials.expiry = datetime.datetime.min
5860
request = mock.Mock()
5961

6062
plugin = google.auth.transport.grpc.AuthMetadataPlugin(

tox.ini

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ commands =
3333
deps =
3434
{[testenv]deps}
3535
nox-automation
36-
gapic-google-pubsub-v1==0.11.1
36+
gapic-google-cloud-pubsub-v1==0.15.0
3737
passenv =
3838
SKIP_APP_ENGINE_SYSTEM_TEST
3939
CLOUD_SDK_ROOT
@@ -46,7 +46,7 @@ commands =
4646
deps =
4747
{[testenv]deps}
4848
nox-automation
49-
gapic-google-pubsub-v1==0.11.1
49+
gapic-google-cloud-pubsub-v1==0.15.0
5050
passenv =
5151
SKIP_APP_ENGINE_SYSTEM_TEST
5252
CLOUD_SDK_ROOT

0 commit comments

Comments
 (0)