Skip to content
This repository was archived by the owner on Mar 6, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions google/auth/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ def before_request(self, request, method, url, headers):
Args:
request (google.auth.transport.Request): The object used to make
HTTP requests.
method (str): The request's HTTP method.
url (str): The request's URI.
method (str): The request's HTTP method or the RPC method being
invoked.
url (str): The request's URI or the RPC service's URI.
headers (Mapping): The request's headers.
"""
# pylint: disable=unused-argument
Expand Down
17 changes: 10 additions & 7 deletions google/auth/transport/grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from __future__ import absolute_import

import grpc
import six


class AuthMetadataPlugin(grpc.AuthMetadataPlugin):
Expand All @@ -40,19 +41,21 @@ def __init__(self, credentials, request):
self._credentials = credentials
self._request = request

def _get_authorization_headers(self):
def _get_authorization_headers(self, context):
"""Gets the authorization headers for a request.

Returns:
Sequence[Tuple[str, str]]: A list of request headers (key, value)
to add to the request.
"""
if self._credentials.expired or not self._credentials.valid:
self._credentials.refresh(self._request)
headers = {}
self._credentials.before_request(
self._request,
context.method_name,
context.service_url,
headers)

return [
('authorization', 'Bearer {}'.format(self._credentials.token))
]
return list(six.iteritems(headers))

def __call__(self, context, callback):
"""Passes authorization metadata into the given callback.
Expand All @@ -62,7 +65,7 @@ def __call__(self, context, callback):
callback (grpc.AuthMetadataPluginCallback): The callback that will
be invoked to pass in the authorization metadata.
"""
callback(self._get_authorization_headers(), None)
callback(self._get_authorization_headers(context), None)


def secure_authorized_channel(
Expand Down
31 changes: 24 additions & 7 deletions system_tests/test_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,40 @@
import google.auth
import google.auth.credentials
import google.auth.transport.grpc
from google.cloud.gapic.pubsub.v1 import publisher_api
from google.cloud.gapic.pubsub.v1 import publisher_client


def test_grpc_request(http_request):
def test_grpc_request_with_regular_credentials(http_request):
credentials, project_id = google.auth.default()
credentials = google.auth.credentials.with_scopes_if_required(
credentials, ['https://www.googleapis.com/auth/pubsub'])

target = '{}:{}'.format(
publisher_api.PublisherApi.SERVICE_ADDRESS,
publisher_api.PublisherApi.DEFAULT_SERVICE_PORT)
channel = google.auth.transport.grpc.secure_authorized_channel(
credentials,
http_request,
publisher_client.PublisherClient.SERVICE_ADDRESS)

# Create a pub/sub client.
client = publisher_client.PublisherClient(channel=channel)

# list the topics and drain the iterator to test that an authorized API
# call works.
list_topics_iter = client.list_topics(
project='projects/{}'.format(project_id))
list(list_topics_iter)

This comment was marked as spam.

This comment was marked as spam.



def test_grpc_request_with_jwt_credentials(http_request):
credentials, project_id = google.auth.default()
credentials = credentials.to_jwt_credentials()

channel = google.auth.transport.grpc.secure_authorized_channel(
credentials, http_request, target)
credentials,
http_request,
publisher_client.PublisherClient.SERVICE_ADDRESS)

# Create a pub/sub client.
client = publisher_api.PublisherApi(channel=channel)
client = publisher_client.PublisherClient(channel=channel)

# list the topics and drain the iterator to test that an authorized API
# call works.
Expand Down
12 changes: 7 additions & 5 deletions tests/transport/test_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import mock
import datetime

import mock
import pytest

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


class MockCredentials(object):
class MockCredentials(credentials.Credentials):
def __init__(self, token='token'):
super(MockCredentials, self).__init__()
self.token = token
self.valid = True
self.expired = False
self.expiry = None

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

def test_call_refresh(self):
credentials = MockCredentials()
credentials.expired = True
credentials.expiry = datetime.datetime.min
request = mock.Mock()

plugin = google.auth.transport.grpc.AuthMetadataPlugin(
Expand Down
4 changes: 2 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ commands =
deps =
{[testenv]deps}
nox-automation
gapic-google-pubsub-v1==0.11.1
gapic-google-cloud-pubsub-v1==0.15.0
passenv =
SKIP_APP_ENGINE_SYSTEM_TEST
CLOUD_SDK_ROOT
Expand All @@ -46,7 +46,7 @@ commands =
deps =
{[testenv]deps}
nox-automation
gapic-google-pubsub-v1==0.11.1
gapic-google-cloud-pubsub-v1==0.15.0
passenv =
SKIP_APP_ENGINE_SYSTEM_TEST
CLOUD_SDK_ROOT
Expand Down