bibibi12345 commited on
Commit
c4bce18
·
1 Parent(s): 4e13286

fixing relogin problem

Browse files
Files changed (1) hide show
  1. src/auth.py +101 -29
src/auth.py CHANGED
@@ -103,6 +103,7 @@ def save_credentials(creds, project_id=None):
103
  expiry_utc = creds.expiry.replace(tzinfo=timezone.utc)
104
  else:
105
  expiry_utc = creds.expiry
 
106
  creds_data["expiry"] = expiry_utc.isoformat()
107
 
108
  if project_id:
@@ -153,40 +154,111 @@ def get_credentials():
153
 
154
  # Check for credentials file (CREDENTIAL_FILE now includes GOOGLE_APPLICATION_CREDENTIALS path if set)
155
  if os.path.exists(CREDENTIAL_FILE):
 
156
  try:
157
  with open(CREDENTIAL_FILE, "r") as f:
158
- creds_data = json.load(f)
159
-
160
- # Handle different credential formats
161
- if "access_token" in creds_data and "token" not in creds_data:
162
- creds_data["token"] = creds_data["access_token"]
163
-
164
- if "scope" in creds_data and "scopes" not in creds_data:
165
- creds_data["scopes"] = creds_data["scope"].split()
166
 
167
- credentials = Credentials.from_authorized_user_info(creds_data, SCOPES)
168
- # Mark as environment credentials if GOOGLE_APPLICATION_CREDENTIALS was used
169
- credentials_from_env = bool(os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
170
-
171
- # Try to refresh if expired and refresh token exists
172
- if credentials.expired and credentials.refresh_token:
173
  try:
174
- logging.info("File-based credentials expired, attempting refresh...")
175
- credentials.refresh(GoogleAuthRequest())
176
- logging.info("File-based credentials refreshed successfully")
177
- save_credentials(credentials)
178
- except Exception as refresh_error:
179
- logging.warning(f"Failed to refresh file-based credentials: {refresh_error}")
180
- logging.info("Using existing file-based credentials despite refresh failure")
181
- elif not credentials.expired:
182
- logging.info("File-based credentials are still valid, no refresh needed")
183
- elif not credentials.refresh_token:
184
- logging.warning("File-based credentials expired but no refresh token available")
185
-
186
- return credentials
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  except Exception as e:
188
- logging.error(f"Failed to load credentials from file {CREDENTIAL_FILE}: {e}")
189
- # Fall through to new login only if credentials are completely unusable
190
 
191
  client_config = {
192
  "installed": {
 
103
  expiry_utc = creds.expiry.replace(tzinfo=timezone.utc)
104
  else:
105
  expiry_utc = creds.expiry
106
+ # Keep the existing ISO format for backward compatibility, but ensure it's properly handled during loading
107
  creds_data["expiry"] = expiry_utc.isoformat()
108
 
109
  if project_id:
 
154
 
155
  # Check for credentials file (CREDENTIAL_FILE now includes GOOGLE_APPLICATION_CREDENTIALS path if set)
156
  if os.path.exists(CREDENTIAL_FILE):
157
+ # First, check if we have a refresh token - if so, we should always be able to load credentials
158
  try:
159
  with open(CREDENTIAL_FILE, "r") as f:
160
+ raw_creds_data = json.load(f)
 
 
 
 
 
 
 
161
 
162
+ # SAFEGUARD: If refresh_token exists, we should always load credentials successfully
163
+ if "refresh_token" in raw_creds_data and raw_creds_data["refresh_token"]:
164
+ logging.info("Refresh token found - ensuring credentials load successfully")
165
+
 
 
166
  try:
167
+ creds_data = raw_creds_data.copy()
168
+
169
+ # Handle different credential formats
170
+ if "access_token" in creds_data and "token" not in creds_data:
171
+ creds_data["token"] = creds_data["access_token"]
172
+
173
+ if "scope" in creds_data and "scopes" not in creds_data:
174
+ creds_data["scopes"] = creds_data["scope"].split()
175
+
176
+ # Handle problematic expiry formats that cause parsing errors
177
+ if "expiry" in creds_data:
178
+ expiry_str = creds_data["expiry"]
179
+ # If expiry has timezone info that causes parsing issues, try to fix it
180
+ if isinstance(expiry_str, str) and ("+00:00" in expiry_str or "Z" in expiry_str):
181
+ try:
182
+ # Try to parse and reformat the expiry to a format Google Credentials can handle
183
+ from datetime import datetime
184
+ if "+00:00" in expiry_str:
185
+ # Handle ISO format with timezone offset
186
+ parsed_expiry = datetime.fromisoformat(expiry_str)
187
+ elif expiry_str.endswith("Z"):
188
+ # Handle ISO format with Z suffix
189
+ parsed_expiry = datetime.fromisoformat(expiry_str.replace('Z', '+00:00'))
190
+ else:
191
+ parsed_expiry = datetime.fromisoformat(expiry_str)
192
+
193
+ # Convert to UTC timestamp format that Google Credentials library expects
194
+ import time
195
+ timestamp = parsed_expiry.timestamp()
196
+ creds_data["expiry"] = datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%dT%H:%M:%SZ")
197
+ logging.info(f"Converted expiry format from '{expiry_str}' to '{creds_data['expiry']}'")
198
+ except Exception as expiry_error:
199
+ logging.warning(f"Could not parse expiry format '{expiry_str}': {expiry_error}, removing expiry field")
200
+ # Remove problematic expiry field - credentials will be treated as expired but still loadable
201
+ del creds_data["expiry"]
202
+
203
+ credentials = Credentials.from_authorized_user_info(creds_data, SCOPES)
204
+ # Mark as environment credentials if GOOGLE_APPLICATION_CREDENTIALS was used
205
+ credentials_from_env = bool(os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
206
+
207
+ # Try to refresh if expired and refresh token exists
208
+ if credentials.expired and credentials.refresh_token:
209
+ try:
210
+ logging.info("File-based credentials expired, attempting refresh...")
211
+ credentials.refresh(GoogleAuthRequest())
212
+ logging.info("File-based credentials refreshed successfully")
213
+ save_credentials(credentials)
214
+ except Exception as refresh_error:
215
+ logging.warning(f"Failed to refresh file-based credentials: {refresh_error}")
216
+ logging.info("Using existing file-based credentials despite refresh failure")
217
+ elif not credentials.expired:
218
+ logging.info("File-based credentials are still valid, no refresh needed")
219
+ elif not credentials.refresh_token:
220
+ logging.warning("File-based credentials expired but no refresh token available")
221
+
222
+ return credentials
223
+
224
+ except Exception as parsing_error:
225
+ # SAFEGUARD: Even if parsing fails, try to create minimal credentials with refresh token
226
+ logging.warning(f"Failed to parse credentials normally: {parsing_error}")
227
+ logging.info("Attempting to create minimal credentials with refresh token")
228
+
229
+ try:
230
+ minimal_creds_data = {
231
+ "client_id": raw_creds_data.get("client_id", CLIENT_ID),
232
+ "client_secret": raw_creds_data.get("client_secret", CLIENT_SECRET),
233
+ "refresh_token": raw_creds_data["refresh_token"],
234
+ "token_uri": "https://oauth2.googleapis.com/token",
235
+ }
236
+
237
+ credentials = Credentials.from_authorized_user_info(minimal_creds_data, SCOPES)
238
+ credentials_from_env = bool(os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
239
+
240
+ # Force refresh since we don't have a valid token
241
+ try:
242
+ logging.info("Refreshing minimal credentials...")
243
+ credentials.refresh(GoogleAuthRequest())
244
+ logging.info("Minimal credentials refreshed successfully")
245
+ save_credentials(credentials)
246
+ return credentials
247
+ except Exception as refresh_error:
248
+ logging.error(f"Failed to refresh minimal credentials: {refresh_error}")
249
+ # Even if refresh fails, return the credentials - they might still work
250
+ return credentials
251
+
252
+ except Exception as minimal_error:
253
+ logging.error(f"Failed to create minimal credentials: {minimal_error}")
254
+ # Fall through to new login as last resort
255
+ else:
256
+ logging.warning("No refresh token found in credentials file")
257
+ # Fall through to new login
258
+
259
  except Exception as e:
260
+ logging.error(f"Failed to read credentials file {CREDENTIAL_FILE}: {e}")
261
+ # Fall through to new login only if file is completely unreadable
262
 
263
  client_config = {
264
  "installed": {