jam-cloud/web/app/controllers/sessions_controller.rb

332 lines
11 KiB
Ruby

# this is not a jam session - this is an 'auth session'
class SessionsController < ApplicationController
layout "web"
def signin
@login_error = false
@sso = params[:sso]
@send_back_to = request.headers['REFERER']
params[:send_back_to] = @send_back_to
if current_user
# send them on their way
complete_sign_in(current_user)
return
end
render :layout => "landing"
end
def create
user = User.authenticate(params[:session][:email], params[:session][:password])
if user.nil?
@login_error = true
@sso = params[:sso]
@send_back_to = params[:send_back_to]
render 'signin', :layout => "landing"
else
if jkclient_agent?
user.update_progression_field(:first_ran_client_at)
end
@session_only_cookie = !jkclient_agent? && !params[:user].nil? && 0 == params[:user][:remember_me].to_i
complete_sign_in user
end
end
# OAuth docs
# http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/
def create_oauth
auth_hash = request.env['omniauth.auth']
authorization = UserAuthorization.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"])
if authorization
# Sign in for a user who has already registered.
complete_sign_in authorization.user
else
# Sign up for a completely new user.
# First/last name: auth_hash["info"]["first_name"] and auth_hash["info"]["last_name"]
# token: auth_hash["credentials"]["token"] -- "expires_at"
#
# For debugging - to see what all is there:
# render :text => auth_hash.to_yaml
#FbGraph.debug!
token = auth_hash[:credentials][:token]
# FIXME:
# This should probably be in a transaction somehow, meaning the user
# create and the authorization create. Concern is UserManager.new.signup sends
# an email and whatnot.
#
# Also, should we grab their photo from facebook?
user = UserManager.new.signup(remote_ip: remote_ip(),
first_name: auth_hash[:info][:first_name],
last_name: auth_hash[:info][:last_name],
email: auth_hash[:info][:email],
affiliate_referral_id: cookies[:affiliate_visitor])
# Users who sign up using oauth are presumed to have valid email adddresses.
user.confirm_email!
auth = user.user_authorizations.build :provider => auth_hash[:provider],
:uid => auth_hash[:uid],
:token => auth_hash[:credentials][:token],
:token_expiration => Time.at(auth_hash[:credentials][:expires_at])
user.save
complete_sign_in user
end
end
# https://github.com/intridea/omniauth/wiki/Saving-User-Location
def oauth_callback
auth_hash = request.env['omniauth.auth']
provider = auth_hash[:provider]
provider = provider.to_s
provider.strip!
if provider == 'google_login'
elsif provider == 'stripe_connect'
oauth_callback_stripe_connect(auth_hash)
return
elsif provider == 'twitter'
@user_authorization = current_user.build_twitter_authorization(auth_hash)
if !@user_authorization.save
# this is a very poorly styled page, but it's better than a server error.
# the only reason this happens is because some other account has authed this twitter acct
render "twitter_oauth_failure"
return
end
redirect_to request.env['omniauth.origin'] || '/'
return
elsif provider == 'facebook'
fb_uid = auth_hash[:uid]
token = auth_hash[:credentials][:token]
token_expiration = Time.at(auth_hash[:credentials][:expires_at])
first_name = auth_hash[:extra][:raw_info][:first_name]
last_name = auth_hash[:extra][:raw_info][:last_name]
email = auth_hash[:extra][:raw_info][:email]
gender = auth_hash[:extra][:raw_info][:gender]
fb_signup = FacebookSignup.new
fb_signup.uid = fb_uid
fb_signup.token = token
fb_signup.token_expires_at = token_expiration
fb_signup.first_name = first_name
fb_signup.last_name = last_name
fb_signup.email = email
if gender == 'male'
fb_signup.gender = 'M'
elsif gender == 'female'
fb_signup.gender = 'F'
end
fb_signup.save!
# see if we can find a SignupHint for a JamTrack; if so, bounce them back to the redeemComplete page to let them know we bought it
if anonymous_user
signup_hint = anonymous_user.signup_hint
if signup_hint && signup_hint.redirect_location
options = {
first_name: first_name,
last_name: last_name,
email: email,
terms_of_service: true,
location: {:country => nil, :state => nil, :city => nil},
affiliate_referral_id: cookies[:affiliate_visitor],
origin: origin_cookie
}
options = User.musician_defaults(request.remote_ip, ApplicationHelper.base_uri(request) + "/confirm", any_user, options)
user = UserManager.new.signup(options)
if user.errors.any?
redirect_to signup_hint.redirect_location
return
end
sign_in(user)
new_user(user, signup_hint)
redirect_to signup_hint.redirect_location
return
else
redirect_to "#{signup_path}?facebook_signup=#{fb_signup.lookup_id}"
return
end
else
redirect_to "#{signup_path}?facebook_signup=#{fb_signup.lookup_id}"
return
end
end
if current_user.nil?
render :nothing => true, :status => 404
return
end
authorization = UserAuthorization.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"])
# Always make and save a new authorization. This is because they expire, and honestly there's no cost
# to just making and saving it.
user_auth_hash = {
:provider => auth_hash[:provider],
:uid => auth_hash[:uid],
:token => auth_hash[:credentials][:token],
:refresh_token => auth_hash[:credentials][:refresh_token],
:token_expiration => Time.at(auth_hash[:credentials][:expires_at]),
:secret => auth_hash[:credentials][:secret]
}
if authorization.nil?
authorization = current_user.user_authorizations.build(user_auth_hash)
authorization.save
else
authorization.token = auth_hash[:credentials][:token]
authorization.token_expiration = Time.at(auth_hash[:credentials][:expires_at])
authorization.save
end
render 'oauth_complete', :layout => "landing"
end
def oauth_callback_stripe_connect(auth_hash)
if current_user.nil?
redirect_to '/signin'
return
end
# https://github.com/isaacsanders/omniauth-stripe-connect
#request.env['omniauth.auth']
=begin
{
"provider"=>"stripe_connect",
"uid"=>"<STRIPE_USER_ID>",
"info"=> {
"scope"=>"read_write", # or "read_only"
"livemode"=>false,
"stripe_publishable_key"=>"<STRIPE_PUBLISHABLE_KEY>",
},
"credentials"=> {
"token"=>"<STRIPE_ACCESS_TOKEN>",
"expires"=>false
},
"extra"=> {
"raw_info"=> {
"token_type"=>"bearer",
"stripe_user_id"=>"<STRIPE_USER_ID>",
"scope"=>"read_only",
"stripe_publishable_key"=>"<STRIPE_PUBLISHABLE_KEY>",
"livemode"=>false
}
}
}
=end
# puts "AUTH HASH #{auth_hash.inspect}"
# AUTH HASH #<OmniAuth::AuthHash credentials=#<OmniAuth::AuthHash expires=false token="sk_test_TU9lDNHpIyJdFAkWtuerfZUM">
# extra=#<OmniAuth::AuthHash raw_info=#<OmniAuth::AuthHash livemode=false scope="read_write" stripe_publishable_key="pk_test_dyrB3YtkZRSJiQKFrDxBz7pu" stripe_user_id="acct_17dIjBCHBELYys1s" token_type="bearer">>
# info=#<OmniAuth::AuthHash::InfoHash livemode=false scope="read_write" stripe_publishable_key="pk_test_dyrB3YtkZRSJiQKFrDxBz7pu"> provider="stripe_connect" uid="acct_17dIjBCHBELYys1s">
authorization = UserAuthorization.find_by_provider_and_uid(auth_hash["provider"], auth_hash["uid"])
# Always make and save a new authorization. This is because they expire, and honestly there's no cost
# to just making and saving it.
user_auth_hash = {
:provider => auth_hash[:provider],
:uid => auth_hash[:uid],
:token => auth_hash[:credentials][:token],
:refresh_token => auth_hash[:credentials][:refresh_token],
:token_expiration => auth_hash[:credentials][:expires],
:secret => auth_hash[:credentials][:secret]
}
# 'false' just means really far into the future
if !user_auth_hash[:token_expiration]
user_auth_hash[:token_expiration] = Date.new(2050, 1, 1)
else
user_auth_hash[:token_expiration] = Time.at(user_auth_hash[:token_expiration])
end
if authorization.nil?
authorization = current_user.user_authorizations.build(user_auth_hash)
authorization.save
else
authorization.token = auth_hash[:credentials][:token]
authorization.token_expiration = Date.new(2050, 1, 1)
authorization.save
end
# request.env['omniauth.origin']
redirect_to SignupHint.most_recent_redirect(current_user, '/client#/jamclass',{"stripe-success" => "true"})
end
def has_google_auth
render :json => {has_google_auth: (!!current_user && !!UserAuthorization.google_auth(current_user).first)}
end
def redirect_after_signin(default)
redirect_to(params['redirect-to'].blank? ? default : params['redirect-to'])
end
def redirect_to_forums_after_signin
redirect_to("#{Rails.application.config.vanilla_login_url}?client_id=#{Rails.application.config.vanilla_client_id}&Target=#{ERB::Util.url_encode(params[:send_back_to].blank? ? '/' : params[:send_back_to])}")
end
def redirect_to_support_after_signin(user)
# generate multipass token and sign it
multipass = DeskMultipass.new(user)
callback_url = Rails.application.config.multipass_callback_url
redirect_to "#{callback_url}?multipass=#{multipass.token}&signature=#{multipass.signature}"
end
def destroy
# earlier, code here would delete the connection using client_id from cookies
# however, we should never try to delete the client_id cookie (make it as permanent as possible)
# also, because the client will stop heartbeating and close the connection to gateway,
# in any case the server will notice after 10 seconds that the user is gone.
# if we really want someone to know right away that the client is gone, then just make sure the client calls
# leave session before it calls delete (VRFS-617 should solve that)
sign_out
redirect_to client_url
end
def failure
strategy = params['strategy']
if strategy == 'stripe_connect'
puts env['omniauth.error.type']
redirect_to SignupHint.most_recent_redirect(current_user, '/client#/jamclass', {"stripe-success" => "false"})
return
end
redirect_to request.query_parameters['origin'] || '/'
end
def connection_state
if (defined?(TEST_CONNECT_STATES) && TEST_CONNECT_STATES) || 'development'==Rails.env
@prefix = defined?(TEST_CONNECT_STATE_JS_LOG_PREFIX) ? TEST_CONNECT_STATE_JS_LOG_PREFIX : '*** '
render('connection_state', :layout => 'client') && return
end
render :nothing => true, :status => 404
end
end