Skip to content

Commit 1eab897

Browse files
committed
Merge branch 'fcm-http2' into je-http2-client
2 parents a5aa585 + de87ba9 commit 1eab897

17 files changed

+160
-47
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ requests, code review feedback, and also pull requests.
4343

4444
## Supported Python Versions
4545

46-
We currently support Python 3.7+. However, Python 3.7 support is deprecated,
47-
and developers are strongly advised to use Python 3.8 or higher. Firebase
46+
We currently support Python 3.7+. However, Python 3.7 and Python 3.8 support is deprecated,
47+
and developers are strongly advised to use Python 3.9 or higher. Firebase
4848
Admin Python SDK is also tested on PyPy and
4949
[Google App Engine](https://cloud.google.com/appengine/) environments.
5050

firebase_admin/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
"""About information (version, etc) for Firebase Admin SDK."""
1616

17-
__version__ = '6.7.0'
17+
__version__ = '6.8.0'
1818
__title__ = 'firebase_admin'
1919
__author__ = 'Firebase'
2020
__license__ = 'Apache License 2.0'

firebase_admin/_http_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
DEFAULT_TIMEOUT_SECONDS = 120
5151

5252
METRICS_HEADERS = {
53-
'X-GOOG-API-CLIENT': _utils.get_metrics_header(),
53+
'x-goog-api-client': _utils.get_metrics_header(),
5454
}
5555

5656
class HttpClient:
@@ -88,7 +88,6 @@ def __init__(
8888

8989
if headers:
9090
self._session.headers.update(headers)
91-
self._session.headers.update(METRICS_HEADERS)
9291
if retries:
9392
self._session.mount('http://', requests.adapters.HTTPAdapter(max_retries=retries))
9493
self._session.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries))
@@ -132,6 +131,7 @@ class call this method to send HTTP requests out. Refer to
132131
"""
133132
if 'timeout' not in kwargs:
134133
kwargs['timeout'] = self.timeout
134+
kwargs.setdefault('headers', {}).update(METRICS_HEADERS)
135135
resp = self._session.request(method, self.base_url + url, **kwargs)
136136
resp.raise_for_status()
137137
return resp

firebase_admin/app_check.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class _AppCheckService:
5252
_jwks_client = None
5353

5454
_APP_CHECK_HEADERS = {
55-
'X-GOOG-API-CLIENT': _utils.get_metrics_header(),
55+
'x-goog-api-client': _utils.get_metrics_header(),
5656
}
5757

5858
def __init__(self, app):

firebase_admin/storage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class _StorageClient:
5656
"""Holds a Google Cloud Storage client instance."""
5757

5858
STORAGE_HEADERS = {
59-
'X-GOOG-API-CLIENT': _utils.get_metrics_header(),
59+
'x-goog-api-client': _utils.get_metrics_header(),
6060
}
6161

6262
def __init__(self, credentials, project, default_bucket):

tests/test_auth_providers.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ def _assert_request(request, expected_method, expected_url):
7575
assert request.method == expected_method
7676
assert request.url == expected_url
7777
assert request.headers['X-Client-Version'] == f'Python/Admin/{firebase_admin.__version__}'
78-
assert request.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
78+
expected_metrics_header = [
79+
_utils.get_metrics_header(),
80+
_utils.get_metrics_header() + ' mock-cred-metric-tag'
81+
]
82+
assert request.headers['x-goog-api-client'] in expected_metrics_header
7983

8084
class TestOIDCProviderConfig:
8185

tests/test_db.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ def _assert_request(self, request, expected_method, expected_url):
198198
assert request.url == expected_url
199199
assert request.headers['Authorization'] == 'Bearer mock-token'
200200
assert request.headers['User-Agent'] == db._USER_AGENT
201-
assert request.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
201+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
202+
assert request.headers['x-goog-api-client'] == expected_metrics_header
202203

203204
@pytest.mark.parametrize('data', valid_values)
204205
def test_get_value(self, data):
@@ -665,7 +666,8 @@ def _assert_request(self, request, expected_method, expected_url):
665666
assert request.url == expected_url
666667
assert request.headers['Authorization'] == 'Bearer mock-token'
667668
assert request.headers['User-Agent'] == db._USER_AGENT
668-
assert request.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
669+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
670+
assert request.headers['x-goog-api-client'] == expected_metrics_header
669671

670672
def test_get_value(self):
671673
ref = db.reference('/test')

tests/test_functions.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ def test_task_enqueue(self):
122122
assert recorder[0].url == _DEFAULT_REQUEST_URL
123123
assert recorder[0].headers['Content-Type'] == 'application/json'
124124
assert recorder[0].headers['Authorization'] == 'Bearer mock-token'
125-
assert recorder[0].headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
125+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
126+
assert recorder[0].headers['x-goog-api-client'] == expected_metrics_header
126127
assert task_id == 'test-task-id'
127128

128129
def test_task_enqueue_with_extension(self):
@@ -139,7 +140,8 @@ def test_task_enqueue_with_extension(self):
139140
assert recorder[0].url == _CLOUD_TASKS_URL + resource_name
140141
assert recorder[0].headers['Content-Type'] == 'application/json'
141142
assert recorder[0].headers['Authorization'] == 'Bearer mock-token'
142-
assert recorder[0].headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
143+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
144+
assert recorder[0].headers['x-goog-api-client'] == expected_metrics_header
143145
assert task_id == 'test-task-id'
144146

145147
def test_task_delete(self):
@@ -149,8 +151,8 @@ def test_task_delete(self):
149151
assert len(recorder) == 1
150152
assert recorder[0].method == 'DELETE'
151153
assert recorder[0].url == _DEFAULT_TASK_URL
152-
assert recorder[0].headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
153-
154+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
155+
assert recorder[0].headers['x-goog-api-client'] == expected_metrics_header
154156

155157
class TestTaskQueueOptions:
156158

tests/test_http_client.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,21 @@ def test_metrics_headers(self):
8686
assert len(recorder) == 1
8787
assert recorder[0].method == 'GET'
8888
assert recorder[0].url == _TEST_URL
89-
assert recorder[0].headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
89+
assert recorder[0].headers['x-goog-api-client'] == _utils.get_metrics_header()
90+
91+
def test_metrics_headers_with_credentials(self):
92+
client = _http_client.HttpClient(
93+
credential=testutils.MockGoogleCredential())
94+
assert client.session is not None
95+
recorder = self._instrument(client, 'body')
96+
resp = client.request('get', _TEST_URL)
97+
assert resp.status_code == 200
98+
assert resp.text == 'body'
99+
assert len(recorder) == 1
100+
assert recorder[0].method == 'GET'
101+
assert recorder[0].url == _TEST_URL
102+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
103+
assert recorder[0].headers['x-goog-api-client'] == expected_metrics_header
90104

91105
def test_credential(self):
92106
client = _http_client.HttpClient(

tests/test_instance_id.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ def _instrument_iid_service(self, app, status=200, payload='True'):
6868
def _assert_request(self, request, expected_method, expected_url):
6969
assert request.method == expected_method
7070
assert request.url == expected_url
71-
assert request.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
71+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
72+
assert request.headers['x-goog-api-client'] == expected_metrics_header
7273

7374
def _get_url(self, project_id, iid):
7475
return instance_id._IID_SERVICE_URL + 'project/{0}/instanceId/{1}'.format(project_id, iid)

tests/test_messaging.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,7 +1686,8 @@ def _assert_request(self, request, expected_method, expected_url, expected_body=
16861686
assert request.url == expected_url
16871687
assert request.headers['X-GOOG-API-FORMAT-VERSION'] == '2'
16881688
assert request.headers['X-FIREBASE-CLIENT'] == self._CLIENT_VERSION
1689-
assert request.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
1689+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
1690+
assert request.headers['x-goog-api-client'] == expected_metrics_header
16901691
if expected_body is None:
16911692
assert request.body is None
16921693
else:
@@ -2802,7 +2803,8 @@ def _assert_request(self, request, expected_method, expected_url):
28022803
assert request.method == expected_method
28032804
assert request.url == expected_url
28042805
assert request.headers['access_token_auth'] == 'true'
2805-
assert request.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
2806+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
2807+
assert request.headers['x-goog-api-client'] == expected_metrics_header
28062808

28072809
def _get_url(self, path):
28082810
return '{0}/{1}'.format(messaging._MessagingService.IID_URL, path)

tests/test_ml.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,8 @@ def _assert_request(request, expected_method, expected_url):
339339
assert request.method == expected_method
340340
assert request.url == expected_url
341341
assert request.headers['X-FIREBASE-CLIENT'] == f'fire-admin-python/{firebase_admin.__version__}'
342-
assert request.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
342+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
343+
assert request.headers['x-goog-api-client'] == expected_metrics_header
343344

344345
class _TestStorageClient:
345346
@staticmethod

tests/test_project_management.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -523,7 +523,8 @@ def _assert_request_is_correct(
523523
assert request.method == expected_method
524524
assert request.url == expected_url
525525
assert request.headers['X-Client-Version'] == f'Python/Admin/{firebase_admin.__version__}'
526-
assert request.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
526+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
527+
assert request.headers['x-goog-api-client'] == expected_metrics_header
527528
if expected_body is None:
528529
assert request.body is None
529530
else:

tests/test_tenant_mgt.py

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""Test cases for the firebase_admin.tenant_mgt module."""
1616

1717
import json
18+
import unittest.mock
1819
from urllib import parse
1920

2021
import pytest
@@ -29,6 +30,7 @@
2930
from firebase_admin import _utils
3031
from tests import testutils
3132
from tests import test_token_gen
33+
from tests.test_token_gen import MOCK_CURRENT_TIME, MOCK_CURRENT_TIME_UTC
3234

3335

3436
GET_TENANT_RESPONSE = """{
@@ -197,7 +199,8 @@ def test_get_tenant(self, tenant_mgt_app):
197199
assert req.method == 'GET'
198200
assert req.url == '{0}/tenants/tenant-id'.format(TENANT_MGT_URL_PREFIX)
199201
assert req.headers['X-Client-Version'] == f'Python/Admin/{firebase_admin.__version__}'
200-
assert req.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
202+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
203+
assert req.headers['x-goog-api-client'] == expected_metrics_header
201204

202205
def test_tenant_not_found(self, tenant_mgt_app):
203206
_instrument_tenant_mgt(tenant_mgt_app, 500, TENANT_NOT_FOUND_RESPONSE)
@@ -289,7 +292,8 @@ def _assert_request(self, recorder, body):
289292
assert req.method == 'POST'
290293
assert req.url == '{0}/tenants'.format(TENANT_MGT_URL_PREFIX)
291294
assert req.headers['X-Client-Version'] == f'Python/Admin/{firebase_admin.__version__}'
292-
assert req.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
295+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
296+
assert req.headers['x-goog-api-client'] == expected_metrics_header
293297
got = json.loads(req.body.decode())
294298
assert got == body
295299

@@ -389,7 +393,8 @@ def _assert_request(self, recorder, body, mask):
389393
assert req.url == '{0}/tenants/tenant-id?updateMask={1}'.format(
390394
TENANT_MGT_URL_PREFIX, ','.join(mask))
391395
assert req.headers['X-Client-Version'] == f'Python/Admin/{firebase_admin.__version__}'
392-
assert req.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
396+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
397+
assert req.headers['x-goog-api-client'] == expected_metrics_header
393398
got = json.loads(req.body.decode())
394399
assert got == body
395400

@@ -411,7 +416,8 @@ def test_delete_tenant(self, tenant_mgt_app):
411416
assert req.method == 'DELETE'
412417
assert req.url == '{0}/tenants/tenant-id'.format(TENANT_MGT_URL_PREFIX)
413418
assert req.headers['X-Client-Version'] == f'Python/Admin/{firebase_admin.__version__}'
414-
assert req.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
419+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
420+
assert req.headers['x-goog-api-client'] == expected_metrics_header
415421

416422
def test_tenant_not_found(self, tenant_mgt_app):
417423
_instrument_tenant_mgt(tenant_mgt_app, 500, TENANT_NOT_FOUND_RESPONSE)
@@ -555,7 +561,8 @@ def _assert_request(self, recorder, expected=None):
555561
req = recorder[0]
556562
assert req.method == 'GET'
557563
assert req.headers['X-Client-Version'] == f'Python/Admin/{firebase_admin.__version__}'
558-
assert req.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
564+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
565+
assert req.headers['x-goog-api-client'] == expected_metrics_header
559566
request = dict(parse.parse_qsl(parse.urlsplit(req.url).query))
560567
assert request == expected
561568

@@ -932,7 +939,8 @@ def _assert_request(
932939
assert req.method == method
933940
assert req.url == '{0}/tenants/tenant-id{1}'.format(prefix, want_url)
934941
assert req.headers['X-Client-Version'] == f'Python/Admin/{firebase_admin.__version__}'
935-
assert req.headers['X-GOOG-API-CLIENT'] == _utils.get_metrics_header()
942+
expected_metrics_header = _utils.get_metrics_header() + ' mock-cred-metric-tag'
943+
assert req.headers['x-goog-api-client'] == expected_metrics_header
936944
body = json.loads(req.body.decode())
937945
assert body == want_body
938946

@@ -958,6 +966,17 @@ def _assert_saml_provider_config(self, provider_config, want_id='saml.provider')
958966

959967
class TestVerifyIdToken:
960968

969+
def setup_method(self):
970+
self.time_patch = unittest.mock.patch('time.time', return_value=MOCK_CURRENT_TIME)
971+
self.mock_time = self.time_patch.start()
972+
self.utcnow_patch = unittest.mock.patch(
973+
'google.auth.jwt._helpers.utcnow', return_value=MOCK_CURRENT_TIME_UTC)
974+
self.mock_utcnow = self.utcnow_patch.start()
975+
976+
def teardown_method(self):
977+
self.time_patch.stop()
978+
self.utcnow_patch.stop()
979+
961980
def test_valid_token(self, tenant_mgt_app):
962981
client = tenant_mgt.auth_for_tenant('test-tenant', app=tenant_mgt_app)
963982
client._token_verifier.request = test_token_gen.MOCK_REQUEST
@@ -991,6 +1010,17 @@ def tenant_aware_custom_token_app():
9911010

9921011
class TestCreateCustomToken:
9931012

1013+
def setup_method(self):
1014+
self.time_patch = unittest.mock.patch('time.time', return_value=MOCK_CURRENT_TIME)
1015+
self.mock_time = self.time_patch.start()
1016+
self.utcnow_patch = unittest.mock.patch(
1017+
'google.auth.jwt._helpers.utcnow', return_value=MOCK_CURRENT_TIME_UTC)
1018+
self.mock_utcnow = self.utcnow_patch.start()
1019+
1020+
def teardown_method(self):
1021+
self.time_patch.stop()
1022+
self.utcnow_patch.stop()
1023+
9941024
def test_custom_token(self, tenant_aware_custom_token_app):
9951025
client = tenant_mgt.auth_for_tenant('test-tenant', app=tenant_aware_custom_token_app)
9961026

0 commit comments

Comments
 (0)