Skip to content

Commit 4a13407

Browse files
committed
refactor(providers): 🔨 replace interactive re-auth with manual expiry
Removes the interactive global re-authentication coordinator logic from Google and Qwen providers. Instead of attempting to launch an interactive OAuth flow (which blocks proxy operations), the system now immediately marks the credential as permanently expired and raises an error. - Remove `get_reauth_coordinator` usage in `GoogleOAuthBase` and `QwenAuthBase`. - Implement immediate credential expiration upon token refresh failure. - Raise `ValueError` with specific instructions to run `credential_tool.py` for recovery. - Simplify `IFlowAuthBase` expiration logic to strictly enforce manual re-authentication.
1 parent 2da1c3f commit 4a13407

File tree

3 files changed

+35
-53
lines changed

3 files changed

+35
-53
lines changed

src/rotator_library/providers/google_oauth_base.py

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -804,8 +804,7 @@ async def _process_refresh_queue(self):
804804
async with self._queue_tracking_lock:
805805
self._queued_credentials.discard(path)
806806
self._mark_credential_expired(
807-
path,
808-
f"Refresh token invalid (HTTP {status_code})"
807+
path, f"Refresh token invalid (HTTP {status_code})"
809808
)
810809
elif status_code == 400:
811810
# Check for invalid_grant
@@ -816,7 +815,7 @@ async def _process_refresh_queue(self):
816815
self._queued_credentials.discard(path)
817816
self._mark_credential_expired(
818817
path,
819-
f"Refresh token invalid (HTTP 400: invalid_grant)"
818+
f"Refresh token invalid (HTTP 400: invalid_grant)",
820819
)
821820
else:
822821
await self._handle_refresh_failure(
@@ -1171,8 +1170,7 @@ async def initialize_token(
11711170
if force_interactive:
11721171
if path:
11731172
self._mark_credential_expired(
1174-
path,
1175-
"Refresh token invalid - re-authentication required"
1173+
path, "Refresh token invalid - re-authentication required"
11761174
)
11771175
raise ValueError(
11781176
f"Credential '{display_name}' requires re-authentication. "
@@ -1191,29 +1189,21 @@ async def initialize_token(
11911189
return await self._refresh_token(path, creds)
11921190
except Exception as e:
11931191
lib_logger.warning(
1194-
f"Automatic token refresh for '{display_name}' failed: {e}. Proceeding to interactive login."
1192+
f"Automatic token refresh for '{display_name}' failed: {e}."
11951193
)
1194+
# Fall through to mark as expired
11961195

1197-
lib_logger.warning(
1198-
f"{self.ENV_PREFIX} OAuth token for '{display_name}' needs setup: {reason}."
1199-
)
1200-
1201-
# [GLOBAL REAUTH COORDINATION] Use the global coordinator to ensure
1202-
# only one interactive OAuth flow runs at a time across all providers
1203-
coordinator = get_reauth_coordinator()
1204-
1205-
# Define the interactive OAuth function to be executed by coordinator
1206-
async def _do_interactive_oauth():
1207-
return await self._perform_interactive_oauth(
1208-
path, creds, display_name
1196+
# [NO AUTO-REAUTH] Mark credential as permanently expired instead of
1197+
# launching interactive browser OAuth. This prevents blocking proxy
1198+
# operations. User must run credential_tool.py manually and restart proxy.
1199+
if path:
1200+
self._mark_credential_expired(
1201+
path,
1202+
f"{reason}. Manual re-authentication required via credential_tool.py",
12091203
)
1210-
1211-
# Execute via global coordinator (ensures only one at a time)
1212-
return await coordinator.execute_reauth(
1213-
credential_path=path or display_name,
1214-
provider_name=self.ENV_PREFIX,
1215-
reauth_func=_do_interactive_oauth,
1216-
timeout=300.0, # 5 minute timeout for user to complete OAuth
1204+
raise ValueError(
1205+
f"Credential '{display_name}' is expired and requires manual re-authentication. "
1206+
f"Run 'python credential_tool.py' to fix, then restart the proxy."
12171207
)
12181208

12191209
lib_logger.info(

src/rotator_library/providers/iflow_auth_base.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,18 +1326,18 @@ async def initialize_token(
13261326
)
13271327
# Fall through to mark as expired
13281328

1329-
# [NO AUTO-REAUTH] If force_interactive is True or refresh failed,
1330-
# mark the credential as permanently expired instead of launching browser OAuth.
1331-
# User must run credential_tool.py manually and restart proxy.
1332-
if force_interactive or reason != "token is expired":
1329+
# [NO AUTO-REAUTH] Mark credential as permanently expired instead of
1330+
# launching interactive browser OAuth. This prevents blocking proxy
1331+
# operations. User must run credential_tool.py manually and restart proxy.
1332+
if path:
13331333
self._mark_credential_expired(
13341334
path,
13351335
f"{reason}. Manual re-authentication required via credential_tool.py",
13361336
)
1337-
raise ValueError(
1338-
f"Credential '{display_name}' is expired and requires manual re-authentication. "
1339-
f"Run 'python credential_tool.py' to fix, then restart the proxy."
1340-
)
1337+
raise ValueError(
1338+
f"Credential '{display_name}' is expired and requires manual re-authentication. "
1339+
f"Run 'python credential_tool.py' to fix, then restart the proxy."
1340+
)
13411341

13421342
lib_logger.info(f"iFlow OAuth token at '{display_name}' is valid.")
13431343
return creds

src/rotator_library/providers/qwen_auth_base.py

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1004,29 +1004,21 @@ async def initialize_token(
10041004
return await self._refresh_token(path)
10051005
except Exception as e:
10061006
lib_logger.warning(
1007-
f"Automatic token refresh for '{display_name}' failed: {e}. Proceeding to interactive login."
1007+
f"Automatic token refresh for '{display_name}' failed: {e}."
10081008
)
1009+
# Fall through to mark as expired
10091010

1010-
lib_logger.warning(
1011-
f"Qwen OAuth token for '{display_name}' needs setup: {reason}."
1012-
)
1013-
1014-
# [GLOBAL REAUTH COORDINATION] Use the global coordinator to ensure
1015-
# only one interactive OAuth flow runs at a time across all providers
1016-
coordinator = get_reauth_coordinator()
1017-
1018-
# Define the interactive OAuth function to be executed by coordinator
1019-
async def _do_interactive_oauth():
1020-
return await self._perform_interactive_oauth(
1021-
path, creds, display_name
1011+
# [NO AUTO-REAUTH] Mark credential as permanently expired instead of
1012+
# launching interactive device OAuth. This prevents blocking proxy
1013+
# operations. User must run credential_tool.py manually and restart proxy.
1014+
if path:
1015+
self._mark_credential_expired(
1016+
path,
1017+
f"{reason}. Manual re-authentication required via credential_tool.py",
10221018
)
1023-
1024-
# Execute via global coordinator (ensures only one at a time)
1025-
return await coordinator.execute_reauth(
1026-
credential_path=path or display_name,
1027-
provider_name="QWEN_CODE",
1028-
reauth_func=_do_interactive_oauth,
1029-
timeout=300.0, # 5 minute timeout for user to complete OAuth
1019+
raise ValueError(
1020+
f"Credential '{display_name}' is expired and requires manual re-authentication. "
1021+
f"Run 'python credential_tool.py' to fix, then restart the proxy."
10301022
)
10311023

10321024
lib_logger.info(f"Qwen OAuth token at '{display_name}' is valid.")

0 commit comments

Comments
 (0)