@@ -38,11 +38,17 @@ def __init__(self):
3838 def find (self , credential_type , target = None , query = None ):
3939 target = target or []
4040 assert isinstance (target , list ), "Invalid parameter type"
41+ target_set = set (target )
4142 with self ._lock :
43+ # Since the target inside token cache key is (per schema) unsorted,
44+ # there is no point to attempt an O(1) key-value search here.
45+ # So we always do an O(n) in-memory search.
4246 return [entry
4347 for entry in self ._cache .get (credential_type , {}).values ()
4448 if is_subdict_of (query or {}, entry )
45- and set (target ) <= set (entry .get ("target" , []))]
49+ and (target_set <= set (entry .get ("target" , "" ).split ())
50+ if target else True )
51+ ]
4652
4753 def add (self , event ):
4854 # type: (dict) -> None
@@ -67,6 +73,7 @@ def add(self, event):
6773 environment = realm = None
6874 if "token_endpoint" in event :
6975 _ , environment , realm = canonicalize (event ["token_endpoint" ])
76+ target = ' ' .join (event .get ("scope" , [])) # Per schema, we don't sort it
7077
7178 with self ._lock :
7279
@@ -77,7 +84,7 @@ def add(self, event):
7784 self .CredentialType .ACCESS_TOKEN ,
7885 event .get ("client_id" , "" ),
7986 realm or "" ,
80- ' ' . join ( sorted ( event . get ( "scope" , []))) ,
87+ target ,
8188 ]).lower ()
8289 now = time .time ()
8390 self ._cache .setdefault (self .CredentialType .ACCESS_TOKEN , {})[key ] = {
@@ -86,7 +93,7 @@ def add(self, event):
8693 "home_account_id" : home_account_id ,
8794 "environment" : environment ,
8895 "client_id" : event .get ("client_id" ),
89- "target" : event . get ( "scope" ) ,
96+ "target" : target ,
9097 "realm" : realm ,
9198 "cached_at" : now ,
9299 "expires_on" : now + response .get ("expires_in" , 3599 ),
@@ -132,15 +139,15 @@ def add(self, event):
132139 if refresh_token :
133140 key = self ._build_rt_key (
134141 home_account_id , environment ,
135- event .get ("client_id" , "" ), event . get ( "scope" , []) )
142+ event .get ("client_id" , "" ), target )
136143 rt = {
137144 "credential_type" : self .CredentialType .REFRESH_TOKEN ,
138145 "secret" : refresh_token ,
139146 "home_account_id" : home_account_id ,
140147 "environment" : environment ,
141148 "client_id" : event .get ("client_id" ),
142149 # Fields below are considered optional
143- "target" : event . get ( "scope" ) ,
150+ "target" : target ,
144151 "client_info" : response .get ("client_info" ),
145152 }
146153 if "foci" in response :
@@ -158,7 +165,7 @@ def _build_rt_key(
158165 cls .CredentialType .REFRESH_TOKEN ,
159166 client_id or "" ,
160167 "" , # RT is cross-tenant in AAD
161- ' ' . join ( sorted ( target or [])) ,
168+ target ,
162169 ]).lower ()
163170
164171 def remove_rt (self , rt_item ):
0 commit comments