22
22
from .region import _detect_region
23
23
from .throttled_http_client import ThrottledHttpClient
24
24
from .cloudshell import _is_running_in_cloud_shell
25
- from .cloudshell import _acquire_token as _acquire_token_by_cloud_shell
26
25
27
26
28
27
# The __init__.py will import this. Not the other way around.
29
28
__version__ = "1.17.0" # When releasing, also check and bump our dependencies's versions if needed
30
29
31
30
logger = logging .getLogger (__name__ )
32
- CURRENT_USER = "Current User" # The value is subject to change
33
- _CLOUD_SHELL_USER = "current_cloud_shell_user" # The value is subject to change
34
-
31
+ _AUTHORITY_TYPE_CLOUDSHELL = "CLOUDSHELL"
35
32
36
33
def extract_certs (public_cert_content ):
37
34
# Parses raw public certificate file contents and returns a list of strings
@@ -118,8 +115,6 @@ def _preferred_browser():
118
115
return None
119
116
120
117
121
-
122
-
123
118
class _ClientWithCcsRoutingInfo (Client ):
124
119
125
120
def initiate_auth_code_flow (self , ** kwargs ):
@@ -950,16 +945,6 @@ def get_accounts(self, username=None):
950
945
Your app can choose to display those information to end user,
951
946
and allow user to choose one of his/her accounts to proceed.
952
947
"""
953
- cloud_shell_pseudo_account = {
954
- "home_account_id" : _CLOUD_SHELL_USER ,
955
- "environment" : "" ,
956
- "realm" : "" ,
957
- "local_account_id" : _CLOUD_SHELL_USER ,
958
- "username" : CURRENT_USER ,
959
- "authority_type" : TokenCache .AuthorityType .MSSTS ,
960
- }
961
- if _is_running_in_cloud_shell () and username == CURRENT_USER :
962
- return [cloud_shell_pseudo_account ]
963
948
accounts = self ._find_msal_accounts (environment = self .authority .instance )
964
949
if not accounts : # Now try other aliases of this authority instance
965
950
for alias in self ._get_authority_aliases (self .authority .instance ):
@@ -978,13 +963,6 @@ def get_accounts(self, username=None):
978
963
"they would contain no username for filtering. "
979
964
"Consider calling get_accounts(username=None) instead."
980
965
).format (username ))
981
- if _is_running_in_cloud_shell () and not username :
982
- # In Cloud Shell, user already signed in w/ an account [email protected]
983
- # We pretend we have that account, for acquire_token_silent() to work.
984
- # Note: If user calls acquire_token_by_xyz() with same account later,
985
- # the get_accounts(username=None) would return multiple accounts,
986
- # with different usernames: [email protected] and CURRENT_USER.
987
- accounts .insert (0 , cloud_shell_pseudo_account )
988
966
# Does not further filter by existing RTs here. It probably won't matter.
989
967
# Because in most cases Accounts and RTs co-exist.
990
968
# Even in the rare case when an RT is revoked and then removed,
@@ -993,6 +971,10 @@ def get_accounts(self, username=None):
993
971
return accounts
994
972
995
973
def _find_msal_accounts (self , environment ):
974
+ interested_authority_types = [
975
+ TokenCache .AuthorityType .ADFS , TokenCache .AuthorityType .MSSTS ]
976
+ if _is_running_in_cloud_shell ():
977
+ interested_authority_types .append (_AUTHORITY_TYPE_CLOUDSHELL )
996
978
grouped_accounts = {
997
979
a .get ("home_account_id" ): # Grouped by home tenant's id
998
980
{ # These are minimal amount of non-tenant-specific account info
@@ -1008,8 +990,7 @@ def _find_msal_accounts(self, environment):
1008
990
for a in self .token_cache .find (
1009
991
TokenCache .CredentialType .ACCOUNT ,
1010
992
query = {"environment" : environment })
1011
- if a ["authority_type" ] in (
1012
- TokenCache .AuthorityType .ADFS , TokenCache .AuthorityType .MSSTS )
993
+ if a ["authority_type" ] in interested_authority_types
1013
994
}
1014
995
return list (grouped_accounts .values ())
1015
996
@@ -1069,6 +1050,21 @@ def _forget_me(self, home_account):
1069
1050
TokenCache .CredentialType .ACCOUNT , query = owned_by_home_account ):
1070
1051
self .token_cache .remove_account (a )
1071
1052
1053
+ def _acquire_token_by_cloud_shell (self , scopes , data = None ):
1054
+ from .cloudshell import _acquire_token
1055
+ response = _acquire_token (
1056
+ self .http_client , scopes , client_id = self .client_id , data = data )
1057
+ if "error" not in response :
1058
+ self .token_cache .add (dict (
1059
+ client_id = self .client_id ,
1060
+ scope = response ["scope" ].split () if "scope" in response else scopes ,
1061
+ token_endpoint = self .authority .token_endpoint ,
1062
+ response = response .copy (),
1063
+ data = data or {},
1064
+ authority_type = _AUTHORITY_TYPE_CLOUDSHELL ,
1065
+ ))
1066
+ return response
1067
+
1072
1068
def acquire_token_silent (
1073
1069
self ,
1074
1070
scopes , # type: List[str]
@@ -1148,13 +1144,6 @@ def acquire_token_silent_with_error(
1148
1144
"""
1149
1145
assert isinstance (scopes , list ), "Invalid parameter type"
1150
1146
self ._validate_ssh_cert_input_data (kwargs .get ("data" , {}))
1151
-
1152
- # The special code path only for _CLOUD_SHELL_USER
1153
- if account and account .get ("home_account_id" ) == _CLOUD_SHELL_USER :
1154
- # Since we don't currently store cloud shell tokens in MSAL's cache,
1155
- # we can have a shortcut here, and semantically bypass all those
1156
- # _acquire_token_silent_from_cache_and_possibly_refresh_it()
1157
- return _acquire_token_by_cloud_shell (self .http_client , scopes , ** kwargs )
1158
1147
correlation_id = msal .telemetry ._get_new_correlation_id ()
1159
1148
if authority :
1160
1149
warnings .warn ("We haven't decided how/if this method will accept authority parameter" )
@@ -1209,6 +1198,7 @@ def _acquire_token_silent_from_cache_and_possibly_refresh_it(
1209
1198
authority , # This can be different than self.authority
1210
1199
force_refresh = False , # type: Optional[boolean]
1211
1200
claims_challenge = None ,
1201
+ correlation_id = None ,
1212
1202
** kwargs ):
1213
1203
access_token_from_cache = None
1214
1204
if not (force_refresh or claims_challenge ): # Bypass AT when desired or using claims
@@ -1247,14 +1237,13 @@ def _acquire_token_silent_from_cache_and_possibly_refresh_it(
1247
1237
refresh_reason = msal .telemetry .FORCE_REFRESH # TODO: It could also mean claims_challenge
1248
1238
assert refresh_reason , "It should have been established at this point"
1249
1239
try :
1250
- ## When/if we will store Cloud Shell tokens into MSAL's token cache,
1251
- # then we will add the following code snippet here.
1252
- #if account and account.get("home_account_id") == _CLOUD_SHELL_USER:
1253
- # result = _acquire_token_by_cloud_shell(..., scopes, **kwargs)
1254
- #else:
1240
+ if account and account .get ("authority_type" ) == _AUTHORITY_TYPE_CLOUDSHELL :
1241
+ return self ._acquire_token_by_cloud_shell (
1242
+ scopes , data = kwargs .get ("data" ))
1255
1243
result = _clean_up (self ._acquire_token_silent_by_finding_rt_belongs_to_me_or_my_family (
1256
1244
authority , self ._decorate_scope (scopes ), account ,
1257
1245
refresh_reason = refresh_reason , claims_challenge = claims_challenge ,
1246
+ correlation_id = correlation_id ,
1258
1247
** kwargs ))
1259
1248
if (result and "error" not in result ) or (not access_token_from_cache ):
1260
1249
return result
@@ -1593,6 +1582,9 @@ def acquire_token_interactive(
1593
1582
- A dict containing an "error" key, when token refresh failed.
1594
1583
"""
1595
1584
self ._validate_ssh_cert_input_data (kwargs .get ("data" , {}))
1585
+ if _is_running_in_cloud_shell () and prompt == "none" :
1586
+ return self ._acquire_token_by_cloud_shell (
1587
+ scopes , data = kwargs .pop ("data" , {}))
1596
1588
claims = _merge_claims_challenge_and_capabilities (
1597
1589
self ._client_capabilities , claims_challenge )
1598
1590
telemetry_context = self ._build_telemetry_context (
0 commit comments