Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/jwt/jwk_set_cache.py: 39%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import time
2from typing import Any, Optional, Union
4from .api_jwk import PyJWKSet, PyJWTSetWithTimestamp
5from .exceptions import PyJWKSetError
8class JWKSetCache:
9 def __init__(self, lifespan: float) -> None:
10 self.jwk_set_with_timestamp: Optional[PyJWTSetWithTimestamp] = None
11 self.lifespan = lifespan
13 def put(self, jwk_set: Optional[Union[PyJWKSet, dict[str, Any]]]) -> None:
14 """Cache *jwk_set*, or clear the cache when it is ``None``.
16 Accepts either an already-parsed ``PyJWKSet`` or the raw JWKS
17 payload it is parsed from, and always stores it parsed so that
18 reads never have to parse the keys again.
20 :raises PyJWKSetError: If *jwk_set* is neither a ``PyJWKSet`` nor a
21 JWKS payload containing usable keys.
22 """
23 if jwk_set is None:
24 # clear cache
25 self.jwk_set_with_timestamp = None
26 return
28 if not isinstance(jwk_set, PyJWKSet):
29 if not isinstance(jwk_set, dict):
30 raise PyJWKSetError("Invalid JWK Set value")
31 jwk_set = PyJWKSet.from_dict(jwk_set)
33 self.jwk_set_with_timestamp = PyJWTSetWithTimestamp(jwk_set)
35 def get(self) -> Optional[PyJWKSet]:
36 if self.jwk_set_with_timestamp is None or self.is_expired():
37 return None
39 return self.jwk_set_with_timestamp.get_jwk_set()
41 def is_expired(self) -> bool:
42 return (
43 self.jwk_set_with_timestamp is not None
44 and self.lifespan > -1
45 and time.monotonic()
46 > self.jwk_set_with_timestamp.get_timestamp() + self.lifespan
47 )