Fix callback OAuth YouTube: pagina HTML con refresh token invece di risposta API vuota.
Il codice OAuth va usato una sola volta; messaggio chiaro se si ricarica il callback. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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
|
||||
|
||||
42
backend/app/controllers/youtube_oauth_callback_controller.rb
Normal file
42
backend/app/controllers/youtube_oauth_callback_controller.rb
Normal file
@@ -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
|
||||
@@ -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"])
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user