add cors for real

This commit is contained in:
Seth Call 2017-04-14 14:34:18 -05:00
parent 2eaa59a6d4
commit a1fd8c3d10
13 changed files with 566 additions and 127 deletions

View File

@ -373,4 +373,5 @@ connection_role.sql
retailer_payment_split.sql
teacher_distribution_fields.sql
jam_track_download_rights.sql
guitar_center_integration_v1.sql
guitar_center_integration_v1.sql
youtube_broadcast.sql

View File

@ -0,0 +1,21 @@
CREATE TABLE broadcasts (
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
music_session_id VARCHAR(64) NOT NULL REFERENCES music_sessions(id) ON DELETE CASCADE,
user_id VARCHAR(64) NOT NULL REFERENCES users(id) ON DELETE CASCADE,
broadcast_id VARCHAR NOT NULL,
stream_id VARCHAR,
broadcast_status VARCHAR,
stream_status VARCHAR,
stream_name VARCHAR,
stream_address VARCHAR,
broadcast_data VARCHAR,
stream_data VARCHAR,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_broadcast_broadcast_id ON broadcasts USING BTREE(broadcast_id);
CREATE INDEX idx_broadcast_status ON broadcasts USING BTREE(broadcast_status);
CREATE INDEX idx_stream_status ON broadcasts USING BTREE(stream_status);
CREATE INDEX idx_broadcast_music_session_id ON broadcasts USING BTREE(music_session_id);

View File

@ -155,6 +155,7 @@ require "jam_ruby/models/friendship"
require "jam_ruby/models/active_music_session"
require "jam_ruby/models/music_session_comment"
require "jam_ruby/models/session_info_comment"
require "jam_ruby/models/broadcast"
require "jam_ruby/models/music_session"
require "jam_ruby/models/music_session_liker"
require "jam_ruby/models/music_session_user_history"

View File

@ -0,0 +1,18 @@
module JamRuby
class Broadcast < ActiveRecord::Base
@@log = Logging.logger[Broadcast]
STATUS_COMPLETED = 'completed'
STATUS_ABANDONED = 'abandoned'
STATUS_REVOKED = 'revoked'
DONE_STATUSES = [STATUS_COMPLETED, STATUS_ABANDONED, STATUS_REVOKED]
belongs_to :music_session, :class_name => 'JamRuby::MusicSsession'
def self.current_broadcast(music_session)
Broadcast.where(music_session_id: music_session.id).where('broadcast_status not in (?)', Broadcast::DONE_STATUSES).first
end
end
end

View File

@ -54,6 +54,7 @@ module JamRuby
has_many :rsvp_slots, :class_name => "JamRuby::RsvpSlot", :foreign_key => "music_session_id", :dependent => :destroy
has_many :music_notations, :class_name => "JamRuby::MusicNotation", :foreign_key => "music_session_id"
has_many :jam_track_session, :class_name => "JamRuby::JamTrackSession"
has_many :broadcasts, :class_name => "JamRuby::Broadcast"
validates :genre, :presence => true
validates :description, :presence => true, :no_profanity => true
@ -78,6 +79,135 @@ module JamRuby
SEPARATOR = '|'
def current_broadcast
Broadcast.current_broadcast(self)
end
def create_broadcast(google_client, user, broadcast_options)
broadcast = current_broadcast
if broadcast.nil?
broadcast = create_youtube_broadcast(google_client, user, broadcast_options)
else
refresh_youtube_broadcast(google_client, user, broadcast)
# check against Youtube the real state of broadcast, to see if we need a new one?
end
broadcast
end
def create_stream(google_client, user, broadcast_options)
broadcast = create_broadcast(google_client, user, broadcast_options)
stream = current_stream(broadcast)
if stream.nil?
create_youtube_stream(google_client, user, broadcast, broadcast_options)
bind_broadcast(google_client, user, broadcast)
else
bind_broadcast(google_client, user, broadcast)
end
end
def current_stream(broadcast)
broadcast.stream_id
end
def refresh_youtube_broadcast(google_client, user, broadcast)
broadcast_data = google_client.get_broadcast(user, broadcast.broadcast_id)
broadcast.broadcast_status = broadcast_data["status"]["lifeCycleStatus"]
broadcast.broadcast_data = broadcast_data.to_json
end
# https://developers.google.com/youtube/v3/live/docs/liveStreams#resource
def create_youtube_stream(google_client, user, broadcast, broadcast_options)
# https://developers.google.com/youtube/v3/live/docs/liveStreams/insert
# required
# snippet.title
# cdn.format
# cdn.ingestionType (deprecated - use resolution/framerate)
stream_options = {}
stream_options[:snippet] ||= {}
stream_options[:snippet][:title] ||= name
stream_options[:snippet][:isDefaultStream] = false
#broadcast_options[:snippet][:scheduledEndTime] = end_time.utc.iso8601
stream_options[:cdn] ||= {}
stream_options[:cdn][:frameRate] ||= '30fps'
stream_options[:cdn][:resolution] ||= '360p'
stream_options[:cdn][:ingestionType] ||= 'rtmp'
stream_options[:contentDetails] ||= {}
stream_options[:contentDetails][:isReusable] = false
stream_options = google_client.create_stream(user, stream_options)
broadcast.stream_id = stream_options["id"]
broadcast.stream_status = stream_options["status"]["streamStatus"]
broadcast.stream_name = stream_options["cdn"]["ingestionInfo"]["streamName"]
broadcast.stream_address = stream_options["cdn"]["ingestionInfo"]["ingestionAddress"]
broadcast.stream_data = stream_options.to_json
broadcast.save!
broadcast
end
def create_youtube_broadcast(google_client, user, broadcast_options)
start_time, end_time = youtube_times
broadcast_options ||= {}
broadcast_options[:snippet] ||= {}
broadcast_options[:snippet][:title] ||= name
broadcast_options[:snippet][:description] ||= description
broadcast_options[:snippet][:scheduledStartTime] = start_time.utc.iso8601
#broadcast_options[:snippet][:scheduledEndTime] = end_time.utc.iso8601
broadcast_options[:status] ||= {}
broadcast_options[:status][:privacyStatus] ||= (fan_access ? 'public' : 'private')
broadcast_options[:contentDetails] ||= {}
# if false, this causes a 'request not authorized error'
# From: https://developers.google.com/youtube/v3/live/docs/liveBroadcasts
# If your channel does not have permission to disable recordings, and you attempt to insert a broadcast with the recordFromStart property set to false, the API will return a Forbidden error.
#broadcast_options[:contentDetails][:recordFromStart] ||= false
broadcast_data = google_client.create_broadcast(user, broadcast_options)
broadcast = Broadcast.new
broadcast.music_session_id = self.id
broadcast.user_id = user.id
broadcast.broadcast_id = broadcast_data["id"]
broadcast.broadcast_status = broadcast_data["status"]["lifeCycleStatus"]
broadcast.broadcast_data = broadcast_data.to_json
broadcast.save!
broadcast
end
def bind_broadcast(google_client, user, broadcast)
bind_data = google_client.bind_broadcast(user, broadcast.broadcast_id, broadcast.stream_id)
broadcast.broadcast_data = bind_data.to_json
broadcast.save!
broadcast
end
def youtube_times
start = scheduled_start_time
if start < Time.now
start = Time.now
end_time = start + safe_scheduled_duration
return [start, end_time]
else
return [start, scheduled_end_time]
end
end
def check_scheduling_info_changed
@scheduling_info_changed = scheduled_start_changed?
true
@ -574,7 +704,9 @@ module JamRuby
end
def scheduled_end_time
start = scheduled_start_time
duration = safe_scheduled_duration
start + duration
end
def timezone_id

View File

@ -50,7 +50,7 @@ module JamRuby
self
.where(:user_id => user.id)
.where(:provider => 'google_login')
.where(['token_expiration IS NULL OR token_expiration > ?', Time.now])
.where(['token_expiration IS NULL OR (token_expiration > ? OR refresh_token is not null)', Time.now])
.limit(1)
end

View File

@ -0,0 +1,58 @@
@import "client/common";
body.video-stream {
position: relative;
color: $ColorTextTypical;
#minimal-container {
padding-bottom: 20px;
height:240px;
}
.video-stream {
padding-left: 30px;
padding-right:30px;
}
h3 {
margin-top:20px;
font-size:16px;
font-weight:bold;
margin-bottom:20px;
text-align:center;
line-height:125%;
}
.control-holder {
margin: 20px 0 20px;
text-align:center;
padding-bottom:20px;
position: absolute;
bottom: 0;
width: 100%;
left: 0;
}
.progress-bar {
background-color:#ED3618;
border:solid 1px #000;
height:20px;
display:block;
@include border_box_sizing;
margin:20px 0;
position:relative;
}
.percentage-progress {
position:absolute;
right:-32px;
}
.video-url {
text-align:center;
display:block;
margin:20px 0;
}
}

View File

@ -29,6 +29,13 @@ class PopupsController < ApplicationController
render :layout => "minimal"
end
def video_stream
@session_id = params[:session_id]
gon.session_id= @session_id
render :layout => "minimal"
end
def jamtrack_player
enable_olark
@jamtrack_id = params[:jam_track_id]

View File

@ -0,0 +1,3 @@
- provide(:page_name, 'video-stream popup')
- provide(:title, 'Video Stream')
= react_component 'PopupVideoStreamer', {}

View File

@ -2,7 +2,7 @@ Rails.application.config.middleware.use OmniAuth::Builder do
provider :facebook, Rails.application.config.facebook_app_id, Rails.application.config.facebook_app_secret, {name: "facebook", :scope => 'email,user_location'}
# add these back later if needed
# userinfo.email, userinfo.profile, https://www.google.com/m8/feeds,
provider :google_oauth2, Rails.application.config.google_client_id, Rails.application.config.google_secret, {name: "google_login", prompt: 'consent', scope: 'userinfo.email, https://www.googleapis.com/auth/youtube.upload, https://www.googleapis.com/auth/youtube'}
provider :google_oauth2, Rails.application.config.google_client_id, Rails.application.config.google_secret, {name: "google_login", prompt: 'consent', scope: ['youtube', 'youtube.force-ssl', 'youtube.upload','userinfo.email','userinfo.profile']}
provider :twitter, Rails.application.config.twitter_app_id, Rails.application.config.twitter_app_secret, {x_auth_access_type: 'write' }
provider :stripe_connect, Rails.application.config.stripe[:client_id], Rails.application.config.stripe[:secret_key], {}
end

View File

@ -178,6 +178,7 @@ Rails.application.routes.draw do
get '/video/upload/:recording_id', to: 'popups#video_upload'
get '/jamtrack-player/:jam_track_id', to: 'popups#jamtrack_player'
get '/jamtrack/download/:jam_track_id/mixdowns/:jam_track_mixdown_id', to: 'popups#jamtrack_download'
get '/video/stream/:session_id', to: 'popups#video_stream'
end
scope '/corp' do

View File

@ -5,13 +5,18 @@ require 'json'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/installed_app'
require 'socket'
require 'socket'
#Google::Apis.logger.level = Logger::DEBUG
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
# Youtube OAuth and API functionality:
module JamRuby
class GoogleClient
attr_accessor :client
attr_accessor :api
attr_accessor :api
attr_accessor :request
attr_accessor :server
attr_accessor :socket
@ -19,21 +24,56 @@ module JamRuby
attr_accessor :redirect_uri
def initialize()
Rails.logger.info("Initializing client...")
self.config = Rails.application.config
self.redirect_uri='http://localhost:2112/auth/google_login/callback'
self.client = Google::APIClient.new(
:application_name => 'JamKazam',
:application_version => '1.0.0'
:application_name => 'JamKazam',
:application_version => '1.0.0'
)
#youtube = client.discovered_api('youtube', 'v3')
end
def youtube
@youtube ||= client.discovered_api('youtube', 'v3')
end
def create_authorization(user_auth, scope, autorefresh)
authorization = Signet::OAuth2::Client.new(
:authorization_uri => "https://accounts.google.com/o/oauth2/auth",
:token_credential_uri => "https://accounts.google.com/o/oauth2/token",
:client_id => @config.google_client_id,
:client_secret => @config.google_secret,
#:redirect_uri => credentials.redirect_uris.first,
:scope => scope
)
authorization.access_token = user_auth.token
authorization.refresh_token = user_auth.refresh_token
authorization.expires_at = user_auth.token_expiration
if autorefresh && (user_auth.token_expiration < (Time.now - 15)) # add 15 second buffer to this time, because OAUth server does not respond with timestamp, but 'expires_in' which is just offset seconds
# XXX: what to do when this fails?
authorization.refresh!
user_auth.token = authorization.access_token
user_auth.token_expiration = authorization.issued_at + authorization.expires_in
user_auth.save
end
authorization
end
def create_client
Google::APIClient.new(
:application_name => 'JamKazam',
:application_version => '1.0.0',
)
end
# Return a login URL that will show a web page with
def get_login_url(username=nil)
puts "GET LOGIN URL"
uri = "https://accounts.google.com/o/oauth2/auth"
uri << "?scope=#{CGI.escape('https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload https://gdata.youtube.com email profile ')}" # # https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload
uri << "?scope=#{CGI.escape('https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload https://www.googleapis.com/auth/youtube https://gdata.youtube.com email profile ')}" # # https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload
uri << "&client_id=#{CGI.escape(self.config.google_email)}"
uri << "&response_type=code"
uri << "&access_type=online"
@ -46,15 +86,168 @@ module JamRuby
uri
end
# create youtube broadcast
def create_broadcast(user, broadcast_options)
auth = UserAuthorization.google_auth(user).first
if auth.nil? || auth.token.nil?
raise JamPermissionError, "No current google token found for user #{user}"
end
broadcast_data = {
"snippet" => broadcast_options[:snippet],
"status" => broadcast_options[:status],
"contentDetails" => broadcast_options[:contentDetails]
}
begin
#secrets = Google::APIClient::ClientSecrets.new({"web" => {"access_token" => auth.token, "refresh_token" => auth.refresh_token, "client_id" => @config.google_client_id, "client_secret" => @config.google_secret}})
my_client = create_client
my_client.authorization = create_authorization(auth, 'https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.force-ssl', true)
puts "BROADCAST DATA: #{broadcast_data}"
#y = my_client.discovered_api('youtube', 'v3')
response = my_client.execute!(:api_method => youtube.live_broadcasts.insert,
:parameters => {:part => 'contentDetails,status,snippet'},
:body_object => broadcast_data)
body = JSON.parse(response.body)
puts "CREATE BROADCAST RESPONSE: #{body}"
return body
rescue Google::APIClient::ClientError => e
# ex:
=begin
ex = {
"error": {
"errors": [
{
"domain": "youtube.liveBroadcast",
"reason": "liveStreamingNotEnabled",
"message": "The user is not enabled for live streaming.",
"extendedHelp": "https://www.youtube.com/features"
}
],
"code": 403,
"message": "The user is not enabled for live streaming."
}
}
ex = {
"error": {
"errors": [
{
"domain": "youtube.liveBroadcast",
"reason": "insufficientLivePermissions",
"message": "Request is not authorized",
"extendedHelp": "https://developers.google.com/youtube/v3/live/docs/liveBroadcasts/insert#auth_required"
}
],
"code": 403,
"message": "Request is not authorized"
}
}
=end
puts e.result.body
raise e
end
end
def bind_broadcast(user, broadcast_id, stream_id)
auth = UserAuthorization.google_auth(user).first
if auth.nil? || auth.token.nil?
raise JamPermissionError, "No current google token found for user #{user}"
end
begin
my_client = create_client
my_client.authorization = create_authorization(auth, 'https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.force-ssl', true)
#y = my_client.discovered_api('youtube', 'v3')
response = my_client.execute!(:api_method => youtube.live_broadcasts.bind,
:parameters => {:part => 'id,contentDetails,status,snippet', :id => broadcast_id, :streamId => stream_id })
body = JSON.parse(response.body)
puts "BIND RESPONSE: #{body}"
return body
rescue Google::APIClient::ClientError => e
puts e.result.body
raise e
end
end
def get_broadcast(user, broadcast_id)
auth = UserAuthorization.google_auth(user).first
if auth.nil? || auth.token.nil?
raise JamPermissionError, "No current google token found for user #{user}"
end
begin
my_client = create_client
my_client.authorization = create_authorization(auth, 'https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.force-ssl', true)
#y = my_client.discovered_api('youtube', 'v3')
response = my_client.execute!(:api_method => youtube.live_broadcasts.list,
:parameters => {:part => 'id,contentDetails,status,snippet', :id => broadcast_id })
body = JSON.parse(response.body)
puts "BIND RESPONSE: #{body}"
return body["items"][0] # returns array of items. meh
rescue Google::APIClient::ClientError => e
puts e.result.body
raise e
end
end
def create_stream(user, stream_options)
auth = UserAuthorization.google_auth(user).first
if auth.nil? || auth.token.nil?
raise JamPermissionError, "No current google token found for user #{user}"
end
broadcast_data = {
"snippet" => stream_options[:snippet],
"cdn" => stream_options[:cdn],
"contentDetails" => stream_options[:contentDetails]
}
begin
my_client = create_client
my_client.authorization = create_authorization(auth, 'https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.force-ssl', true)
puts "STREAM DATA: #{broadcast_data}"
#y = my_client.discovered_api('youtube', 'v3')
response = my_client.execute!(:api_method => youtube.live_streams.insert,
:parameters => {:part => 'id,contentDetails,cdn,status,snippet'},
:body_object => broadcast_data)
body = JSON.parse(response.body)
puts "CREATE STREAM RESPONSE: #{body}"
return body
rescue Google::APIClient::ClientError => e
puts e.result.body
raise e
end
end
# create youtube broadcast
def update_broadcast(user, broadcast_options)
end
# Contacts youtube and prepares an upload to youtube. This
# process is somewhat painful, even in ruby, so we do the preparation
# and the client does the actual upload using the URL returned:
# https://developers.google.com/youtube/v3/docs/videos/insert
# https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol
def sign_youtube_upload(user, filename, length)
def sign_youtube_upload(user, filename, length)
raise ArgumentError, "Length is required and should be > 0" if length.to_i.zero?
# Something like this:
# POST /upload/youtube/v3/videos?uploadType=resumable&part=snippet,status,contentDetails HTTP/1.1
# Host: www.googleapis.com
@ -79,38 +272,38 @@ module JamRuby
# }
auth = UserAuthorization.google_auth(user).first
if auth.nil? || auth.token.nil?
raise SecurityError, "No current google token found for user #{user}"
raise SecurityError, "No current google token found for user #{user}"
end
video_data = {
"snippet"=> {
"title"=> filename,
"description"=> filename,
"tags"=> ["cool", "video", "more keywords"],
"categoryId"=>1
},
"status"=> {
"privacyStatus"=> "public",
"embeddable"=> true,
"license"=> "youtube"
}
}
conn = Faraday.new(:url =>"https://www.googleapis.com",:ssl => {:verify => false}) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
"snippet" => {
"title" => filename,
"description" => filename,
"tags" => ["cool", "video", "more keywords"],
"categoryId" => 1
},
"status" => {
"privacyStatus" => "public",
"embeddable" => true,
"license" => "youtube"
}
}
conn = Faraday.new(:url => "https://www.googleapis.com", :ssl => {:verify => false}) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
end
video_json=video_data.to_json
result = conn.post("/upload/youtube/v3/videos?access_token=#{CGI.escape(auth.token)}&uploadType=resumable&part=snippet,status,contentDetails",
video_json,
{
'content-type'=>'application/json;charset=utf-8',
'x-Upload-Content-Length'=>"#{length}",
'x-upload-content-type'=>"video/*"
}
video_json,
{
'content-type' => 'application/json;charset=utf-8',
'x-Upload-Content-Length' => "#{length}",
'x-upload-content-type' => "video/*"
}
)
# Response should something look like:
# HTTP/1.1 200 OK
# Location: https://www.googleapis.com/upload/youtube/v3/videos?uploadType=resumable&upload_id=xa298sd_f&part=snippet,status,contentDetails
@ -119,7 +312,7 @@ module JamRuby
if (result.nil? || result.status!=200 || result.headers['location'].blank?)
msg = "Failed signing with status=#{result.status} #{result.inspect}: "
if result.body.present? && result.body.length > 2
msg << result.body.inspect# JSON.parse(result.body).inspect
msg << result.body.inspect # JSON.parse(result.body).inspect
end
# TODO: how to test for this:
@ -130,20 +323,20 @@ module JamRuby
else
# This has everything one needs to start the upload to youtube:
{
"method" => "PUT",
"url" => result.headers['location'],
"Authorization" => "Bearer #{auth.token}",
"Content-Length" => length,
"Content-Type" => "video/*"
}
"method" => "PUT",
"url" => result.headers['location'],
"Authorization" => "Bearer #{auth.token}",
"Content-Length" => length,
"Content-Type" => "video/*"
}
end
end
end
# https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol#Check_Upload_Status
def youtube_upload_status(user, upload_url, length)
auth = UserAuthorization.google_auth(user).first
if auth.nil? || auth.token.nil?
raise SecurityError, "No current google token found for user #{user}"
raise SecurityError, "No current google token found for user #{user}"
end
# PUT UPLOAD_URL HTTP/1.1
@ -151,20 +344,20 @@ module JamRuby
# Content-Length: 0
# Content-Range: bytes */CONTENT_LENGTH
RestClient.put(upload_url, nil, {
'Authorization' => "Bearer #{auth.token}",
'Content-Length'=> "0",
'Content-Range' => "bytes */#{length}"
}) do |response, request, result|
'Authorization' => "Bearer #{auth.token}",
'Content-Length' => "0",
'Content-Range' => "bytes */#{length}"
}) do |response, request, result|
# Result looks like this:
# 308 Resume Incomplete
# Content-Length: 0
# Range: bytes=0-999999
case(response.code)
case (response.code)
when 200..207
result_hash = {
"offset" => 0,
"length" => length,
"status" => response.code
"offset" => 0,
"length" => length,
"status" => response.code
}
when 308
range_str = response.headers['Range']
@ -174,15 +367,15 @@ module JamRuby
range = range_str.split("-")
end
result_hash = {
"offset" => range.first.to_i,
"length" => range.last.to_i,
"status" => response.code
"offset" => range.first.to_i,
"length" => range.last.to_i,
"status" => response.code
}
else
raise "Unexpected status from youtube: [#{response.code}] with headers: #{response.headers.inspect}"
end
end
result_hash
result_hash
end
end
@ -190,14 +383,14 @@ module JamRuby
def verify_youtube_upload(user, upload_url, length)
status_hash=youtube_upload_status(user, upload_url, length)
(status_hash['status']>=200 && status_hash['status']<300)
end
end
# Set fully_uploaded if the upload can be verified.
# @return true if verified; false otherwise:
def complete_upload(recorded_video)
def complete_upload(recorded_video)
if (verify_youtube_upload(recorded_video.user, recorded_video.url, recorded_video.length))
recorded_video.update_attribute(:fully_uploaded, true)
else
else
false
end
end
@ -205,17 +398,17 @@ module JamRuby
def verify_recaptcha(recaptcha_response)
success = false
if !Rails.application.config.recaptcha_enable
success = true
success = true
else
Rails.logger.info "Login with: #{recaptcha_response}"
RestClient.get("https://www.google.com/recaptcha/api/siteverify",
params: {
secret: Rails.application.config.recaptcha_private_key,
response: recaptcha_response
}
RestClient.get("https://www.google.com/recaptcha/api/siteverify",
params: {
secret: Rails.application.config.recaptcha_private_key,
response: recaptcha_response
}
) do |response, request, result|
Rails.logger.info "response: #{response.inspect}"
case(response.code)
case (response.code)
when 200..207
json = JSON.parse(response.to_str)
if json['success']
@ -229,34 +422,37 @@ module JamRuby
end #do
end # if
success
end #def
end
#def
# This will also sign in and prompt for login as necessary;
# currently requires the server to be running at localhost:3000
def signin_flow()
def signin_flow()
config = Rails.application.config
self.client = Google::APIClient.new(
:application_name => 'JamKazam',
:application_version => '1.0.0'
:application_name => 'JamKazam',
:application_version => '1.0.0'
)
raise "SIGNIN FLOW!!"
flow = Google::APIClient::InstalledAppFlow.new(
:client_id => config.google_client_id,
:client_secret => config.google_secret,
:redirect_uri=>redirect_uri,
:scope => 'email profile'
:client_id => config.google_client_id,
:client_secret => config.google_secret,
:redirect_uri => redirect_uri,
:scope => 'email profile https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload'
)
self.client.authorization = flow.authorize
end
# Must manually confirm to obtain refresh token:
def get_refresh_token
def get_refresh_token
config = Rails.application.config
conn = Faraday.new(:url => 'https://accounts.google.com',:ssl => {:verify => false}) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
conn = Faraday.new(:url => 'https://accounts.google.com', :ssl => {:verify => false}) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
end
wait_for_callback do |refresh_token|
@ -264,40 +460,40 @@ module JamRuby
end
result = conn.get '/o/oauth2/auth', {
'scope'=>'email profile',
'client_id'=>config.google_client_id,
'response_type'=>"code",
'access_type'=>"offline",
'redirect_uri'=>redirect_uri
}
'scope' => 'email profile https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload',
'client_id' => config.google_client_id,
'response_type' => "code",
'access_type' => "offline",
'redirect_uri' => redirect_uri
}
end
def get_access_token(refresh_token)
def get_access_token(refresh_token)
refresh_token = "4/g9uZ8S4lq2Bj1J8PPIkgOFKhTKmCHSmRe68iHA75hRg.gj8Nt5bpVYQdPm8kb2vw2M23tnRnkgI"
config = Rails.application.config
conn = Faraday.new(:url => 'https://accounts.google.com',:ssl => {:verify => false}) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
conn = Faraday.new(:url => 'https://accounts.google.com', :ssl => {:verify => false}) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
end
wait_for_callback do |access_token|
Rails.logger.info("The access_token is #{access_token}")
Rails.logger.info("The access_token is #{access_token}")
end
result = conn.post '/o/oauth2/token', nil, {
'scope'=>'email profile',
'client_id'=>config.google_client_id,
'client_secret'=>config.google_secret,
'refresh_token'=>refresh_token,
'grant_type'=>"refresh_token",
'redirect_uri'=>redirect_uri
}
'scope' => 'email profile https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload',
'client_id' => config.google_client_id,
'client_secret' => config.google_secret,
'refresh_token' => refresh_token,
'grant_type' => "refresh_token",
'redirect_uri' => redirect_uri
}
Rails.logger.info("REsult: #{result.inspect}\n\n")
end
def wait_for_callback(port=3000)
def wait_for_callback(port=3000)
shutdown()
self.server = Thread.new {
Rails.logger.info("STARTING SERVER THREAD...")
@ -307,7 +503,7 @@ module JamRuby
if self.socket
request = self.socket.gets
Rails.logger.info("REQUEST: #{request}")
params=CGI.parse(request)
code = params['code'].first
# Whack the end part:
@ -317,16 +513,16 @@ module JamRuby
Rails.logger.info("access_code is #{status}")
token=exchange_for_token(access_code)
yield(token)
response = "#{status}\n"
response = "#{status}\n"
self.socket.print "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: #{response.bytesize}\r\n" +
"Connection: close\r\n"
"Content-Type: text/plain\r\n" +
"Content-Length: #{response.bytesize}\r\n" +
"Connection: close\r\n"
self.socket.print "\r\n"
self.socket.print response
self.socket.close
self.socket.close
self.socket=nil
else
puts "WHY WOULD THIS EVER HAPPEN?"
@ -339,17 +535,17 @@ module JamRuby
def exchange_for_token(access_code)
Rails.logger.info("Exchanging token for code: [#{access_code}]")
conn = Faraday.new(:url =>"https://accounts.google.com",:ssl => {:verify => false}) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
conn = Faraday.new(:url => "https://accounts.google.com", :ssl => {:verify => false}) do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
end
exchange_parms={
'grant_type'=>'authorization_code',
'code'=>(access_code),
'client_id'=>(config.google_email),
'client_secret'=>(config.google_secret),
'redirect_uri'=>(redirect_uri),
'grant_type' => 'authorization_code',
'code' => (access_code),
'client_id' => (config.google_email),
'client_secret' => (config.google_secret),
'redirect_uri' => (redirect_uri),
}
result = conn.post('/o/oauth2/token', exchange_parms)
@ -362,7 +558,7 @@ module JamRuby
end
# shutdown
def shutdown()
def shutdown()
Rails.logger.info("Stopping oauth server...")
if (self.socket)
begin

View File

@ -1,13 +1,14 @@
=begin
require 'google/api_client'
Rails.logger = Logger.new(STDOUT)
require Rails.root.join('lib', 'google_client')
namespace :google do
task create_broadcast: :environment do |task, args|
google_client = JamRuby::GoogleClient.new
music_session = MusicSession.first
user = User.find_by_email('seth@jamkazam.com')
task :youtube do |task, args|
client = Google::APIClient.new
yt = client.discovered_api('youtube', 'v3')
# google-api oauth-2-login --client-id='785931784279-gd0g8on6sc0tuesj7cu763pitaiv2la8.apps.googleusercontent.com' --client-secret='UwzIcvtErv9c2-GIsNfIo7bA' --scope="https://www.googleapis.com/auth/plus.me"
broadcast = music_session.create_stream(google_client, user, nil)
puts broadcast.inspect
end
end
=end