diff --git a/backend/app/controllers/api/v1/youtube_controller.rb b/backend/app/controllers/api/v1/youtube_controller.rb index 848c68f..5b14107 100644 --- a/backend/app/controllers/api/v1/youtube_controller.rb +++ b/backend/app/controllers/api/v1/youtube_controller.rb @@ -1,10 +1,6 @@ module Api module V1 class YoutubeController < BaseController - include ActionController::Cookies - - skip_before_action :authenticate_request!, only: :callback - def authorize team = current_user.manageable_teams.find(params[:team_id]) team.entitlements.assert_can_connect_youtube! @@ -12,60 +8,6 @@ module Api url = Youtube::OauthUrl.build(state: state, redirect_uri: ENV.fetch("YOUTUBE_REDIRECT_URI")) render json: { authorization_url: url } end - - def callback - return redirect_to_oauth_error("Codice OAuth mancante") if params[:code].blank? - - ctx = Youtube::OauthState.verify!(params[:state]) - tokens = Youtube::OauthExchange.call(params[:code]) - - if ctx[:kind] == :platform - unless platform_oauth_authorized?(ctx[:admin_id]) - return redirect_to "#{admin_base_url}/login", alert: "Sessione admin richiesta", allow_other_host: true - end - - return render_platform_token(tokens) - end - - user = User.find(ctx[:user_id]) - team = user.manageable_teams.find(ctx[:team_id]) - cred = team.youtube_credential || team.build_youtube_credential - cred.update!( - access_token: tokens[:access_token], - refresh_token: tokens[:refresh_token] || cred.refresh_token, - expires_at: Time.current + tokens[:expires_in].seconds, - channel_id: tokens[:channel_id], - channel_title: tokens[:channel_title] - ) - redirect_to "#{public_base_url}/teams/#{team.id}/dettagli?youtube=connected", allow_other_host: true - rescue ArgumentError, Youtube::BroadcastService::Error => e - redirect_to_oauth_error(e.message) - end - - private - - def public_base_url - MatchLiveTv.app_public_url.chomp("/") - end - - def redirect_to_oauth_error(message) - redirect_to "#{public_base_url}/prezzi?youtube_error=#{ERB::Util.url_encode(message)}", - allow_other_host: true - end - - def render_platform_token(tokens) - @refresh_token = tokens[:refresh_token] - @channel_title = tokens[:channel_title] - render "admin/youtube/platform_token", layout: "admin" - end - - def platform_oauth_authorized?(admin_id) - session[:admin_account_id].present? && session[:admin_account_id].to_s == admin_id.to_s - end - - def admin_base_url - "#{public_base_url}/admin" - end end end end diff --git a/backend/app/controllers/youtube_oauth_callback_controller.rb b/backend/app/controllers/youtube_oauth_callback_controller.rb new file mode 100644 index 0000000..9de6548 --- /dev/null +++ b/backend/app/controllers/youtube_oauth_callback_controller.rb @@ -0,0 +1,42 @@ +# Callback OAuth YouTube (HTML). Non usare Api::V1 — ActionController::API non renderizza le view. +class YoutubeOauthCallbackController < ActionController::Base + layout "admin" + + def show + return redirect_to_oauth_error("Codice OAuth mancante") if params[:code].blank? + + ctx = Youtube::OauthState.verify!(params[:state]) + tokens = Youtube::OauthExchange.call(params[:code]) + + if ctx[:kind] == :platform + @refresh_token = tokens[:refresh_token] + @channel_title = tokens[:channel_title] + return render "admin/youtube/platform_token" + end + + user = User.find(ctx[:user_id]) + team = user.manageable_teams.find(ctx[:team_id]) + cred = team.youtube_credential || team.build_youtube_credential + cred.update!( + access_token: tokens[:access_token], + refresh_token: tokens[:refresh_token] || cred.refresh_token, + expires_at: Time.current + tokens[:expires_in].seconds, + channel_id: tokens[:channel_id], + channel_title: tokens[:channel_title] + ) + redirect_to "#{public_base_url}/teams/#{team.id}/dettagli?youtube=connected", allow_other_host: true + rescue ArgumentError, Youtube::BroadcastService::Error => e + redirect_to_oauth_error(e.message) + end + + private + + def public_base_url + MatchLiveTv.app_public_url.chomp("/") + end + + def redirect_to_oauth_error(message) + redirect_to "#{public_base_url}/prezzi?youtube_error=#{ERB::Util.url_encode(message)}", + allow_other_host: true + end +end diff --git a/backend/app/services/youtube/oauth_exchange.rb b/backend/app/services/youtube/oauth_exchange.rb index 9aab1eb..81158ac 100644 --- a/backend/app/services/youtube/oauth_exchange.rb +++ b/backend/app/services/youtube/oauth_exchange.rb @@ -11,7 +11,13 @@ module Youtube grant_type: "authorization_code" }) data = JSON.parse(response.body) - raise BroadcastService::Error, data["error_description"] if data["error"] + if data["error"] + msg = data["error_description"].presence || data["error"] + if data["error"] == "invalid_grant" + msg = "Codice OAuth già usato o scaduto. Riapri /admin/youtube/platform e ripeti il collegamento." + end + raise BroadcastService::Error, msg + end info = ChannelInfo.fetch(access_token: data["access_token"]) { diff --git a/backend/config/routes.rb b/backend/config/routes.rb index 377267c..2f481a9 100644 --- a/backend/config/routes.rb +++ b/backend/config/routes.rb @@ -40,7 +40,7 @@ Rails.application.routes.draw do end end - get "youtube/callback", to: "youtube#callback" + get "youtube/callback", to: "/youtube_oauth_callback#show" end end