16
16
import base64
17
17
import datetime
18
18
import random
19
+ import string
19
20
import time
20
21
from urllib import parse
21
22
import uuid
38
39
39
40
ACTION_LINK_CONTINUE_URL = 'http://localhost?a=1&b=5#f=1'
40
41
42
+ X509_CERTIFICATES = [
43
+ ('-----BEGIN CERTIFICATE-----\n MIICZjCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQ0FADBQMQswCQYDVQQGEwJ1czE'
44
+ 'L\n MAkGA1UECAwCQ0ExDTALBgNVBAoMBEFjbWUxETAPBgNVBAMMCGFjbWUuY29tMRIw\n EAYDVQQHDAlTdW5ueXZhbGU'
45
+ 'wHhcNMTgxMjA2MDc1MTUxWhcNMjgxMjAzMDc1MTUx\n WjBQMQswCQYDVQQGEwJ1czELMAkGA1UECAwCQ0ExDTALBgNVB'
46
+ 'AoMBEFjbWUxETAP\n BgNVBAMMCGFjbWUuY29tMRIwEAYDVQQHDAlTdW5ueXZhbGUwgZ8wDQYJKoZIhvcN\n AQEBBQADg'
47
+ 'Y0AMIGJAoGBAKphmggjiVgqMLXyzvI7cKphscIIQ+wcv7Dld6MD4aKv\n 7Jqr8ltujMxBUeY4LFEKw8Terb01snYpDot'
48
+ 'filaG6NxpF/GfVVmMalzwWp0mT8+H\n yzyPj89mRcozu17RwuooR6n1ofXjGcBE86lqC21UhA3WVgjPOLqB42rlE9gPn'
49
+ 'ZLB\n AgMBAAGjUDBOMB0GA1UdDgQWBBS0iM7WnbCNOnieOP1HIA+Oz/ML+zAfBgNVHSME\n GDAWgBS0iM7WnbCNOnieO'
50
+ 'P1HIA+Oz/ML+zAMBgNVHRMEBTADAQH/MA0GCSqGSIb3\n DQEBDQUAA4GBAF3jBgS+wP+K/jTupEQur6iaqS4UvXd//d4'
51
+ 'vo1MV06oTLQMTz+rP\n OSMDNwxzfaOn6vgYLKP/Dcy9dSTnSzgxLAxfKvDQZA0vE3udsw0Bd245MmX4+GOp\n lbrN99X'
52
+ 'P1u+lFxCSdMUzvQ/jW4ysw/Nq4JdJ0gPAyPvL6Qi/3mQdIQwx\n -----END CERTIFICATE-----\n ' ),
53
+ ('-----BEGIN CERTIFICATE-----\n MIICZjCCAc+gAwIBAgIBADANBgkqhkiG9w0BAQ0FADBQMQswCQYDVQQGEwJ1czE'
54
+ 'L\n MAkGA1UECAwCQ0ExDTALBgNVBAoMBEFjbWUxETAPBgNVBAMMCGFjbWUuY29tMRIw\n EAYDVQQHDAlTdW5ueXZhbGU'
55
+ 'wHhcNMTgxMjA2MDc1ODE4WhcNMjgxMjAzMDc1ODE4\n WjBQMQswCQYDVQQGEwJ1czELMAkGA1UECAwCQ0ExDTALBgNVB'
56
+ 'AoMBEFjbWUxETAP\n BgNVBAMMCGFjbWUuY29tMRIwEAYDVQQHDAlTdW5ueXZhbGUwgZ8wDQYJKoZIhvcN\n AQEBBQADg'
57
+ 'Y0AMIGJAoGBAKuzYKfDZGA6DJgQru3wNUqv+S0hMZfP/jbp8ou/8UKu\n rNeX7cfCgt3yxoGCJYKmF6t5mvo76JY0MWw'
58
+ 'A53BxeP/oyXmJ93uHG5mFRAsVAUKs\n cVVb0Xi6ujxZGVdDWFV696L0BNOoHTfXmac6IBoZQzNNK4n1AATqwo+z7a0pf'
59
+ 'RrJ\n AgMBAAGjUDBOMB0GA1UdDgQWBBSKmi/ZKMuLN0ES7/jPa7q7jAjPiDAfBgNVHSME\n GDAWgBSKmi/ZKMuLN0ES7'
60
+ '/jPa7q7jAjPiDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3\n DQEBDQUAA4GBAAg2a2kSn05NiUOuWOHwPUjW3wQRsGxPXtb'
61
+ 'hWMhmNdCfKKteM2+/\n Ld/jz5F3qkOgGQ3UDgr3SHEoWhnLaJMF4a2tm6vL2rEIfPEK81KhTTRxSsAgMVbU\n JXBz1md'
62
+ '6Ur0HlgQC7d1CHC8/xi2DDwHopLyxhogaZUxy9IaRxUEa2vJW\n -----END CERTIFICATE-----\n ' ),
63
+ ]
64
+
65
+
41
66
def _sign_in (custom_token , api_key ):
42
67
body = {'token' : custom_token .decode (), 'returnSecureToken' : True }
43
68
params = {'key' : api_key }
@@ -52,6 +77,10 @@ def _sign_in_with_password(email, password, api_key):
52
77
resp .raise_for_status ()
53
78
return resp .json ().get ('idToken' )
54
79
80
+ def _random_string (length = 10 ):
81
+ letters = string .ascii_lowercase
82
+ return '' .join (random .choice (letters ) for i in range (length ))
83
+
55
84
def _random_id ():
56
85
random_id = str (uuid .uuid4 ()).lower ().replace ('-' , '' )
57
86
email = 'test{0}@example.{1}.com' .format (random_id [:12 ], random_id [12 :])
@@ -477,6 +506,163 @@ def test_email_sign_in_with_settings(new_user_email_unverified, api_key):
477
506
assert id_token is not None and len (id_token ) > 0
478
507
assert auth .get_user (new_user_email_unverified .uid ).email_verified
479
508
509
+
510
+ @pytest .fixture (scope = 'module' )
511
+ def oidc_provider ():
512
+ provider_config = _create_oidc_provider_config ()
513
+ yield provider_config
514
+ auth .delete_oidc_provider_config (provider_config .provider_id )
515
+
516
+
517
+ def test_create_oidc_provider_config (oidc_provider ):
518
+ assert isinstance (oidc_provider , auth .OIDCProviderConfig )
519
+ assert oidc_provider .client_id == 'OIDC_CLIENT_ID'
520
+ assert oidc_provider .issuer == 'https://oidc.com/issuer'
521
+ assert oidc_provider .display_name == 'OIDC_DISPLAY_NAME'
522
+ assert oidc_provider .enabled is True
523
+
524
+
525
+ def test_get_oidc_provider_config (oidc_provider ):
526
+ provider_config = auth .get_oidc_provider_config (oidc_provider .provider_id )
527
+ assert isinstance (provider_config , auth .OIDCProviderConfig )
528
+ assert provider_config .provider_id == oidc_provider .provider_id
529
+ assert provider_config .client_id == 'OIDC_CLIENT_ID'
530
+ assert provider_config .issuer == 'https://oidc.com/issuer'
531
+ assert provider_config .display_name == 'OIDC_DISPLAY_NAME'
532
+ assert provider_config .enabled is True
533
+
534
+
535
+ def test_list_oidc_provider_configs (oidc_provider ):
536
+ page = auth .list_oidc_provider_configs ()
537
+ result = None
538
+ for provider_config in page .iterate_all ():
539
+ if provider_config .provider_id == oidc_provider .provider_id :
540
+ result = provider_config
541
+ break
542
+
543
+ assert result is not None
544
+
545
+
546
+ def test_update_oidc_provider_config ():
547
+ provider_config = _create_oidc_provider_config ()
548
+ try :
549
+ provider_config = auth .update_oidc_provider_config (
550
+ provider_config .provider_id ,
551
+ client_id = 'UPDATED_OIDC_CLIENT_ID' ,
552
+ issuer = 'https://oidc.com/updated_issuer' ,
553
+ display_name = 'UPDATED_OIDC_DISPLAY_NAME' ,
554
+ enabled = False )
555
+ assert provider_config .client_id == 'UPDATED_OIDC_CLIENT_ID'
556
+ assert provider_config .issuer == 'https://oidc.com/updated_issuer'
557
+ assert provider_config .display_name == 'UPDATED_OIDC_DISPLAY_NAME'
558
+ assert provider_config .enabled is False
559
+ finally :
560
+ auth .delete_oidc_provider_config (provider_config .provider_id )
561
+
562
+
563
+ def test_delete_oidc_provider_config ():
564
+ provider_config = _create_oidc_provider_config ()
565
+ auth .delete_oidc_provider_config (provider_config .provider_id )
566
+ with pytest .raises (auth .ConfigurationNotFoundError ):
567
+ auth .get_oidc_provider_config (provider_config .provider_id )
568
+
569
+
570
+ @pytest .fixture (scope = 'module' )
571
+ def saml_provider ():
572
+ provider_config = _create_saml_provider_config ()
573
+ yield provider_config
574
+ auth .delete_saml_provider_config (provider_config .provider_id )
575
+
576
+
577
+ def test_create_saml_provider_config (saml_provider ):
578
+ assert isinstance (saml_provider , auth .SAMLProviderConfig )
579
+ assert saml_provider .idp_entity_id == 'IDP_ENTITY_ID'
580
+ assert saml_provider .sso_url == 'https://example.com/login'
581
+ assert saml_provider .x509_certificates == [X509_CERTIFICATES [0 ]]
582
+ assert saml_provider .rp_entity_id == 'RP_ENTITY_ID'
583
+ assert saml_provider .callback_url == 'https://projectId.firebaseapp.com/__/auth/handler'
584
+ assert saml_provider .display_name == 'SAML_DISPLAY_NAME'
585
+ assert saml_provider .enabled is True
586
+
587
+
588
+ def test_get_saml_provider_config (saml_provider ):
589
+ provider_config = auth .get_saml_provider_config (saml_provider .provider_id )
590
+ assert isinstance (provider_config , auth .SAMLProviderConfig )
591
+ assert provider_config .provider_id == saml_provider .provider_id
592
+ assert provider_config .idp_entity_id == 'IDP_ENTITY_ID'
593
+ assert provider_config .sso_url == 'https://example.com/login'
594
+ assert provider_config .x509_certificates == [X509_CERTIFICATES [0 ]]
595
+ assert provider_config .rp_entity_id == 'RP_ENTITY_ID'
596
+ assert provider_config .callback_url == 'https://projectId.firebaseapp.com/__/auth/handler'
597
+ assert provider_config .display_name == 'SAML_DISPLAY_NAME'
598
+ assert provider_config .enabled is True
599
+
600
+
601
+ def test_list_saml_provider_configs (saml_provider ):
602
+ page = auth .list_saml_provider_configs ()
603
+ result = None
604
+ for provider_config in page .iterate_all ():
605
+ if provider_config .provider_id == saml_provider .provider_id :
606
+ result = provider_config
607
+ break
608
+
609
+ assert result is not None
610
+
611
+
612
+ def test_update_saml_provider_config ():
613
+ provider_config = _create_saml_provider_config ()
614
+ try :
615
+ provider_config = auth .update_saml_provider_config (
616
+ provider_config .provider_id ,
617
+ idp_entity_id = 'UPDATED_IDP_ENTITY_ID' ,
618
+ sso_url = 'https://example.com/updated_login' ,
619
+ x509_certificates = [X509_CERTIFICATES [1 ]],
620
+ rp_entity_id = 'UPDATED_RP_ENTITY_ID' ,
621
+ callback_url = 'https://updatedProjectId.firebaseapp.com/__/auth/handler' ,
622
+ display_name = 'UPDATED_SAML_DISPLAY_NAME' ,
623
+ enabled = False )
624
+ assert provider_config .idp_entity_id == 'UPDATED_IDP_ENTITY_ID'
625
+ assert provider_config .sso_url == 'https://example.com/updated_login'
626
+ assert provider_config .x509_certificates == [X509_CERTIFICATES [1 ]]
627
+ assert provider_config .rp_entity_id == 'UPDATED_RP_ENTITY_ID'
628
+ assert provider_config .callback_url == ('https://updatedProjectId.firebaseapp.com/'
629
+ '__/auth/handler' )
630
+ assert provider_config .display_name == 'UPDATED_SAML_DISPLAY_NAME'
631
+ assert provider_config .enabled is False
632
+ finally :
633
+ auth .delete_saml_provider_config (provider_config .provider_id )
634
+
635
+
636
+ def test_delete_saml_provider_config ():
637
+ provider_config = _create_saml_provider_config ()
638
+ auth .delete_saml_provider_config (provider_config .provider_id )
639
+ with pytest .raises (auth .ConfigurationNotFoundError ):
640
+ auth .get_saml_provider_config (provider_config .provider_id )
641
+
642
+
643
+ def _create_oidc_provider_config ():
644
+ provider_id = 'oidc.{0}' .format (_random_string ())
645
+ return auth .create_oidc_provider_config (
646
+ provider_id = provider_id ,
647
+ client_id = 'OIDC_CLIENT_ID' ,
648
+ issuer = 'https://oidc.com/issuer' ,
649
+ display_name = 'OIDC_DISPLAY_NAME' ,
650
+ enabled = True )
651
+
652
+
653
+ def _create_saml_provider_config ():
654
+ provider_id = 'saml.{0}' .format (_random_string ())
655
+ return auth .create_saml_provider_config (
656
+ provider_id = provider_id ,
657
+ idp_entity_id = 'IDP_ENTITY_ID' ,
658
+ sso_url = 'https://example.com/login' ,
659
+ x509_certificates = [X509_CERTIFICATES [0 ]],
660
+ rp_entity_id = 'RP_ENTITY_ID' ,
661
+ callback_url = 'https://projectId.firebaseapp.com/__/auth/handler' ,
662
+ display_name = 'SAML_DISPLAY_NAME' ,
663
+ enabled = True )
664
+
665
+
480
666
class CredentialWrapper (credentials .Base ):
481
667
"""A custom Firebase credential that wraps an OAuth2 token."""
482
668
0 commit comments