31
31
32
32
_verify_token_url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyCustomToken'
33
33
_verify_password_url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword'
34
+ _password_reset_url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/resetPassword'
35
+ _verify_email_url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/setAccountInfo'
36
+ _email_sign_in_url = 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/emailLinkSignin'
34
37
38
+ ACTION_LINK_CONTINUE_URL = 'http://localhost?a=1&b=5#f=1'
35
39
36
40
def _sign_in (custom_token , api_key ):
37
41
body = {'token' : custom_token .decode (), 'returnSecureToken' : True }
@@ -55,6 +59,35 @@ def _random_id():
55
59
def _random_phone ():
56
60
return '+1' + '' .join ([str (random .randint (0 , 9 )) for _ in range (0 , 10 )])
57
61
62
+ def _reset_password (oob_code , new_password , api_key ):
63
+ body = {'oobCode' : oob_code , 'newPassword' : new_password }
64
+ params = {'key' : api_key }
65
+ resp = requests .request ('post' , _password_reset_url , params = params , json = body )
66
+ resp .raise_for_status ()
67
+ return resp .json ().get ('email' )
68
+
69
+ def _verify_email (oob_code , api_key ):
70
+ body = {'oobCode' : oob_code }
71
+ params = {'key' : api_key }
72
+ resp = requests .request ('post' , _verify_email_url , params = params , json = body )
73
+ resp .raise_for_status ()
74
+ return resp .json ().get ('email' )
75
+
76
+ def _sign_in_with_email_link (email , oob_code , api_key ):
77
+ body = {'oobCode' : oob_code , 'email' : email }
78
+ params = {'key' : api_key }
79
+ resp = requests .request ('post' , _email_sign_in_url , params = params , json = body )
80
+ resp .raise_for_status ()
81
+ return resp .json ().get ('idToken' )
82
+
83
+ def _validate_link_url (link , check_continue_url = True ):
84
+ assert isinstance (link , six .string_types )
85
+ query = six .moves .urllib .parse .urlparse (link ).query
86
+ query_dict = dict (six .moves .urllib .parse .parse_qsl (query ))
87
+ if check_continue_url :
88
+ assert query_dict ['continueUrl' ] == ACTION_LINK_CONTINUE_URL
89
+ return query_dict ['oobCode' ]
90
+
58
91
def test_custom_token (api_key ):
59
92
custom_token = auth .create_custom_token ('user1' )
60
93
id_token = _sign_in (custom_token , api_key )
@@ -152,6 +185,18 @@ def new_user_list():
152
185
for uid in users :
153
186
auth .delete_user (uid )
154
187
188
+ @pytest .fixture
189
+ def new_user_email_unverified ():
190
+ random_id , email = _random_id ()
191
+ user = auth .create_user (
192
+ uid = random_id ,
193
+ email = email ,
194
+ email_verified = False ,
195
+ password = 'password'
196
+ )
197
+ yield user
198
+ auth .delete_user (user .uid )
199
+
155
200
def test_get_user (new_user_with_params ):
156
201
user = auth .get_user (new_user_with_params .uid )
157
202
assert user .uid == new_user_with_params .uid
@@ -373,37 +418,41 @@ def test_import_users_with_password(api_key):
373
418
finally :
374
419
auth .delete_user (uid )
375
420
376
- @pytest .fixture
377
- def action_code_settings ():
378
- return auth .ActionCodeSettings ('http://localhost' )
379
-
380
- def _validate_link_url (link ):
381
- assert isinstance (link , six .string_types )
382
- six .moves .urllib .parse .urlparse (link )
383
-
384
- def test_password_reset (new_user_with_params ):
385
- link = auth .generate_password_reset_link (new_user_with_params .email )
386
- _validate_link_url (link )
387
-
388
- def test_email_verification (new_user_with_params ):
389
- link = auth .generate_email_verification_link (new_user_with_params .email )
390
- _validate_link_url (link )
391
-
392
- def test_password_reset_with_settings (new_user_with_params , action_code_settings ):
393
- link = auth .generate_password_reset_link (new_user_with_params .email ,
421
+ def test_password_reset (new_user_email_unverified , api_key ):
422
+ link = auth .generate_password_reset_link (new_user_email_unverified .email )
423
+ oob_code = _validate_link_url (link , check_continue_url = False )
424
+ assert new_user_email_unverified .email == _reset_password (oob_code , "newPassword" , api_key )
425
+ assert auth .get_user (new_user_email_unverified .uid ).email_verified
426
+
427
+ def test_email_verification (new_user_email_unverified , api_key ):
428
+ link = auth .generate_email_verification_link (new_user_email_unverified .email )
429
+ oob_code = _validate_link_url (link , check_continue_url = False )
430
+ assert new_user_email_unverified .email == _verify_email (oob_code , api_key )
431
+ assert auth .get_user (new_user_email_unverified .uid ).email_verified
432
+
433
+ def test_password_reset_with_settings (new_user_email_unverified , api_key ):
434
+ action_code_settings = auth .ActionCodeSettings (ACTION_LINK_CONTINUE_URL )
435
+ link = auth .generate_password_reset_link (new_user_email_unverified .email ,
394
436
action_code_settings = action_code_settings )
395
- _validate_link_url (link )
437
+ oob_code = _validate_link_url (link )
438
+ assert new_user_email_unverified .email == _reset_password (oob_code , "newPassword" , api_key )
439
+ assert auth .get_user (new_user_email_unverified .uid ).email_verified
396
440
397
- def test_email_verification_with_settings (new_user_with_params , action_code_settings ):
398
- link = auth .generate_email_verification_link (new_user_with_params .email ,
441
+ def test_email_verification_with_settings (new_user_email_unverified , api_key ):
442
+ action_code_settings = auth .ActionCodeSettings (ACTION_LINK_CONTINUE_URL )
443
+ link = auth .generate_email_verification_link (new_user_email_unverified .email ,
399
444
action_code_settings = action_code_settings )
400
- _validate_link_url (link )
445
+ oob_code = _validate_link_url (link )
446
+ assert new_user_email_unverified .email == _verify_email (oob_code , api_key )
447
+ assert auth .get_user (new_user_email_unverified .uid ).email_verified
401
448
402
- def test_email_sign_in_with_settings (new_user_with_params , action_code_settings ):
403
- link = auth .generate_sign_in_with_email_link (new_user_with_params .email ,
449
+ def test_email_sign_in_with_settings (new_user_email_unverified , api_key ):
450
+ action_code_settings = auth .ActionCodeSettings (ACTION_LINK_CONTINUE_URL )
451
+ link = auth .generate_sign_in_with_email_link (new_user_email_unverified .email ,
404
452
action_code_settings = action_code_settings )
405
- _validate_link_url (link )
406
-
453
+ oob_code = _validate_link_url (link )
454
+ assert _sign_in_with_email_link (new_user_email_unverified .email , oob_code , api_key )
455
+ assert auth .get_user (new_user_email_unverified .uid ).email_verified
407
456
408
457
class CredentialWrapper (credentials .Base ):
409
458
"""A custom Firebase credential that wraps an OAuth2 token."""
0 commit comments