Skip to content

Commit a3df9d7

Browse files
authored
Handle refresh token error and change of endpoint (#65)
* reauthenticate if refresh token expiry is too close and if endpoint changes * improve
1 parent 7239c83 commit a3df9d7

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

cirro/api/auth/oauth_client.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
import threading
55
import time
6-
from datetime import datetime
6+
from datetime import datetime, timedelta
77
from pathlib import Path
88
from typing import Optional
99

@@ -12,6 +12,7 @@
1212
import requests
1313
from botocore.exceptions import ClientError
1414
from msal_extensions import FilePersistence
15+
from msal_extensions.persistence import BasePersistence
1516
from requests.auth import AuthBase
1617

1718
from cirro.api.auth.base import AuthInfo, RequestAuthWrapper
@@ -85,13 +86,26 @@ class ClientAuth(AuthInfo):
8586
def __init__(self, client_id: str, region: str, auth_endpoint: str, enable_cache=True):
8687
self.client_id = client_id
8788
self.region = region
88-
self._token_info = None
89-
self._persistence = None
89+
self._token_info: Optional[OAuthTokenResponse] = None
90+
self._persistence: Optional[BasePersistence] = None
9091

9192
if enable_cache:
9293
self._persistence = _build_token_persistence(str(TOKEN_PATH), fallback_to_plaintext=True)
9394
self._token_info = self._load_token_info()
9495

96+
# Check saved token for change in endpoint
97+
if self._token_info and self._token_info.get('client_id') != client_id:
98+
logger.debug('Different client ID found, clearing saved token info')
99+
self._clear_token_info()
100+
101+
# Check saved token for refresh token expiry
102+
if self._token_info and self._token_info.get('refresh_expires_in'):
103+
refresh_expiry_threshold = datetime.fromtimestamp(self._token_info.get('refresh_expires_in'))\
104+
- timedelta(hours=12)
105+
if refresh_expiry_threshold < datetime.now():
106+
logger.debug('Refresh token expiry is too soon, re-authenticating')
107+
self._clear_token_info()
108+
95109
if not self._token_info:
96110
self._token_info = _authenticate(client_id=client_id, auth_endpoint=auth_endpoint)
97111

@@ -162,3 +176,4 @@ def _clear_token_info(self):
162176
return
163177

164178
Path(self._persistence.get_location()).unlink(missing_ok=True)
179+
self._token_info = None

cirro/api/models/auth.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,6 @@ class OAuthTokenResponse(TypedDict):
2424
id_token: str
2525
token_type: str
2626
expires_in: int
27+
refresh_expires_in: int
28+
client_id: str
2729
message: Optional[str]

0 commit comments

Comments
 (0)