2013-02-12 21:47:22 +08:00
|
|
|
# -*- encoding : utf-8 -*-
|
2019-05-03 06:17:27 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2013-02-12 21:47:22 +08:00
|
|
|
require_dependency 'email'
|
2013-03-05 02:44:41 +08:00
|
|
|
require_dependency 'enum'
|
2013-06-06 22:40:10 +08:00
|
|
|
require_dependency 'user_name_suggester'
|
2013-03-05 02:44:41 +08:00
|
|
|
|
2013-02-12 21:47:22 +08:00
|
|
|
class Users::OmniauthCallbacksController < ApplicationController
|
2013-08-23 14:20:43 +08:00
|
|
|
|
2017-08-31 12:06:56 +08:00
|
|
|
skip_before_action :redirect_to_login_if_required
|
2013-02-12 21:47:22 +08:00
|
|
|
|
2017-11-16 03:04:26 +08:00
|
|
|
layout 'no_ember'
|
2013-02-12 21:47:22 +08:00
|
|
|
|
|
|
|
# need to be able to call this
|
2017-08-31 12:06:56 +08:00
|
|
|
skip_before_action :check_xhr
|
2013-02-12 21:47:22 +08:00
|
|
|
|
2013-07-29 13:13:13 +08:00
|
|
|
# this is the only spot where we allow CSRF, our openid / oauth redirect
|
|
|
|
# will not have a CSRF token, however the payload is all validated so its safe
|
2017-08-31 12:06:56 +08:00
|
|
|
skip_before_action :verify_authenticity_token, only: :complete
|
2013-02-12 21:47:22 +08:00
|
|
|
|
|
|
|
def complete
|
2013-08-23 14:20:43 +08:00
|
|
|
auth = request.env["omniauth.auth"]
|
2017-05-05 03:35:03 +08:00
|
|
|
raise Discourse::NotFound unless request.env["omniauth.auth"]
|
|
|
|
|
2013-11-20 01:58:12 +08:00
|
|
|
auth[:session] = session
|
2013-08-01 13:59:57 +08:00
|
|
|
|
2013-08-23 14:20:43 +08:00
|
|
|
authenticator = self.class.find_authenticator(params[:provider])
|
2018-07-23 23:51:57 +08:00
|
|
|
provider = DiscoursePluginRegistry.auth_providers.find { |p| p.name == params[:provider] }
|
2013-03-05 02:44:41 +08:00
|
|
|
|
2018-12-11 21:19:00 +08:00
|
|
|
if session.delete(:auth_reconnect) && authenticator.can_connect_existing_user? && current_user
|
|
|
|
# If we're reconnecting, don't actually try and log the user in
|
2018-07-23 23:51:57 +08:00
|
|
|
@auth_result = authenticator.after_authenticate(auth, existing_account: current_user)
|
2018-12-11 21:19:00 +08:00
|
|
|
if provider&.full_screen_login || cookies['fsl']
|
|
|
|
cookies.delete('fsl')
|
|
|
|
return redirect_to Discourse.base_uri("/my/preferences/account")
|
|
|
|
else
|
2018-12-12 01:40:02 +08:00
|
|
|
@auth_result.authenticated = true
|
2018-12-11 21:19:00 +08:00
|
|
|
return respond_to do |format|
|
|
|
|
format.html
|
|
|
|
format.json { render json: @auth_result.to_client_hash }
|
|
|
|
end
|
|
|
|
end
|
2018-07-23 23:51:57 +08:00
|
|
|
else
|
|
|
|
@auth_result = authenticator.after_authenticate(auth)
|
|
|
|
end
|
2019-06-11 09:28:42 +08:00
|
|
|
DiscourseEvent.trigger(:after_auth, authenticator, @auth_result)
|
2013-08-01 13:59:57 +08:00
|
|
|
|
2019-05-15 16:55:31 +08:00
|
|
|
preferred_origin = request.env['omniauth.origin']
|
2018-01-27 01:52:27 +08:00
|
|
|
|
2018-10-05 02:31:08 +08:00
|
|
|
if SiteSetting.enable_sso_provider && payload = cookies.delete(:sso_payload)
|
2019-05-15 16:55:31 +08:00
|
|
|
preferred_origin = session_sso_provider_url + "?" + payload
|
2018-10-05 02:31:08 +08:00
|
|
|
elsif cookies[:destination_url].present?
|
2019-05-15 16:55:31 +08:00
|
|
|
preferred_origin = cookies[:destination_url]
|
2016-09-16 11:48:50 +08:00
|
|
|
cookies.delete(:destination_url)
|
|
|
|
end
|
|
|
|
|
2019-05-15 16:55:31 +08:00
|
|
|
if preferred_origin.present?
|
2018-03-28 16:20:08 +08:00
|
|
|
parsed = begin
|
2019-05-15 16:55:31 +08:00
|
|
|
URI.parse(preferred_origin)
|
2018-08-14 18:23:32 +08:00
|
|
|
rescue URI::Error
|
2018-03-28 16:20:08 +08:00
|
|
|
end
|
|
|
|
|
2019-03-19 20:39:13 +08:00
|
|
|
if parsed && (parsed.host == nil || parsed.host == Discourse.current_hostname)
|
2019-05-03 06:17:27 +08:00
|
|
|
@origin = +"#{parsed.path}"
|
2019-03-19 20:39:13 +08:00
|
|
|
@origin << "?#{parsed.query}" if parsed.query
|
2015-10-13 09:23:34 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-01-27 01:52:27 +08:00
|
|
|
if @origin.blank?
|
2017-05-26 02:04:28 +08:00
|
|
|
@origin = Discourse.base_uri("/")
|
2015-10-13 09:23:34 +08:00
|
|
|
end
|
|
|
|
|
2019-05-15 16:55:31 +08:00
|
|
|
@auth_result.destination_url = @origin
|
2019-03-19 20:39:13 +08:00
|
|
|
|
2015-06-25 00:12:43 +08:00
|
|
|
if @auth_result.failed?
|
|
|
|
flash[:error] = @auth_result.failed_reason.html_safe
|
|
|
|
return render('failure')
|
|
|
|
else
|
|
|
|
@auth_result.authenticator_name = authenticator.name
|
|
|
|
complete_response_data
|
2015-10-13 11:49:09 +08:00
|
|
|
|
2018-12-11 21:19:00 +08:00
|
|
|
if provider&.full_screen_login || cookies['fsl']
|
2016-08-29 08:13:32 +08:00
|
|
|
cookies.delete('fsl')
|
2015-10-29 05:16:56 +08:00
|
|
|
cookies['_bypass_cache'] = true
|
2018-10-30 06:30:36 +08:00
|
|
|
cookies[:authentication_data] = @auth_result.to_client_hash.to_json
|
2015-10-13 11:49:09 +08:00
|
|
|
redirect_to @origin
|
|
|
|
else
|
|
|
|
respond_to do |format|
|
|
|
|
format.html
|
|
|
|
format.json { render json: @auth_result.to_client_hash }
|
|
|
|
end
|
2015-06-25 00:12:43 +08:00
|
|
|
end
|
2013-03-02 03:22:54 +08:00
|
|
|
end
|
2013-02-12 21:47:22 +08:00
|
|
|
end
|
|
|
|
|
2013-02-15 03:11:13 +08:00
|
|
|
def failure
|
2015-01-06 13:28:29 +08:00
|
|
|
flash[:error] = I18n.t("login.omniauth_error")
|
2017-11-16 03:04:26 +08:00
|
|
|
render 'failure'
|
2013-02-15 03:11:13 +08:00
|
|
|
end
|
|
|
|
|
2013-08-23 14:20:43 +08:00
|
|
|
def self.find_authenticator(name)
|
2018-07-23 23:51:57 +08:00
|
|
|
Discourse.enabled_authenticators.each do |authenticator|
|
|
|
|
return authenticator if authenticator.name == name
|
2013-08-18 12:43:59 +08:00
|
|
|
end
|
2018-07-23 23:51:57 +08:00
|
|
|
raise Discourse::InvalidAccess.new(I18n.t('authenticator_not_found'))
|
2013-02-12 21:47:22 +08:00
|
|
|
end
|
|
|
|
|
2013-08-23 14:20:43 +08:00
|
|
|
protected
|
2013-02-26 12:28:32 +08:00
|
|
|
|
2014-10-01 00:24:22 +08:00
|
|
|
def complete_response_data
|
2015-06-25 00:12:43 +08:00
|
|
|
if @auth_result.user
|
|
|
|
user_found(@auth_result.user)
|
2014-10-01 00:24:22 +08:00
|
|
|
elsif SiteSetting.invite_only?
|
2015-06-25 00:12:43 +08:00
|
|
|
@auth_result.requires_invite = true
|
2014-10-01 00:24:22 +08:00
|
|
|
else
|
2015-06-25 00:12:43 +08:00
|
|
|
session[:authentication] = @auth_result.session_data
|
2014-10-01 00:24:22 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-08-23 14:20:43 +08:00
|
|
|
def user_found(user)
|
2018-03-01 15:47:07 +08:00
|
|
|
if user.totp_enabled?
|
|
|
|
@auth_result.omniauth_disallow_totp = true
|
2018-05-30 12:14:04 +08:00
|
|
|
@auth_result.email = user.email
|
2018-03-01 15:47:07 +08:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2016-04-05 01:04:10 +08:00
|
|
|
# automatically activate/unstage any account if a provider marked the email valid
|
2017-03-01 11:58:24 +08:00
|
|
|
if @auth_result.email_valid && @auth_result.email == user.email
|
2018-05-13 23:00:02 +08:00
|
|
|
user.unstage
|
|
|
|
user.save
|
2018-03-01 10:22:41 +08:00
|
|
|
|
2017-06-08 07:05:33 +08:00
|
|
|
# ensure there is an active email token
|
2018-03-01 10:22:41 +08:00
|
|
|
unless EmailToken.where(email: user.email, confirmed: true).exists? ||
|
|
|
|
user.email_tokens.active.where(email: user.email).exists?
|
|
|
|
|
|
|
|
user.email_tokens.create!(email: user.email)
|
|
|
|
end
|
|
|
|
|
2017-04-13 02:29:32 +08:00
|
|
|
user.activate
|
2017-12-12 20:08:57 +08:00
|
|
|
user.update!(registration_ip_address: request.remote_ip) if user.registration_ip_address.blank?
|
2013-08-02 10:03:53 +08:00
|
|
|
end
|
|
|
|
|
2015-03-03 01:13:10 +08:00
|
|
|
if ScreenedIpAddress.should_block?(request.remote_ip)
|
2015-06-25 00:12:43 +08:00
|
|
|
@auth_result.not_allowed_from_ip_address = true
|
2015-03-03 01:13:10 +08:00
|
|
|
elsif ScreenedIpAddress.block_admin_login?(user, request.remote_ip)
|
2015-06-25 00:12:43 +08:00
|
|
|
@auth_result.admin_not_allowed_from_ip_address = true
|
2014-09-05 06:50:27 +08:00
|
|
|
elsif Guardian.new(user).can_access_forum? && user.active # log on any account that is active with forum access
|
2013-08-23 14:20:43 +08:00
|
|
|
log_on_user(user)
|
2014-01-22 05:53:46 +08:00
|
|
|
Invite.invalidate_for_email(user.email) # invite link can't be used to log in anymore
|
|
|
|
session[:authentication] = nil # don't carry around old auth info, perhaps move elsewhere
|
2015-06-25 00:12:43 +08:00
|
|
|
@auth_result.authenticated = true
|
2013-03-01 23:23:21 +08:00
|
|
|
else
|
2013-08-28 15:18:31 +08:00
|
|
|
if SiteSetting.must_approve_users? && !user.approved?
|
2015-06-25 00:12:43 +08:00
|
|
|
@auth_result.awaiting_approval = true
|
2013-07-11 14:02:18 +08:00
|
|
|
else
|
2015-06-25 00:12:43 +08:00
|
|
|
@auth_result.awaiting_activation = true
|
2013-07-11 14:02:18 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-02-12 21:47:22 +08:00
|
|
|
end
|