diff --git a/backend/routers/gsc_auth.py b/backend/routers/gsc_auth.py index f117f1a9..f0ddac2d 100644 --- a/backend/routers/gsc_auth.py +++ b/backend/routers/gsc_auth.py @@ -4,12 +4,12 @@ All legacy endpoints are preserved with deprecation warnings for backward compatibility. """ -from fastapi import APIRouter, HTTPException, Depends, Query -from fastapi.responses import HTMLResponse, JSONResponse +from fastapi import APIRouter, HTTPException, Depends, Query, Request +from fastapi.responses import HTMLResponse from typing import Dict, List, Any, Optional from pydantic import BaseModel from loguru import logger -import os +from urllib.parse import parse_qs, urlparse # Import unified OAuth client for migration from services.integrations.registry import get_provider @@ -23,6 +23,9 @@ from services.gsc_service import GSCService gsc_service = GSCService() + +DEPRECATED_GSC_LEGACY_ROUTES_REMOVAL_DATE = "2026-06-30" + def _get_gsc_postmessage_origin() -> str: return get_trusted_origins_for_redirect("GSC", "GSC_REDIRECT_URI")[0] @@ -49,15 +52,31 @@ class GSCCallbackResponse(BaseModel): connected: Optional[bool] = None site_count: Optional[int] = None + +class GSCDataQualityResponse(BaseModel): + site_url: str + permission_level: Optional[str] = None + has_sufficient_permission: bool + data_days_available: int + data_window_start: Optional[str] = None + data_window_end: Optional[str] = None + indexing_health: Dict[str, Any] + + +class GSCCachedOpportunitiesResponse(BaseModel): + site_url: str + opportunities: List[Dict[str, Any]] + generated_from_cache: bool + @router.get("/auth/url") -async def get_gsc_auth_url(user: dict = Depends(get_current_user)): +async def get_gsc_auth_url(request: Request, user: dict = Depends(get_current_user)): """ Get Google Search Console OAuth authorization URL. @deprecated Use unified OAuth client: unifiedOAuthClient.getAuthUrl('gsc') This method is preserved for backward compatibility but will be removed in future versions. """ - console.warn('GSC Router: get_gsc_auth_url() is deprecated. Use unifiedOAuthClient.getAuthUrl("gsc") instead') + logger.warning(f'GSC Router: /gsc/auth/url is deprecated; use /oauth/gsc/auth. Planned removal after {DEPRECATED_GSC_LEGACY_ROUTES_REMOVAL_DATE}') try: user_id = user.get('id') @@ -66,32 +85,29 @@ async def get_gsc_auth_url(user: dict = Depends(get_current_user)): logger.info(f"Generating GSC OAuth URL for user: {user_id}") - # Use unified OAuth client for consistent patterns - from frontend.src.api.unifiedOAuth import unifiedOAuthClient - unified_client = unifiedOAuthClient() - - try: - auth_response = await unified_client.getAuthUrl('gsc') - - return { - "auth_url": auth_response.auth_url, - "state": auth_response.state, - "trusted_origins": auth_response.trusted_origins - } - except Exception as unified_error: - # Fall back to legacy service if unified client fails - logger.warning(f"Unified client failed, falling back to legacy GSC service: {unified_error}") - - auth_url = gsc_service.get_oauth_url(user_id) - - return { - "auth_url": auth_url, - "state": gsc_service.get_oauth_state(user_id), - "trusted_origins": get_trusted_origins_for_redirect("GSC", "GSC_REDIRECT_URI") - } + provider = get_provider("gsc") + if not provider: + raise HTTPException(status_code=500, detail="GSC provider not registered") + + auth_payload = provider.get_auth_url(user_id) + if not auth_payload.auth_url: + raise HTTPException(status_code=500, detail="Failed to generate GSC OAuth URL") + + parsed_query = parse_qs(urlparse(auth_payload.auth_url).query) + state = parsed_query.get("state", [auth_payload.state or ""])[0] + + trusted_origins = get_trusted_origins_for_redirect("GSC", "GSC_REDIRECT_URI") + backend_origin = str(request.base_url).rstrip("/") + if backend_origin not in trusted_origins: + trusted_origins.append(backend_origin) + + return { + "auth_url": auth_payload.auth_url, + "state": state, + "trusted_origins": trusted_origins + } logger.info(f"GSC OAuth URL generated successfully for user: {user_id}") - logger.info(f"OAuth URL: {auth_url[:100]}...") except Exception as e: logger.error(f"Error generating GSC OAuth URL: {e}") @@ -153,7 +169,10 @@ async def handle_gsc_callback(
Connection Successful. You can close this window.
@@ -169,7 +188,10 @@ async def handle_gsc_callback(Connection Failed. Please close this window and try again.