get this keyring to stop mucking about

This commit is contained in:
adamhaley
2025-08-19 18:57:54 -07:00
parent 898fd78f60
commit c2538ec848
2 changed files with 40 additions and 16 deletions
+27 -13
View File
@@ -20,17 +20,26 @@ def setup_keyring_backend():
print(f"[DropboxAuthManager] Skipping interactive keyring ({keyring_name}) to avoid blocking")
raise Exception("Interactive keyring detected - using fallback")
# Test non-interactively
test_service = "test_keyring_availability"
keyring.set_password(test_service, "test", "test")
keyring.delete_password(test_service, "test")
# Test non-interactively with our actual service name to be more thorough
test_service = DROPBOX_KEYRING_SERVICE
test_key = "test_key_interactive_check"
test_value = "test_value"
print(f"[DropboxAuthManager] Testing keyring ({keyring_name}) for interactive prompts...")
keyring.set_password(test_service, test_key, test_value)
retrieved = keyring.get_password(test_service, test_key)
keyring.delete_password(test_service, test_key)
if retrieved != test_value:
raise Exception("Keyring test failed - retrieved value doesn't match")
print(f"[DropboxAuthManager] Using system keyring backend: {keyring_name}")
return True
except Exception as e:
print(f"[DropboxAuthManager] System keyring not available or interactive: {e}")
# Try keyrings.alt file-based backends
# Force fallback to plaintext file keyring to avoid any interactive prompts
try:
import keyrings.alt.file
@@ -44,7 +53,7 @@ def setup_keyring_backend():
keyring.set_keyring(file_keyring)
# Test it works
# Test the file keyring works
test_service = "test_file_keyring"
keyring.set_password(test_service, "test", "test")
keyring.delete_password(test_service, "test")
@@ -60,10 +69,6 @@ def setup_keyring_backend():
except Exception as file_error:
print(f"[DropboxAuthManager] File keyring failed: {file_error}")
return False
except Exception as e:
print(f"[DropboxAuthManager] All keyring backends failed: {e}")
return False
class DropboxAuthManager:
def __init__(self, app_key=None, app_secret=None):
@@ -120,10 +125,12 @@ class DropboxAuthManager:
return bool(self.app_key and self.app_secret and self.refresh_token)
def store_tokens(self, app_key, app_secret, refresh_token):
if not self._ensure_keyring_setup():
raise RuntimeError("Keyring not available. Please use 'env_file' or 'display_only' storage method instead.")
"""Store tokens in keyring with fallback for interactive keyrings"""
try:
if not self._ensure_keyring_setup():
raise RuntimeError("Keyring not available. Please use 'env_file' or 'display_only' storage method instead.")
print(f"[DropboxAuthManager] Storing tokens using keyring...")
keyring.set_password(DROPBOX_KEYRING_SERVICE, "app_key", app_key)
keyring.set_password(DROPBOX_KEYRING_SERVICE, "app_secret", app_secret)
keyring.set_password(DROPBOX_KEYRING_SERVICE, "refresh_token", refresh_token)
@@ -132,8 +139,15 @@ class DropboxAuthManager:
self.app_key = app_key
self.app_secret = app_secret
self.refresh_token = refresh_token
print(f"[DropboxAuthManager] Tokens stored successfully in keyring")
except KeyringError as e:
raise RuntimeError(f"Failed to store Dropbox tokens securely: {e}")
except Exception as e:
# Handle cases where keyring setup succeeded but storage fails (e.g., interactive prompts)
error_msg = f"Keyring storage failed - this may be due to interactive keyring prompts: {e}"
print(f"[DropboxAuthManager] {error_msg}")
raise RuntimeError(error_msg)
def exchange_auth_code(self, auth_code, redirect_uri=None):
if not (self.app_key and self.app_secret):
+13 -3
View File
@@ -46,19 +46,29 @@ class OAuthCallbackHandler:
print(f"[OAuthHandler] Redirect URI: {redirect_uri}")
# Use DropboxAuthManager to exchange the code
print(f"[OAuthHandler] Creating DropboxAuthManager for token exchange...")
auth_manager = DropboxAuthManager(self.app_key, self.app_secret)
print(f"[OAuthHandler] Exchanging auth code for tokens...")
result = auth_manager.exchange_auth_code_raw(auth_code, redirect_uri=redirect_uri)
refresh_token = result.get("refresh_token")
print(f"[OAuthHandler] Auth code exchange successful")
print(f"[OAuthHandler] Auth code exchange successful - got refresh token: {bool(refresh_token)}")
print(f"[OAuthHandler] Using storage method: {self.storage_method}")
# Handle different storage methods
success_message = None
if self.storage_method == "keyring":
# Store in system keyring (original behavior)
auth_manager.store_tokens(self.app_key, self.app_secret, refresh_token)
success_message = "✅ Dropbox connected successfully! Credentials stored securely in system keyring."
print(f"[OAuthHandler] Attempting to store tokens in keyring...")
try:
auth_manager.store_tokens(self.app_key, self.app_secret, refresh_token)
print(f"[OAuthHandler] Tokens stored in keyring successfully")
success_message = "✅ Dropbox connected successfully! Credentials stored securely in system keyring."
except Exception as e:
print(f"[OAuthHandler] ERROR storing tokens in keyring: {e}")
# Fall back to display_only if keyring fails
success_message = f"⚠️ Keyring storage failed: {e}. Please use 'display_only' or 'env_file' storage method."
return False, success_message
elif self.storage_method == "env_file":
# Store in .env file