@@ -196,6 +196,8 @@ def _test_username_password(self,
196196 azure_region = azure_region , # Regional endpoint does not support ROPC.
197197 # Here we just use it to test a regional app won't break ROPC.
198198 client_credential = client_secret )
199+ self .assertEqual (
200+ self .app .get_accounts (username = username ), [], "Cache starts empty" )
199201 result = self .app .acquire_token_by_username_password (
200202 username , password , scopes = scope )
201203 self .assertLoosely (result )
@@ -204,6 +206,9 @@ def _test_username_password(self,
204206 username = username , # Our implementation works even when "profile" scope was not requested, or when profile claims is unavailable in B2C
205207 )
206208
209+ @unittest .skipIf (
210+ os .getenv ("TRAVIS" ), # It is set when running on TravisCI or Github Actions
211+ "Although it is doable, we still choose to skip device flow to save time" )
207212 def _test_device_flow (
208213 self , client_id = None , authority = None , scope = None , ** ignored ):
209214 assert client_id and authority and scope
@@ -229,6 +234,7 @@ def _test_device_flow(
229234 logger .info (
230235 "%s obtained tokens: %s" , self .id (), json .dumps (result , indent = 4 ))
231236
237+ @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
232238 def _test_acquire_token_interactive (
233239 self , client_id = None , authority = None , scope = None , port = None ,
234240 username = None , lab_name = None ,
@@ -289,7 +295,6 @@ def test_ssh_cert_for_service_principal(self):
289295 result .get ("error" ), result .get ("error_description" )))
290296 self .assertEqual ("ssh-cert" , result ["token_type" ])
291297
292- @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
293298 def test_ssh_cert_for_user_should_work_with_any_account (self ):
294299 result = self ._test_acquire_token_interactive (
295300 client_id = "04b07795-8ddb-461a-bbee-02f9e1bf7b46" , # Azure CLI is one
@@ -524,8 +529,8 @@ def tearDownClass(cls):
524529 cls .session .close ()
525530
526531 @classmethod
527- def get_lab_app_object (cls , ** query ): # https://msidlab.com/swagger/index.html
528- url = "https://msidlab.com/api/app"
532+ def get_lab_app_object (cls , client_id = None , ** query ): # https://msidlab.com/swagger/index.html
533+ url = "https://msidlab.com/api/app/{}" . format ( client_id or "" )
529534 resp = cls .session .get (url , params = query )
530535 result = resp .json ()[0 ]
531536 result ["scopes" ] = [ # Raw data has extra space, such as "s1, s2"
@@ -546,6 +551,8 @@ def get_lab_user_secret(cls, lab_name="msidlab4"):
546551 def get_lab_user (cls , ** query ): # https://docs.msidlab.com/labapi/userapi.html
547552 resp = cls .session .get ("https://msidlab.com/api/user" , params = query )
548553 result = resp .json ()[0 ]
554+ assert result .get ("upn" ), "Found no test user but {}" .format (
555+ json .dumps (result , indent = 2 ))
549556 _env = query .get ("azureenvironment" , "" ).lower ()
550557 authority_base = {
551558 "azureusgovernment" : "https://login.microsoftonline.us/"
@@ -561,6 +568,7 @@ def get_lab_user(cls, **query): # https://docs.msidlab.com/labapi/userapi.html
561568 "scope" : scope ,
562569 }
563570
571+ @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
564572 def _test_acquire_token_by_auth_code (
565573 self , client_id = None , authority = None , port = None , scope = None ,
566574 ** ignored ):
@@ -583,6 +591,7 @@ def _test_acquire_token_by_auth_code(
583591 error_description = result .get ("error_description" )))
584592 self .assertCacheWorksForUser (result , scope , username = None )
585593
594+ @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
586595 def _test_acquire_token_by_auth_code_flow (
587596 self , client_id = None , authority = None , port = None , scope = None ,
588597 username = None , lab_name = None ,
@@ -723,11 +732,9 @@ def test_adfs2019_fed_user(self):
723732 self .skipTest ("MEX endpoint in our test environment tends to fail" )
724733 raise
725734
726- @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
727735 def test_cloud_acquire_token_interactive (self ):
728736 self ._test_acquire_token_interactive (** self .get_lab_user (usertype = "cloud" ))
729737
730- @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
731738 def test_msa_pt_app_signin_via_organizations_authority_without_login_hint (self ):
732739 """There is/was an upstream bug. See test case full docstring for the details.
733740
@@ -751,7 +758,6 @@ def test_ropc_adfs2019_onprem(self):
751758 config ["password" ] = self .get_lab_user_secret (config ["lab_name" ])
752759 self ._test_username_password (** config )
753760
754- @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
755761 def test_adfs2019_onprem_acquire_token_by_auth_code (self ):
756762 """When prompted, you can manually login using this account:
757763
@@ -765,7 +771,6 @@ def test_adfs2019_onprem_acquire_token_by_auth_code(self):
765771 config ["port" ] = 8080
766772 self ._test_acquire_token_by_auth_code (** config )
767773
768- @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
769774 def test_adfs2019_onprem_acquire_token_by_auth_code_flow (self ):
770775 config = self .get_lab_user (usertype = "onprem" , federationProvider = "ADFSv2019" )
771776 self ._test_acquire_token_by_auth_code_flow (** dict (
@@ -775,7 +780,6 @@ def test_adfs2019_onprem_acquire_token_by_auth_code_flow(self):
775780 port = 8080 ,
776781 ))
777782
778- @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
779783 def test_adfs2019_onprem_acquire_token_interactive (self ):
780784 config = self .get_lab_user (usertype = "onprem" , federationProvider = "ADFSv2019" )
781785 self ._test_acquire_token_interactive (** dict (
@@ -846,7 +850,6 @@ def _build_b2c_authority(self, policy):
846850 base = "https://msidlabb2c.b2clogin.com/msidlabb2c.onmicrosoft.com"
847851 return base + "/" + policy # We do not support base + "?p=" + policy
848852
849- @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
850853 def test_b2c_acquire_token_by_auth_code (self ):
851854 """
852855 When prompted, you can manually login using this account:
@@ -863,7 +866,6 @@ def test_b2c_acquire_token_by_auth_code(self):
863866 scope = config ["scopes" ],
864867 )
865868
866- @unittest .skipIf (os .getenv ("TRAVIS" ), "Browser automation is not yet implemented" )
867869 def test_b2c_acquire_token_by_auth_code_flow (self ):
868870 self ._test_acquire_token_by_auth_code_flow (** dict (
869871 self .get_lab_user (usertype = "b2c" , b2cprovider = "local" ),
@@ -882,6 +884,18 @@ def test_b2c_acquire_token_by_ropc(self):
882884 scope = config ["scopes" ],
883885 )
884886
887+ def test_b2c_allows_using_client_id_as_scope (self ):
888+ # See also https://learn.microsoft.com/en-us/azure/active-directory-b2c/access-tokens#openid-connect-scopes
889+ config = self .get_lab_app_object (azureenvironment = "azureb2ccloud" )
890+ config ["scopes" ] = [config ["appId" ]]
891+ self ._test_username_password (
892+ authority = self ._build_b2c_authority ("B2C_1_ROPC_Auth" ),
893+ client_id = config ["appId" ],
894+ 895+ password = self .get_lab_user_secret ("msidlabb2c" ),
896+ scope = config ["scopes" ],
897+ )
898+
885899
886900class WorldWideRegionalEndpointTestCase (LabBasedTestCase ):
887901 region = "westus"
@@ -904,7 +918,7 @@ def _test_acquire_token_for_client(self, configured_region, expected_region):
904918 self .app .http_client , "post" , return_value = MinimalResponse (
905919 status_code = 400 , text = '{"error": "mock"}' )) as mocked_method :
906920 self .app .acquire_token_for_client (scopes )
907- expected_host = '{}.r. login.microsoftonline .com' .format (
921+ expected_host = '{}.login.microsoft .com' .format (
908922 expected_region ) if expected_region else 'login.microsoftonline.com'
909923 mocked_method .assert_called_with (
910924 'https://{}/{}/oauth2/v2.0/token' .format (
0 commit comments