16
16
import datetime
17
17
import python_jwt as jwt
18
18
import jwcrypto .jwk as jwk
19
+ from urllib .parse import parse_qs
19
20
20
21
from firebase ._exception import raise_detailed_error
21
22
@@ -412,7 +413,7 @@ def delete_user_account(self, id_token):
412
413
413
414
return request_object .json ()
414
415
415
- def sign_in_with_oauth_credential (self , token ):
416
+ def sign_in_with_oauth_credential (self , oauth2callback_url ):
416
417
""" Sign In With OAuth credential.
417
418
418
419
| For more details:
@@ -425,16 +426,17 @@ def sign_in_with_oauth_credential(self, token):
425
426
https://firebase.google.com/docs/reference/rest/auth#section-sign-in-with-oauth-credential
426
427
427
428
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 .
431
432
432
433
:return: User account info and Firebase Auth Tokens.
433
434
:rtype: dict
434
435
"""
435
436
436
437
request_ref = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyAssertion?key={0}" .format (self .api_key )
437
438
439
+ token = self ._token_from_auth_url (oauth2callback_url )
438
440
data = {
439
441
'postBody' : 'providerId={0}&{1}={2}' .format (self .provider_id , token ['type' ], token ['value' ]),
440
442
'autoCreate' : 'true' ,
@@ -453,6 +455,41 @@ def sign_in_with_oauth_credential(self, token):
453
455
454
456
return request_object .json ()
455
457
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
+
456
493
def update_profile (self , id_token , display_name = None , photo_url = None , delete_attribute = None ):
457
494
""" Update a user's profile (display name / photo URL).
458
495
0 commit comments