1616import datetime
1717import python_jwt as jwt
1818import jwcrypto .jwk as jwk
19+ from urllib .parse import parse_qs
1920
2021from firebase ._exception import raise_detailed_error
2122
@@ -412,7 +413,7 @@ def delete_user_account(self, id_token):
412413
413414 return request_object .json ()
414415
415- def sign_in_with_oauth_credential (self , token ):
416+ def sign_in_with_oauth_credential (self , oauth2callback_url ):
416417 """ Sign In With OAuth credential.
417418
418419 | For more details:
@@ -425,16 +426,17 @@ def sign_in_with_oauth_credential(self, token):
425426 https://firebase.google.com/docs/reference/rest/auth#section-sign-in-with-oauth-credential
426427
427428
428- :type token: dict
429- :param token : The OAuth credential (an ID token or access
430- token) .
429+ :type oauth2callback_url: str
430+ :param oauth2callback_url : The URL redirected to after
431+ successful authorization from the provider .
431432
432433 :return: User account info and Firebase Auth Tokens.
433434 :rtype: dict
434435 """
435436
436437 request_ref = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyAssertion?key={0}" .format (self .api_key )
437438
439+ token = self ._token_from_auth_url (oauth2callback_url )
438440 data = {
439441 'postBody' : 'providerId={0}&{1}={2}' .format (self .provider_id , token ['type' ], token ['value' ]),
440442 'autoCreate' : 'true' ,
@@ -453,6 +455,41 @@ def sign_in_with_oauth_credential(self, token):
453455
454456 return request_object .json ()
455457
458+ def _token_from_auth_url (self , url ):
459+ """ Fetch tokens using the authorization code from given URL.
460+
461+
462+ :type url: str
463+ :param url: The URL redirected to after successful
464+ authorization from the provider.
465+
466+
467+ :return: The OAuth credential (an ID token).
468+ :rtype: dict
469+ """
470+
471+ request_ref = 'https://www.googleapis.com/oauth2/v4/token'
472+
473+ auth_url_values = parse_qs (url [url .index ('?' ) + 1 :])
474+
475+ data = {
476+ 'client_id' : self .client_secret ['client_id' ],
477+ 'client_secret' : self .client_secret ['client_secret' ],
478+ 'code' : auth_url_values ['code' ][0 ],
479+ 'grant_type' : 'authorization_code' ,
480+ 'redirect_uri' : self .client_secret ['redirect_uris' ][0 ],
481+ }
482+
483+ headers = {"content-type" : "application/x-www-form-urlencoded; charset=UTF-8" }
484+ request_object = self .requests .post (request_ref , headers = headers , data = data )
485+
486+ raise_detailed_error (request_object )
487+
488+ return {
489+ 'type' : 'id_token' ,
490+ 'value' : request_object .json ()['id_token' ],
491+ }
492+
456493 def update_profile (self , id_token , display_name = None , photo_url = None , delete_attribute = None ):
457494 """ Update a user's profile (display name / photo URL).
458495
0 commit comments