MCPcopy Create free account
hub / github.com/AzureAD/microsoft-authentication-library-for-python / search

Method search

msal/token_cache.py:236–289  ·  view source on GitHub ↗

Returns a generator of matching entries. It is O(1) for AT hits, and O(n) for other types. Note that it holds a lock during the entire search.

(self, credential_type, target=None, query=None, *, now=None)

Source from the content-addressed store, hash-verified

234 if target_set else True)
235
236 def search(self, credential_type, target=None, query=None, *, now=None): # O(n) generator
237 """Returns a generator of matching entries.
238
239 It is O(1) for AT hits, and O(n) for other types.
240 Note that it holds a lock during the entire search.
241 """
242 target = sorted(target or []) # Match the order sorted by add()
243 assert isinstance(target, list), "Invalid parameter type"
244
245 preferred_result = None
246 if (credential_type == self.CredentialType.ACCESS_TOKEN
247 and isinstance(query, dict)
248 and "home_account_id" in query and "environment" in query
249 and "client_id" in query and "realm" in query and target
250 ): # Special case for O(1) AT lookup
251 preferred_result = self._get_access_token(
252 query["home_account_id"], query["environment"],
253 query["client_id"], query["realm"], target,
254 ext_cache_key=query.get("ext_cache_key"))
255 if preferred_result and self._is_matching(
256 preferred_result, query,
257 # Needs no target_set here because it is satisfied by dict key
258 ):
259 yield preferred_result
260
261 target_set = set(target)
262 with self._lock:
263 # O(n) search. The key is NOT used in search.
264 now = int(time.time() if now is None else now)
265 expired_access_tokens = [
266 # Especially when/if we key ATs by ephemeral fields such as key_id,
267 # stale ATs keyed by an old key_id would stay forever.
268 # Here we collect them for their removal.
269 ]
270 for entry in self._cache.get(credential_type, {}).values():
271 if ( # Automatically delete expired access tokens
272 credential_type == self.CredentialType.ACCESS_TOKEN
273 and int(entry["expires_on"]) < now
274 ):
275 expired_access_tokens.append(entry) # Can't delete them within current for-loop
276 continue
277 if (entry != preferred_result # Avoid yielding the same entry twice
278 and self._is_matching(entry, query, target_set=target_set)
279 ):
280 # Cache isolation for extended cache keys (e.g., FMI path).
281 # Entries with ext_cache_key must not match queries without one.
282 if (credential_type == self.CredentialType.ACCESS_TOKEN
283 and "ext_cache_key" in entry
284 and "ext_cache_key" not in (query or {})
285 ):
286 continue
287 yield entry
288 for at in expired_access_tokens:
289 self.remove_at(at)
290
291 def find(self, credential_type, target=None, query=None, *, now=None):
292 """Equivalent to list(search(...))."""

Calls 4

_get_access_tokenMethod · 0.95
_is_matchingMethod · 0.95
remove_atMethod · 0.95
getMethod · 0.45