Skip to content

Commit 3816856

Browse files
authored
Merge branch 'master' into auth-add-provider
2 parents 1932786 + 1b131f0 commit 3816856

21 files changed

+289
-284
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ jobs:
108108
uses: actions/[email protected]
109109
with:
110110
name: dist
111+
path: dist
111112

112113
- name: Publish preflight check
113114
id: preflight

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.5.0'
17+
__version__ = '6.6.0'
1818
__title__ = 'firebase_admin'
1919
__author__ = 'Firebase'
2020
__license__ = 'Apache License 2.0'

firebase_admin/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import os
1919
import threading
2020

21+
from google.auth.credentials import Credentials as GoogleAuthCredentials
2122
from google.auth.exceptions import DefaultCredentialsError
2223
from firebase_admin import credentials
2324
from firebase_admin.__about__ import __version__
@@ -208,10 +209,13 @@ def __init__(self, name, credential, options):
208209
'non-empty string.'.format(name))
209210
self._name = name
210211

211-
if not isinstance(credential, credentials.Base):
212+
if isinstance(credential, GoogleAuthCredentials):
213+
self._credential = credentials._ExternalCredentials(credential) # pylint: disable=protected-access
214+
elif isinstance(credential, credentials.Base):
215+
self._credential = credential
216+
else:
212217
raise ValueError('Illegal Firebase credential provided. App must be initialized '
213218
'with a valid credential instance.')
214-
self._credential = credential
215219
self._options = _AppOptions(options)
216220
self._lock = threading.RLock()
217221
self._services = {}

firebase_admin/_http_client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import requests
2222
from requests.packages.urllib3.util import retry # pylint: disable=import-error
2323

24+
from firebase_admin import _utils
2425

2526
if hasattr(retry.Retry.DEFAULT, 'allowed_methods'):
2627
_ANY_METHOD = {'allowed_methods': None}
@@ -36,6 +37,9 @@
3637

3738
DEFAULT_TIMEOUT_SECONDS = 120
3839

40+
METRICS_HEADERS = {
41+
'X-GOOG-API-CLIENT': _utils.get_metrics_header(),
42+
}
3943

4044
class HttpClient:
4145
"""Base HTTP client used to make HTTP calls.
@@ -72,6 +76,7 @@ def __init__(
7276

7377
if headers:
7478
self._session.headers.update(headers)
79+
self._session.headers.update(METRICS_HEADERS)
7580
if retries:
7681
self._session.mount('http://', requests.adapters.HTTPAdapter(max_retries=retries))
7782
self._session.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries))

firebase_admin/_utils.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""Internal utilities common to all modules."""
1616

1717
import json
18+
from platform import python_version
1819

1920
import google.auth
2021
import requests
@@ -75,6 +76,8 @@
7576
16: exceptions.UNAUTHENTICATED,
7677
}
7778

79+
def get_metrics_header():
80+
return f'gl-python/{python_version()} fire-admin/{firebase_admin.__version__}'
7881

7982
def _get_initialized_app(app):
8083
"""Returns a reference to an initialized App instance."""

firebase_admin/app_check.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ class _AppCheckService:
5151
_scoped_project_id = None
5252
_jwks_client = None
5353

54+
_APP_CHECK_HEADERS = {
55+
'X-GOOG-API-CLIENT': _utils.get_metrics_header(),
56+
}
57+
5458
def __init__(self, app):
5559
# Validate and store the project_id to validate the JWT claims
5660
self._project_id = app.project_id
@@ -62,7 +66,8 @@ def __init__(self, app):
6266
'GOOGLE_CLOUD_PROJECT environment variable.')
6367
self._scoped_project_id = 'projects/' + app.project_id
6468
# Default lifespan is 300 seconds (5 minutes) so we change it to 21600 seconds (6 hours).
65-
self._jwks_client = PyJWKClient(self._JWKS_URL, lifespan=21600)
69+
self._jwks_client = PyJWKClient(
70+
self._JWKS_URL, lifespan=21600, headers=self._APP_CHECK_HEADERS)
6671

6772

6873
def verify_token(self, token: str) -> Dict[str, Any]:

firebase_admin/credentials.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import pathlib
1919

2020
import google.auth
21+
from google.auth.credentials import Credentials as GoogleAuthCredentials
2122
from google.auth.transport import requests
2223
from google.oauth2 import credentials
2324
from google.oauth2 import service_account
@@ -58,6 +59,19 @@ def get_credential(self):
5859
"""Returns the Google credential instance used for authentication."""
5960
raise NotImplementedError
6061

62+
class _ExternalCredentials(Base):
63+
"""A wrapper for google.auth.credentials.Credentials typed credential instances"""
64+
65+
def __init__(self, credential: GoogleAuthCredentials):
66+
super(_ExternalCredentials, self).__init__()
67+
self._g_credential = credential
68+
69+
def get_credential(self):
70+
"""Returns the underlying Google Credential
71+
72+
Returns:
73+
google.auth.credentials.Credentials: A Google Auth credential instance."""
74+
return self._g_credential
6175

6276
class Certificate(Base):
6377
"""A credential initialized from a JSON certificate keyfile."""

firebase_admin/storage.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,13 @@ def bucket(name=None, app=None) -> storage.Bucket:
5555
class _StorageClient:
5656
"""Holds a Google Cloud Storage client instance."""
5757

58+
STORAGE_HEADERS = {
59+
'X-GOOG-API-CLIENT': _utils.get_metrics_header(),
60+
}
61+
5862
def __init__(self, credentials, project, default_bucket):
59-
self._client = storage.Client(credentials=credentials, project=project)
63+
self._client = storage.Client(
64+
credentials=credentials, project=project, extra_headers=self.STORAGE_HEADERS)
6065
self._default_bucket = default_bucket
6166

6267
@classmethod

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ pytest-mock >= 3.6.1
99
cachecontrol >= 0.12.14
1010
google-api-core[grpc] >= 1.22.1, < 3.0.0dev; platform.python_implementation != 'PyPy'
1111
google-api-python-client >= 1.7.8
12-
google-cloud-firestore >= 2.9.1; platform.python_implementation != 'PyPy'
12+
google-cloud-firestore >= 2.19.0; platform.python_implementation != 'PyPy'
1313
google-cloud-storage >= 1.37.1
1414
pyjwt[crypto] >= 2.5.0

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
'cachecontrol>=0.12.14',
4141
'google-api-core[grpc] >= 1.22.1, < 3.0.0dev; platform.python_implementation != "PyPy"',
4242
'google-api-python-client >= 1.7.8',
43-
'google-cloud-firestore>=2.9.1; platform.python_implementation != "PyPy"',
43+
'google-cloud-firestore>=2.19.0; platform.python_implementation != "PyPy"',
4444
'google-cloud-storage>=1.37.1',
4545
'pyjwt[crypto] >= 2.5.0',
4646
]

tests/test_app.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,16 @@ def test_non_default_app_init(self, app_credential):
246246
with pytest.raises(ValueError):
247247
firebase_admin.initialize_app(app_credential, name='myApp')
248248

249+
def test_app_init_with_google_auth_cred(self):
250+
cred = testutils.MockGoogleCredential()
251+
assert isinstance(cred, credentials.GoogleAuthCredentials)
252+
app = firebase_admin.initialize_app(cred)
253+
assert cred is app.credential.get_credential()
254+
assert isinstance(app.credential, credentials.Base)
255+
assert isinstance(app.credential, credentials._ExternalCredentials)
256+
with pytest.raises(ValueError):
257+
firebase_admin.initialize_app(app_credential)
258+
249259
@pytest.mark.parametrize('cred', invalid_credentials)
250260
def test_app_init_with_invalid_credential(self, cred):
251261
with pytest.raises(ValueError):

0 commit comments

Comments
 (0)