1717# Set up logger for this module
1818logger = get_logger (__name__ )
1919
20- # TTL cache for token validation (1 hour TTL, max 1000 entries)
21- _token_cache : cachetools .TTLCache [str , "UserInfo" ] = cachetools .TTLCache (
20+ # TTL cache keyed by a user's OIDC subject. Evict entries when roles change. We
21+ # still validate the JWT signature and expiry on every request before reading a
22+ # cached record.
23+ _user_info_cache : cachetools .TTLCache [str , "UserInfo" ] = cachetools .TTLCache (
2224 maxsize = 1000 , ttl = 60 * 60
2325)
2426
@@ -41,6 +43,17 @@ async def close_tdei_client() -> None:
4143 _tdei_client = None
4244
4345
46+ def evict_user_from_cache (auth_uid : str ) -> None :
47+ """
48+ Evict a user's cached UserInfo object so that their next request re-fetches
49+ permissions.
50+
51+ Call this after modifying a user's roles in the OSM DB to ensure the change
52+ takes effect on their next request rather than after the cache TTL expires.
53+ """
54+ _user_info_cache .pop (auth_uid , None )
55+
56+
4457security = HTTPBearer ()
4558
4659
@@ -151,9 +164,13 @@ async def validate_token(
151164 osm_db_session : AsyncSession = Depends (get_osm_db_session ),
152165 task_db_session : AsyncSession = Depends (get_task_db_session ),
153166) -> UserInfo :
154- """Dependency to get current authenticated user from TDEI/KeyCloak token and APIs.
167+ """
168+ Dependency that gets the current authenticated user from the TDEI/KeyCloak
169+ access token and fetches permissions from TDEI APIs.
155170
156- Results are cached by token for 1 hour to avoid repeated validation calls.
171+ The JWT signature and expiry are validated on every request. The expensive
172+ TDEI API and DB lookups are cached for 1 hour and should be evicted when a
173+ user's role changes via evict_user_from_cache().
157174 """
158175 token = credentials .credentials
159176
@@ -172,16 +189,16 @@ async def validate_token(
172189 if user_id is None :
173190 raise credentials_exception
174191
175- # Check cache first
176- if token in _token_cache :
192+ # Cache keyed by user ID so roles take effect immediately after eviction:
193+ if user_id in _user_info_cache :
177194 logger .info ("Token validation cache hit" )
178- return _token_cache [ token ]
195+ return _user_info_cache [ user_id ]
179196
180- # Cache miss - perform full validation
197+ # Cache miss: fetch TDEI roles and DB data:
181198 user_info = await _validate_token_uncached (
182199 token , user_id , payload , osm_db_session , task_db_session
183200 )
184- _token_cache [ token ] = user_info
201+ _user_info_cache [ user_id ] = user_info
185202
186203 return user_info
187204
0 commit comments