Skip to content

Commit 32e8dd2

Browse files
authored
feat: Support passing google.auth typed credentials in initialize_app() (#821)
* feat: Support passing `google.auth` typed credentials in `initialize_app()` * Refactor and add unit test
1 parent d8d6aea commit 32e8dd2

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

firebase_admin/__init__.py

+6-2
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/credentials.py

+14
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."""

tests/test_app.py

+10
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)