31
31
from firebase_admin import _auth_utils
32
32
33
33
34
+ #_auth_utils.is_emulated() = _auth_utils.get_emulator_host() != ''
34
35
# ID token constants
35
36
ID_TOKEN_ISSUER_PREFIX = 'https://securetoken.google.com/'
36
37
ID_TOKEN_CERT_URI = ('https://www.googleapis.com/robot/v1/metadata/x509/'
54
55
'service-accounts/default/email' )
55
56
56
57
58
+ class _EmulatedSigner (google .auth .crypt .Signer ):
59
+ key_id = None
60
+
61
+ def __init__ (self ):
62
+ pass
63
+
64
+ def sign (self , message ):
65
+ return b''
66
+
67
+
57
68
class _SigningProvider :
58
69
"""Stores a reference to a google.auth.crypto.Signer."""
59
70
@@ -78,6 +89,10 @@ def from_iam(cls, request, google_cred, service_account):
78
89
signer = iam .Signer (request , google_cred , service_account )
79
90
return _SigningProvider (signer , service_account )
80
91
92
+ @classmethod
93
+ def for_emulator (cls ):
94
+ return _SigningProvider (
_EmulatedSigner (),
'[email protected] ' )
95
+
81
96
82
97
class TokenGenerator :
83
98
"""Generates custom tokens and session cookies."""
@@ -94,6 +109,8 @@ def __init__(self, app, http_client, url_override=None):
94
109
95
110
def _init_signing_provider (self ):
96
111
"""Initializes a signing provider by following the go/firebase-admin-sign protocol."""
112
+ if _auth_utils .is_emulated ():
113
+ return _SigningProvider .for_emulator ()
97
114
# If the SDK was initialized with a service account, use it to sign bytes.
98
115
google_cred = self .app .credential .get_credential ()
99
116
if isinstance (google_cred , google .oauth2 .service_account .Credentials ):
@@ -291,15 +308,15 @@ def verify(self, token, request):
291
308
error_message = (
292
309
'{0} expects {1}, but was given a custom '
293
310
'token.' .format (self .operation , self .articled_short_name ))
294
- elif not header .get ('kid' ):
311
+ elif not _auth_utils . is_emulated () and not header .get ('kid' ):
295
312
if header .get ('alg' ) == 'HS256' and payload .get (
296
313
'v' ) == 0 and 'uid' in payload .get ('d' , {}):
297
314
error_message = (
298
315
'{0} expects {1}, but was given a legacy custom '
299
316
'token.' .format (self .operation , self .articled_short_name ))
300
317
else :
301
318
error_message = 'Firebase {0} has no "kid" claim.' .format (self .short_name )
302
- elif header .get ('alg' ) != 'RS256' :
319
+ elif not _auth_utils . is_emulated () and header .get ('alg' ) != 'RS256' :
303
320
error_message = (
304
321
'Firebase {0} has incorrect algorithm. Expected "RS256" but got '
305
322
'"{1}". {2}' .format (self .short_name , header .get ('alg' ), verify_id_token_msg ))
@@ -329,6 +346,10 @@ def verify(self, token, request):
329
346
if error_message :
330
347
raise self ._invalid_token_error (error_message )
331
348
349
+ if _auth_utils .is_emulated ():
350
+ claims = jwt .decode (token , verify = False )
351
+ claims ['uid' ] = claims ['sub' ]
352
+ return claims
332
353
try :
333
354
verified_claims = google .oauth2 .id_token .verify_token (
334
355
token ,
@@ -342,7 +363,7 @@ def verify(self, token, request):
342
363
except ValueError as error :
343
364
if 'Token expired' in str (error ):
344
365
raise self ._expired_token_error (str (error ), cause = error )
345
- raise self ._invalid_token_error (str (error ), cause = error )
366
+ raise self ._invalid_token_error (str (error ) + "FOO" , cause = error )
346
367
347
368
def _decode_unverified (self , token ):
348
369
try :
0 commit comments