2323)
2424from assisted_service_mcp .src .settings import settings
2525
26+ # Token expiration constants
27+ DEFAULT_TOKEN_EXPIRES_IN = 900 # 15 minutes in seconds
28+ TOKEN_EXPIRY_BUFFER = 300 # 5 minutes safety margin before expiration
29+
2630
2731class OAuthManager :
2832 """Manages OAuth authentication flow for the MCP server.
@@ -214,14 +218,14 @@ async def exchange_code_for_token(
214218
215219 # Create token object
216220 token_id = secrets .token_hex (16 )
217- expires_in = token_data .get ("expires_in" , 3600 )
221+ expires_in = token_data .get ("expires_in" , DEFAULT_TOKEN_EXPIRES_IN )
218222
219223 token = OAuthToken (
220224 token_id = token_id ,
221225 client_id = state .client_id ,
222226 access_token = token_data ["access_token" ],
223227 refresh_token = token_data .get ("refresh_token" ),
224- expires_at = time .time () + expires_in - 300 , # 5 min safety margin
228+ expires_at = time .time () + expires_in - TOKEN_EXPIRY_BUFFER ,
225229 )
226230
227231 # Store token
@@ -248,7 +252,8 @@ async def get_access_token_by_id(self, token_id: str) -> Optional[str]:
248252 Returns:
249253 Access token if found and valid, None otherwise
250254 """
251- token = self .token_store .get_token_by_id (token_id )
255+ # Get token including expired ones (for refresh purposes)
256+ token = self .token_store .get_token_by_id (token_id , include_expired = True )
252257 if not token :
253258 return None
254259
@@ -260,6 +265,8 @@ async def get_access_token_by_id(self, token_id: str) -> Optional[str]:
260265 token = self .token_store .get_token_by_id (token_id )
261266 return token .access_token if token else None
262267 log .warning ("Failed to refresh token %s" , token_id )
268+ # Clean up expired token if refresh failed
269+ self .token_store .remove_token (token_id )
263270 return None
264271
265272 return token .access_token
@@ -287,7 +294,8 @@ async def get_access_token_by_client(self, client_id: str) -> Optional[str]:
287294 Returns:
288295 Access token if found and valid, None otherwise
289296 """
290- token = self .token_store .get_token_by_client (client_id )
297+ # Get token including expired ones (for refresh purposes)
298+ token = self .token_store .get_token_by_client (client_id , include_expired = True )
291299 if not token :
292300 return None
293301
@@ -299,6 +307,8 @@ async def get_access_token_by_client(self, client_id: str) -> Optional[str]:
299307 token = self .token_store .get_token_by_client (client_id )
300308 return token .access_token if token else None
301309 log .warning ("Failed to refresh token for client %s" , client_id )
310+ # Clean up expired token if refresh failed
311+ self .token_store .remove_client_token (client_id )
302312 return None
303313
304314 return token .access_token
@@ -333,8 +343,8 @@ async def _refresh_token(self, token: OAuthToken) -> bool:
333343 # Update token in store
334344 new_access_token = token_data ["access_token" ]
335345 new_refresh_token = token_data .get ("refresh_token" , token .refresh_token )
336- expires_in = token_data .get ("expires_in" , 3600 )
337- new_expires_at = time .time () + expires_in - 300
346+ expires_in = token_data .get ("expires_in" , DEFAULT_TOKEN_EXPIRES_IN )
347+ new_expires_at = time .time () + expires_in - TOKEN_EXPIRY_BUFFER
338348
339349 self .token_store .update_token (
340350 token .token_id , new_access_token , new_refresh_token , new_expires_at
@@ -536,7 +546,7 @@ async def oauth_token_handler(request: Request) -> Dict[str, Any]:
536546 return {
537547 "access_token" : token .get ("access_token" ),
538548 "token_type" : token .get ("token_type" , "Bearer" ),
539- "expires_in" : token .get ("expires_in" , 3600 ),
549+ "expires_in" : token .get ("expires_in" , DEFAULT_TOKEN_EXPIRES_IN ),
540550 "refresh_token" : token .get ("refresh_token" ),
541551 "scope" : token .get ("scope" , "openid profile email" ),
542552 }
0 commit comments