diff --git a/firebase_admin/__init__.py b/firebase_admin/__init__.py index 0ca82ec5..7bb9c59c 100644 --- a/firebase_admin/__init__.py +++ b/firebase_admin/__init__.py @@ -18,6 +18,7 @@ import os import threading +from google.auth.credentials import Credentials as GoogleAuthCredentials from google.auth.exceptions import DefaultCredentialsError from firebase_admin import credentials from firebase_admin.__about__ import __version__ @@ -208,10 +209,13 @@ def __init__(self, name, credential, options): 'non-empty string.'.format(name)) self._name = name - if not isinstance(credential, credentials.Base): + if isinstance(credential, GoogleAuthCredentials): + self._credential = credentials._ExternalCredentials(credential) # pylint: disable=protected-access + elif isinstance(credential, credentials.Base): + self._credential = credential + else: raise ValueError('Illegal Firebase credential provided. App must be initialized ' 'with a valid credential instance.') - self._credential = credential self._options = _AppOptions(options) self._lock = threading.RLock() self._services = {} diff --git a/firebase_admin/credentials.py b/firebase_admin/credentials.py index 5477e1cf..75060028 100644 --- a/firebase_admin/credentials.py +++ b/firebase_admin/credentials.py @@ -18,6 +18,7 @@ import pathlib import google.auth +from google.auth.credentials import Credentials as GoogleAuthCredentials from google.auth.transport import requests from google.oauth2 import credentials from google.oauth2 import service_account @@ -58,6 +59,19 @@ def get_credential(self): """Returns the Google credential instance used for authentication.""" raise NotImplementedError +class _ExternalCredentials(Base): + """A wrapper for google.auth.credentials.Credentials typed credential instances""" + + def __init__(self, credential: GoogleAuthCredentials): + super(_ExternalCredentials, self).__init__() + self._g_credential = credential + + def get_credential(self): + """Returns the underlying Google Credential + + Returns: + google.auth.credentials.Credentials: A Google Auth credential instance.""" + return self._g_credential class Certificate(Base): """A credential initialized from a JSON certificate keyfile.""" diff --git a/tests/test_app.py b/tests/test_app.py index 4233d584..5b203661 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -246,6 +246,16 @@ def test_non_default_app_init(self, app_credential): with pytest.raises(ValueError): firebase_admin.initialize_app(app_credential, name='myApp') + def test_app_init_with_google_auth_cred(self): + cred = testutils.MockGoogleCredential() + assert isinstance(cred, credentials.GoogleAuthCredentials) + app = firebase_admin.initialize_app(cred) + assert cred is app.credential.get_credential() + assert isinstance(app.credential, credentials.Base) + assert isinstance(app.credential, credentials._ExternalCredentials) + with pytest.raises(ValueError): + firebase_admin.initialize_app(app_credential) + @pytest.mark.parametrize('cred', invalid_credentials) def test_app_init_with_invalid_credential(self, cred): with pytest.raises(ValueError):