defmodule BerrypodWeb.GSCAuthController do @moduledoc """ Handles Google Search Console OAuth flow. """ use BerrypodWeb, :controller alias Berrypod.GSC.{Cache, OAuth} @doc """ Initiates the OAuth flow by redirecting to Google's consent screen. """ def connect(conn, _params) do case OAuth.authorize_url() do {:ok, url} -> redirect(conn, external: url) {:error, :missing_client_id} -> conn |> put_flash( :error, "Google Search Console is not configured. Set GSC_CLIENT_ID and GSC_CLIENT_SECRET environment variables." ) |> redirect(to: ~p"/admin/gsc") end end @doc """ Handles the OAuth callback from Google. Exchanges the authorization code for tokens and redirects to the dashboard. """ def callback(conn, %{"code" => code}) do case OAuth.exchange_code(code) do {:ok, _access_token} -> # Invalidate any stale cache when reconnecting Cache.invalidate() conn |> put_flash(:info, "Connected to Google Search Console") |> redirect(to: ~p"/admin/gsc") {:error, reason} -> conn |> put_flash(:error, "Failed to connect: #{inspect(reason)}") |> redirect(to: ~p"/admin/gsc") end end def callback(conn, %{"error" => error}) do conn |> put_flash(:error, "Authorization denied: #{error}") |> redirect(to: ~p"/admin/gsc") end @doc """ Disconnects from Google Search Console by clearing stored tokens. """ def disconnect(conn, _params) do OAuth.disconnect() Cache.invalidate() conn |> put_flash(:info, "Disconnected from Google Search Console") |> redirect(to: ~p"/admin/gsc") end end