feat(scouts): pending-session Gmail OAuth — create cloud scout at finalize
Refactor _pending_scout_oauth_states from a tuple to a dict carrying mode (reconnect|create), draft fields, and a transient encrypted token. Add authorize-draft, session-labels, and cloud/finalize endpoints so the scout row is created only when the flow completes — abandoned flows leave no orphan rows. Zero-trust: the encrypted token lives only in the in-memory session (<=15 min) until finalize persists it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,12 +45,15 @@ def _extract_plain_text_body(payload: dict) -> str:
|
||||
return ""
|
||||
|
||||
|
||||
def _get_gmail_service(scout):
|
||||
"""Return a synchronous Google API client for low-level metadata/history calls."""
|
||||
def _gmail_service_from_token(creds_info: dict):
|
||||
"""Build a synchronous Gmail API client from a decrypted credentials dict.
|
||||
|
||||
Shared by ``_get_gmail_service`` (scout-backed) and the pending-session
|
||||
OAuth flow which has a raw token but no scout row yet.
|
||||
"""
|
||||
from googleapiclient.discovery import build
|
||||
from google.oauth2.credentials import Credentials
|
||||
|
||||
creds_info = decrypt_token(scout.oauth_token_encrypted)
|
||||
credentials = Credentials(
|
||||
token=creds_info.get("token"),
|
||||
refresh_token=creds_info.get("refresh_token"),
|
||||
@@ -62,6 +65,12 @@ def _get_gmail_service(scout):
|
||||
return build("gmail", "v1", credentials=credentials, cache_discovery=False)
|
||||
|
||||
|
||||
def _get_gmail_service(scout):
|
||||
"""Return a synchronous Google API client for low-level metadata/history calls."""
|
||||
creds_info = decrypt_token(scout.oauth_token_encrypted)
|
||||
return _gmail_service_from_token(creds_info)
|
||||
|
||||
|
||||
class GmailConnector:
|
||||
source_type = "gmail"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user