mirror of
https://github.com/discourse/discourse.git
synced 2024-11-27 02:13:38 +08:00
commit
afc23cc8cb
8
Gemfile
8
Gemfile
|
@ -23,11 +23,14 @@ gem 'hiredis'
|
|||
gem 'hpricot'
|
||||
gem 'i18n-js'
|
||||
gem 'jquery-rails'
|
||||
gem 'koala', require: false
|
||||
gem 'multi_json'
|
||||
gem 'mustache'
|
||||
gem 'nokogiri'
|
||||
gem 'oauth', require: false
|
||||
gem "omniauth"
|
||||
gem "omniauth-openid"
|
||||
gem "openid-redis-store"
|
||||
gem "omniauth-facebook"
|
||||
gem "omniauth-twitter"
|
||||
gem 'oj'
|
||||
gem 'pbkdf2'
|
||||
gem 'pg'
|
||||
|
@ -37,7 +40,6 @@ gem 'redis'
|
|||
gem 'redis-rails'
|
||||
gem 'rest-client'
|
||||
gem 'rinku'
|
||||
gem 'ruby-openid', require: 'openid'
|
||||
gem 'sanitize'
|
||||
gem 'sass'
|
||||
gem 'seed-fu'
|
||||
|
|
46
Gemfile.lock
46
Gemfile.lock
|
@ -95,7 +95,6 @@ GEM
|
|||
multi_json (~> 1.0)
|
||||
acts_as_paranoid (0.4.1)
|
||||
activerecord (~> 3.2)
|
||||
addressable (2.3.2)
|
||||
airbrake (3.1.2)
|
||||
activesupport
|
||||
builder
|
||||
|
@ -189,10 +188,12 @@ GEM
|
|||
spork (>= 0.8.4)
|
||||
haml (3.1.7)
|
||||
has_ip_address (0.0.1)
|
||||
hashie (1.2.0)
|
||||
highline (1.6.15)
|
||||
hike (1.2.1)
|
||||
hiredis (0.4.5)
|
||||
hpricot (0.8.6)
|
||||
httpauth (0.2.0)
|
||||
i18n (0.6.1)
|
||||
i18n-js (2.1.2)
|
||||
i18n
|
||||
|
@ -212,10 +213,8 @@ GEM
|
|||
railties (>= 3.0, < 5.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.7.7)
|
||||
koala (1.6.0)
|
||||
addressable (~> 2.2)
|
||||
faraday (~> 0.8)
|
||||
multi_json (~> 1.3)
|
||||
jwt (0.1.5)
|
||||
multi_json (>= 1.0)
|
||||
librarian (0.0.26)
|
||||
archive-tar-minitar (>= 0.5.2)
|
||||
chef (>= 0.10)
|
||||
|
@ -252,6 +251,12 @@ GEM
|
|||
net-ssh-gateway (>= 0.99.0)
|
||||
nokogiri (1.5.6)
|
||||
oauth (0.4.7)
|
||||
oauth2 (0.8.0)
|
||||
faraday (~> 0.8)
|
||||
httpauth (~> 0.1)
|
||||
jwt (~> 0.1.4)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.2)
|
||||
ohai (6.16.0)
|
||||
ipaddress
|
||||
mixlib-cli
|
||||
|
@ -261,6 +266,26 @@ GEM
|
|||
systemu
|
||||
yajl-ruby
|
||||
oj (2.0.3)
|
||||
omniauth (1.1.1)
|
||||
hashie (~> 1.2)
|
||||
rack
|
||||
omniauth-facebook (1.4.1)
|
||||
omniauth-oauth2 (~> 1.1.0)
|
||||
omniauth-oauth (1.0.1)
|
||||
oauth
|
||||
omniauth (~> 1.0)
|
||||
omniauth-oauth2 (1.1.1)
|
||||
oauth2 (~> 0.8.0)
|
||||
omniauth (~> 1.0)
|
||||
omniauth-openid (1.0.1)
|
||||
omniauth (~> 1.0)
|
||||
rack-openid (~> 1.3.1)
|
||||
omniauth-twitter (0.0.14)
|
||||
multi_json (~> 1.3)
|
||||
omniauth-oauth (~> 1.0)
|
||||
openid-redis-store (0.0.2)
|
||||
redis
|
||||
ruby-openid
|
||||
pbkdf2 (0.1.0)
|
||||
pg (0.14.1)
|
||||
polyglot (0.3.3)
|
||||
|
@ -274,6 +299,9 @@ GEM
|
|||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-openid (1.3.1)
|
||||
rack (>= 1.1.0)
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-protection (1.3.2)
|
||||
rack
|
||||
rack-ssl (1.3.3)
|
||||
|
@ -441,15 +469,18 @@ DEPENDENCIES
|
|||
image_optim
|
||||
jasminerice
|
||||
jquery-rails
|
||||
koala
|
||||
librarian (>= 0.0.25)
|
||||
message_bus!
|
||||
mocha
|
||||
multi_json
|
||||
mustache
|
||||
nokogiri
|
||||
oauth
|
||||
oj
|
||||
omniauth
|
||||
omniauth-facebook
|
||||
omniauth-openid
|
||||
omniauth-twitter
|
||||
openid-redis-store
|
||||
pbkdf2
|
||||
pg
|
||||
pry-rails
|
||||
|
@ -464,7 +495,6 @@ DEPENDENCIES
|
|||
rest-client
|
||||
rinku
|
||||
rspec-rails
|
||||
ruby-openid
|
||||
sanitize
|
||||
sass
|
||||
sass-rails
|
||||
|
|
|
@ -23,7 +23,10 @@ The following Ruby Gems are used in Discourse:
|
|||
* [i18n-js](https://rubygems.org/gems/i18n-js)
|
||||
* [pbkdf2](https://rubygems.org/gems/pbkdf2)
|
||||
* [fast_xs](https://rubygems.org/gems/fast_xs)
|
||||
* [koala](https://rubygems.org/gems/koala)
|
||||
* [omniauth](https://github.com/intridea/omniauth)
|
||||
* [omniauth-openid](https://github.com/intridea/omniauth-openid)
|
||||
* [omniauth-facebook](https://github.com/mkdynamic/omniauth-facebook)
|
||||
* [omniauth-twitter](https://github.com/arunagw/omniauth-twitter)
|
||||
* [has_ip_address](https://rubygems.org/gems/has_ip_address)
|
||||
* [vestal_versions](https://rubygems.org/gems/vestal_versions)
|
||||
* [coffee-rails](https://rubygems.org/gems/coffee-rails)
|
||||
|
|
|
@ -47,22 +47,22 @@ window.Discourse.LoginView = window.Discourse.ModalBodyView.extend Discourse.Pre
|
|||
@set('authenticate', 'twitter')
|
||||
left = @get('lastX') - 400
|
||||
top = @get('lastY') - 200
|
||||
window.open("/twitter/frame", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top)
|
||||
window.open("/auth/twitter", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top)
|
||||
|
||||
facebookLogin: ()->
|
||||
@set('authenticate', 'facebook')
|
||||
left = @get('lastX') - 400
|
||||
top = @get('lastY') - 200
|
||||
window.open("/facebook/frame", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top)
|
||||
window.open("/auth/facebook", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top)
|
||||
|
||||
openidLogin: (provider)->
|
||||
left = @get('lastX') - 400
|
||||
top = @get('lastY') - 200
|
||||
if(provider == "yahoo")
|
||||
@set("authenticate", 'yahoo')
|
||||
window.open("/user_open_ids/frame?provider=yahoo", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top)
|
||||
window.open("/auth/yahoo", "_blank", "menubar=no,status=no,height=400,width=800,left=" + left + ",top=" + top)
|
||||
else
|
||||
window.open("/user_open_ids/frame?provider=google", "_blank", "menubar=no,status=no,height=500,width=850,left=" + left + ",top=" + top)
|
||||
window.open("/auth/google", "_blank", "menubar=no,status=no,height=500,width=850,left=" + left + ",top=" + top)
|
||||
@set("authenticate", 'google')
|
||||
|
||||
authenticationComplete: (options)->
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
class FacebookController < ApplicationController
|
||||
skip_before_filter :check_xhr, only: [:frame, :complete]
|
||||
layout false
|
||||
|
||||
def frame
|
||||
redirect_to oauth_consumer.url_for_oauth_code(:permissions => "email")
|
||||
end
|
||||
|
||||
def complete
|
||||
consumer = oauth_consumer
|
||||
token = consumer.get_access_token(params[:code])
|
||||
|
||||
graph = Koala::Facebook::API.new(token)
|
||||
me = graph.get_object("me")
|
||||
|
||||
email = me["email"]
|
||||
verified = me["verified"]
|
||||
|
||||
name = me["name"]
|
||||
username = User.suggest_username(me["username"])
|
||||
|
||||
verified = me["verified"]
|
||||
|
||||
# non verified accounts are just trouble
|
||||
unless verified
|
||||
render text: "Your account must be verified with facebook, before authenticating with facebook"
|
||||
return
|
||||
end
|
||||
|
||||
session[:authentication] = {
|
||||
facebook: {
|
||||
facebook_user_id: me["id"],
|
||||
link: me["link"],
|
||||
username: me["username"],
|
||||
first_name: me["first_name"],
|
||||
last_name: me["last_name"],
|
||||
email: me["email"],
|
||||
gender: me["gender"],
|
||||
name: me["name"]
|
||||
},
|
||||
email: me["email"],
|
||||
email_valid: true
|
||||
}
|
||||
|
||||
user_info = FacebookUserInfo.where(:facebook_user_id => me["id"]).first
|
||||
|
||||
@data = {
|
||||
username: username,
|
||||
name: name,
|
||||
email: email,
|
||||
auth_provider: "Facebook",
|
||||
email_valid: true
|
||||
}
|
||||
|
||||
if user_info
|
||||
user = user_info.user
|
||||
if user
|
||||
unless user.active
|
||||
user.active = true
|
||||
user.save
|
||||
end
|
||||
log_on_user(user)
|
||||
@data[:authenticated] = true
|
||||
end
|
||||
else
|
||||
user = User.where(email: me["email"]).first
|
||||
if user
|
||||
FacebookUserInfo.create!(session[:authentication][:facebook].merge(user_id: user.id))
|
||||
unless user.active
|
||||
user.active = true
|
||||
user.save
|
||||
end
|
||||
log_on_user(user)
|
||||
@data[:authenticated] = true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
def oauth_consumer
|
||||
require 'koala'
|
||||
|
||||
host = request.host
|
||||
host = "#{host}:#{request.port}" if request.port != 80
|
||||
callback_url = "http://#{host}/facebook/complete"
|
||||
|
||||
oauth = Koala::Facebook::OAuth.new(SiteSetting.facebook_app_id, SiteSetting.facebook_app_secret, callback_url)
|
||||
end
|
||||
|
||||
end
|
|
@ -1,85 +0,0 @@
|
|||
class TwitterController < ApplicationController
|
||||
skip_before_filter :check_xhr, only: [:frame, :complete]
|
||||
layout false
|
||||
|
||||
def frame
|
||||
|
||||
# defer the require as late as possible
|
||||
require 'oauth'
|
||||
|
||||
consumer = oauth_consumer
|
||||
host = request.host
|
||||
host = "#{host}:#{request.port}" if request.port != 80
|
||||
request_token = consumer.get_request_token(:oauth_callback => "http://#{host}/twitter/complete")
|
||||
|
||||
session[:request_token] = request_token.token
|
||||
session[:request_token_secret] = request_token.secret
|
||||
|
||||
redirect_to request_token.authorize_url
|
||||
end
|
||||
|
||||
def complete
|
||||
|
||||
require 'oauth'
|
||||
|
||||
consumer = oauth_consumer
|
||||
|
||||
unless session[:request_token] && session[:request_token_secret]
|
||||
render :text => ('No authentication information was found in the session. Please try again.') and return
|
||||
end
|
||||
|
||||
unless params[:oauth_token].blank? || session[:request_token] == params[:oauth_token]
|
||||
render :text => ('Authentication information does not match session information. Please try again.') and return
|
||||
end
|
||||
|
||||
request_token = OAuth::RequestToken.new(consumer, session[:request_token], session[:request_token_secret])
|
||||
access_token = request_token.get_access_token(:oauth_verifier => params[:oauth_verifier])
|
||||
|
||||
session[:request_token] = request_token.token
|
||||
session[:request_token_secret] = request_token.secret
|
||||
|
||||
screen_name = access_token.params["screen_name"]
|
||||
twitter_user_id = access_token.params["user_id"]
|
||||
|
||||
session[:authentication] = {
|
||||
twitter_user_id: twitter_user_id,
|
||||
twitter_screen_name: screen_name
|
||||
}
|
||||
|
||||
user_info = TwitterUserInfo.where(:twitter_user_id => twitter_user_id).first
|
||||
|
||||
@data = {
|
||||
username: screen_name,
|
||||
auth_provider: "Twitter"
|
||||
}
|
||||
|
||||
if user_info
|
||||
if user_info.user.active
|
||||
log_on_user(user_info.user)
|
||||
@data[:authenticated] = true
|
||||
else
|
||||
@data[:awaiting_activation] = true
|
||||
# send another email ?
|
||||
end
|
||||
else
|
||||
#TODO typheous or some other webscale http request lib that does not block thins
|
||||
require 'open-uri'
|
||||
parsed = ::JSON.parse(open("http://api.twitter.com/1/users/show.json?screen_name=#{screen_name}").read)
|
||||
@data[:name] = parsed["name"]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
def oauth_consumer
|
||||
OAuth::Consumer.new(
|
||||
SiteSetting.twitter_consumer_key,
|
||||
SiteSetting.twitter_consumer_secret,
|
||||
:site => "https://api.twitter.com",
|
||||
:authorize_path => '/oauth/authenticate'
|
||||
)
|
||||
end
|
||||
|
||||
end
|
|
@ -1,192 +0,0 @@
|
|||
require 'openid'
|
||||
require 'openid/extensions/sreg'
|
||||
require 'openid/extensions/ax'
|
||||
require 'openid/store/filesystem'
|
||||
|
||||
require_dependency 'email'
|
||||
|
||||
|
||||
class UserOpenIdsController < ApplicationController
|
||||
layout false
|
||||
|
||||
# need to be able to call this
|
||||
skip_before_filter :check_xhr
|
||||
|
||||
# must be done, cause we may trigger a POST
|
||||
skip_before_filter :verify_authenticity_token, :only => :complete
|
||||
|
||||
def frame
|
||||
if params[:provider] == 'google'
|
||||
params[:user_open_id] = {url: "https://www.google.com/accounts/o8/id"}
|
||||
end
|
||||
if params[:provider] == 'yahoo'
|
||||
params[:user_open_id] = {url: "https://me.yahoo.com"}
|
||||
end
|
||||
create
|
||||
end
|
||||
|
||||
def destroy
|
||||
@open_id = UserOpenId.find(params[:id])
|
||||
if @open_id.user.id == current_user.id
|
||||
@open_id.destroy
|
||||
end
|
||||
redirect_to current_user
|
||||
end
|
||||
|
||||
def new
|
||||
@open_id = UserOpenId.new
|
||||
end
|
||||
|
||||
def create
|
||||
url = params[:user_open_id]
|
||||
|
||||
begin
|
||||
# validations
|
||||
@open_id = UserOpenId.new(url)
|
||||
open_id_request = openid_consumer.begin @open_id.url
|
||||
return_to, realm = ['complete','index'].map {|a| url_for :action => a, :only_path => false}
|
||||
|
||||
add_ax_request(open_id_request)
|
||||
add_sreg_request(open_id_request)
|
||||
|
||||
# immediate mode is not required
|
||||
if open_id_request.send_redirect?(realm, return_to, false)
|
||||
redirect_to open_id_request.redirect_url(realm, return_to, false)
|
||||
else
|
||||
logger.warn("send_redirect? returned false")
|
||||
render :text, open_id_request.html_markup(realm, return_to, false, {'id' => 'openid_form'})
|
||||
end
|
||||
rescue => e
|
||||
flash[:error] = "There seems to be something wrong with your open id url"
|
||||
logger.warn("failed to load contact open id: " + e.to_s)
|
||||
render :text => 'Something went wrong, we have been notified, try again soon'
|
||||
end
|
||||
end
|
||||
|
||||
def complete
|
||||
current_url = url_for(:action => 'complete', :only_path => false)
|
||||
parameters = params.reject{|k,v|request.path_parameters[k]}.reject{|k,v| k == 'action' || k == 'controller'}
|
||||
open_id_response = openid_consumer.complete(parameters, current_url)
|
||||
|
||||
case open_id_response.status
|
||||
when OpenID::Consumer::SUCCESS
|
||||
data = {}
|
||||
if params[:did_sreg]
|
||||
data = get_sreg_response(open_id_response)
|
||||
end
|
||||
|
||||
if params[:did_ax]
|
||||
info = get_ax_response(open_id_response)
|
||||
data.merge!(info)
|
||||
end
|
||||
|
||||
trusted = open_id_response.endpoint.server_url =~ /\Ahttps:\/\/www\.google\.com\// ||
|
||||
open_id_response.endpoint.server_url =~ /\Ahttps:\/\/me\.yahoo\.com\//
|
||||
|
||||
email = data[:email]
|
||||
user_open_id = UserOpenId.where(url: open_id_response.display_identifier).first
|
||||
|
||||
if trusted && user_open_id.nil? && user = User.where(email: email).first
|
||||
# we trust so do an email lookup
|
||||
user_open_id = UserOpenId.create(url: open_id_response.display_identifier, user_id: user.id, email: email, active: true)
|
||||
end
|
||||
|
||||
authenticated = !user_open_id.nil?
|
||||
|
||||
if authenticated
|
||||
user = user_open_id.user
|
||||
|
||||
# If we have to approve users
|
||||
if SiteSetting.must_approve_users? and !user.approved?
|
||||
@data = {awaiting_approval: true}
|
||||
else
|
||||
log_on_user(user)
|
||||
@data = {authenticated: true}
|
||||
end
|
||||
|
||||
else
|
||||
@data = {
|
||||
email: email,
|
||||
name: User.suggest_name(email),
|
||||
username: User.suggest_username(email),
|
||||
email_valid: trusted,
|
||||
auth_provider: "Google"
|
||||
}
|
||||
session[:authentication] = {
|
||||
email: @data[:email],
|
||||
email_valid: @data[:email_valid],
|
||||
openid_url: open_id_response.display_identifier
|
||||
}
|
||||
end
|
||||
|
||||
else
|
||||
# note there are lots of failure reasons, we treat them all as failures
|
||||
logger.warn("Verification #{open_id_response.display_identifier || "" }"\
|
||||
" failed: #{open_id_response.status.to_s}" )
|
||||
logger.warn(open_id_response.message)
|
||||
flash[:error] = "Sorry, I seem to be having trouble confirming your open id account, please try again!"
|
||||
render :text => "Apologies, something went wrong ... try again soon"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
|
||||
def persist_session
|
||||
if s = UserSession.find
|
||||
s.remember_me = true
|
||||
s.save
|
||||
end
|
||||
end
|
||||
|
||||
def openid_consumer
|
||||
@openid_consumer ||= OpenID::Consumer.new(session,
|
||||
OpenID::Store::Filesystem.new("#{Rails.root}/tmp/openid"))
|
||||
end
|
||||
|
||||
def get_sreg_response(open_id_response)
|
||||
data = {}
|
||||
sreg_resp = OpenID::SReg::Response.from_success_response(open_id_response)
|
||||
unless sreg_resp.empty?
|
||||
data[:email] = sreg_resp.data['email']
|
||||
data[:nickname] = sreg_resp.data['nickname']
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
def get_ax_response(open_id_response)
|
||||
data = {}
|
||||
ax_resp = OpenID::AX::FetchResponse.from_success_response(open_id_response)
|
||||
if ax_resp && !ax_resp.data.empty?
|
||||
data[:email] = ax_resp.data['http://schema.openid.net/contact/email'][0]
|
||||
end
|
||||
data
|
||||
end
|
||||
|
||||
def add_sreg_request(open_id_request)
|
||||
sreg_request = OpenID::SReg::Request.new
|
||||
sreg_request.request_fields(['email'], true)
|
||||
# optional
|
||||
sreg_request.request_fields(['dob', 'fullname', 'nickname'], false)
|
||||
open_id_request.add_extension(sreg_request)
|
||||
open_id_request.return_to_args['did_sreg'] = 'y'
|
||||
|
||||
end
|
||||
|
||||
def add_ax_request(open_id_request)
|
||||
ax_request = OpenID::AX::FetchRequest.new
|
||||
requested_attrs = [
|
||||
['namePerson', 'fullname'],
|
||||
['namePerson/friendly', 'nickname'],
|
||||
['contact/email', 'email', true],
|
||||
['contact/web/default', 'web_default'],
|
||||
['birthDate', 'dob'],
|
||||
['contact/country/home', 'country']
|
||||
]
|
||||
|
||||
requested_attrs.each {|a| ax_request.add(OpenID::AX::AttrInfo.new("http://schema.openid.net/#{a[0]}", a[1], a[2] || false))}
|
||||
open_id_request.add_extension(ax_request)
|
||||
open_id_request.return_to_args['did_ax'] = 'y'
|
||||
end
|
||||
end
|
163
app/controllers/users/omniauth_callbacks_controller.rb
Normal file
163
app/controllers/users/omniauth_callbacks_controller.rb
Normal file
|
@ -0,0 +1,163 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
require_dependency 'email'
|
||||
class Users::OmniauthCallbacksController < ApplicationController
|
||||
|
||||
layout false
|
||||
|
||||
# need to be able to call this
|
||||
skip_before_filter :check_xhr
|
||||
|
||||
# must be done, cause we may trigger a POST
|
||||
skip_before_filter :verify_authenticity_token, :only => :complete
|
||||
|
||||
def complete
|
||||
auth_token = env["omniauth.auth"]
|
||||
case params[:provider]
|
||||
when "facebook"
|
||||
create_or_sign_on_user_using_facebook(auth_token)
|
||||
when "twitter"
|
||||
create_or_sign_on_user_using_twitter(auth_token)
|
||||
when "google", "yahoo"
|
||||
create_or_sign_on_user_using_openid(auth_token)
|
||||
end
|
||||
end
|
||||
|
||||
def create_or_sign_on_user_using_twitter(auth_token)
|
||||
|
||||
data = auth_token[:info]
|
||||
screen_name = data["nickname"]
|
||||
twitter_user_id = auth_token["uid"]
|
||||
|
||||
session[:authentication] = {
|
||||
twitter_user_id: twitter_user_id,
|
||||
twitter_screen_name: screen_name
|
||||
}
|
||||
|
||||
user_info = TwitterUserInfo.where(:twitter_user_id => twitter_user_id).first
|
||||
|
||||
@data = {
|
||||
username: screen_name,
|
||||
auth_provider: "Twitter"
|
||||
}
|
||||
|
||||
if user_info
|
||||
if user_info.user.active
|
||||
log_on_user(user_info.user)
|
||||
@data[:authenticated] = true
|
||||
else
|
||||
@data[:awaiting_activation] = true
|
||||
# send another email ?
|
||||
end
|
||||
else
|
||||
@data[:name] = screen_name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def create_or_sign_on_user_using_facebook(auth_token)
|
||||
|
||||
data = auth_token[:info]
|
||||
raw_info = auth_token["extra"]["raw_info"]
|
||||
|
||||
email = data[:email]
|
||||
name = data["name"]
|
||||
fb_uid = auth_token["uid"]
|
||||
|
||||
|
||||
username = User.suggest_username(name)
|
||||
|
||||
|
||||
session[:authentication] = {
|
||||
facebook: {
|
||||
facebook_user_id: fb_uid ,
|
||||
link: raw_info["link"],
|
||||
username: raw_info["username"],
|
||||
first_name: raw_info["first_name"],
|
||||
last_name: raw_info["last_name"],
|
||||
email: raw_info["email"],
|
||||
gender: raw_info["gender"],
|
||||
name: raw_info["name"]
|
||||
},
|
||||
email: email,
|
||||
email_valid: true
|
||||
}
|
||||
|
||||
user_info = FacebookUserInfo.where(:facebook_user_id => fb_uid ).first
|
||||
|
||||
@data = {
|
||||
username: username,
|
||||
name: name,
|
||||
email: email,
|
||||
auth_provider: "Facebook",
|
||||
email_valid: true
|
||||
}
|
||||
|
||||
if user_info
|
||||
user = user_info.user
|
||||
if user
|
||||
unless user.active
|
||||
user.active = true
|
||||
user.save
|
||||
end
|
||||
log_on_user(user)
|
||||
@data[:authenticated] = true
|
||||
end
|
||||
else
|
||||
user = User.where(email: email).first
|
||||
if user
|
||||
FacebookUserInfo.create!(session[:authentication][:facebook].merge(user_id: user.id))
|
||||
unless user.active
|
||||
user.active = true
|
||||
user.save
|
||||
end
|
||||
log_on_user(user)
|
||||
@data[:authenticated] = true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def create_or_sign_on_user_using_openid(auth_token)
|
||||
|
||||
data = auth_token[:info]
|
||||
identity_url = auth_token[:extra][:identity_url]
|
||||
|
||||
email = data[:email]
|
||||
|
||||
user_open_id = UserOpenId.find_by_url(identity_url)
|
||||
|
||||
if user_open_id.blank? && user = User.find_by_email(email)
|
||||
# we trust so do an email lookup
|
||||
user_open_id = UserOpenId.create(url: identity_url , user_id: user.id, email: email, active: true)
|
||||
end
|
||||
|
||||
authenticated = user_open_id # if authed before
|
||||
|
||||
if authenticated
|
||||
user = user_open_id.user
|
||||
|
||||
# If we have to approve users
|
||||
if SiteSetting.must_approve_users? and !user.approved?
|
||||
@data = {awaiting_approval: true}
|
||||
else
|
||||
log_on_user(user)
|
||||
@data = {authenticated: true}
|
||||
end
|
||||
|
||||
else
|
||||
@data = {
|
||||
email: email,
|
||||
name: User.suggest_name(email),
|
||||
username: User.suggest_username(email),
|
||||
email_valid: true ,
|
||||
auth_provider: data[:provider]
|
||||
}
|
||||
session[:authentication] = {
|
||||
email: @data[:email],
|
||||
email_valid: @data[:email_valid],
|
||||
openid_url: identity_url
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -1,9 +0,0 @@
|
|||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
window.opener.Discourse.authenticationComplete(<%=@data.to_json.html_safe%>);
|
||||
window.close();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,9 +0,0 @@
|
|||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
window.opener.Discourse.authenticationComplete(<%=@data.to_json.html_safe%>);
|
||||
window.close();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
17
config/initializers/omniauth.rb
Normal file
17
config/initializers/omniauth.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
require 'openid/store/filesystem'
|
||||
require 'openssl'
|
||||
require 'openid_redis_store'
|
||||
module OpenSSL
|
||||
module SSL
|
||||
remove_const :VERIFY_PEER
|
||||
end
|
||||
end
|
||||
|
||||
OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
|
||||
|
||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
provider :open_id, :store => OpenID::Store::Redis.new($redis), :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id', :require => 'omniauth-openid'
|
||||
provider :open_id, :store => OpenID::Store::Redis.new($redis), :name => 'yahoo', :identifier => 'https://me.yahoo.com', :require => 'omniauth-openid'
|
||||
provider :facebook, SiteSetting.facebook_app_id, SiteSetting.facebook_app_secret, :scope => "email"
|
||||
provider :twitter, SiteSetting.twitter_consumer_key , SiteSetting.twitter_consumer_secret
|
||||
end
|
|
@ -111,12 +111,8 @@ Discourse::Application.routes.draw do
|
|||
|
||||
resources :notifications
|
||||
resources :categories
|
||||
resources :user_open_ids do
|
||||
collection do
|
||||
get 'frame'
|
||||
get 'complete'
|
||||
end
|
||||
end
|
||||
|
||||
match "/auth/:provider/callback", to: "users/omniauth_callbacks#complete"
|
||||
|
||||
get 'twitter/frame' => 'twitter#frame'
|
||||
get 'twitter/complete' => 'twitter#complete'
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe "facebook/complete.html.erb" do
|
||||
it "renders data " do
|
||||
assign(:data, {:username =>"username", :auth_provider=>"Facebook", :awaiting_activation=>true})
|
||||
|
||||
render
|
||||
|
||||
rendered_data = JSON.parse(rendered.match(/window.opener.Discourse.authenticationComplete\((.*)\)/)[1])
|
||||
|
||||
rendered_data["username"].should eq("username")
|
||||
rendered_data["auth_provider"].should eq("Facebook")
|
||||
rendered_data["awaiting_activation"].should eq(true)
|
||||
end
|
||||
end
|
43
spec/views/omniauth_callbacks/complete.html.erb_spec.rb
Normal file
43
spec/views/omniauth_callbacks/complete.html.erb_spec.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe "users/omniauth_callbacks/complete.html.erb" do
|
||||
it "renders facebook data " do
|
||||
assign(:data, {:username =>"username", :auth_provider=> "Facebook", :awaiting_activation=>true})
|
||||
|
||||
render
|
||||
|
||||
rendered_data = JSON.parse(rendered.match(/window.opener.Discourse.authenticationComplete\((.*)\)/)[1])
|
||||
|
||||
rendered_data["username"].should eq("username")
|
||||
rendered_data["auth_provider"].should eq("Facebook")
|
||||
rendered_data["awaiting_activation"].should eq(true)
|
||||
end
|
||||
|
||||
it "renders twitter data " do
|
||||
assign(:data, {:username =>"username", :auth_provider=>"Twitter", :awaiting_activation=>true})
|
||||
|
||||
render
|
||||
|
||||
rendered_data = JSON.parse(rendered.match(/window.opener.Discourse.authenticationComplete\((.*)\)/)[1])
|
||||
|
||||
rendered_data["username"].should eq("username")
|
||||
rendered_data["auth_provider"].should eq("Twitter")
|
||||
rendered_data["awaiting_activation"].should eq(true)
|
||||
end
|
||||
|
||||
|
||||
it "renders openid data " do
|
||||
assign(:data, {:username =>"username", :auth_provider=>"OpenId", :awaiting_activation=>true})
|
||||
|
||||
render
|
||||
|
||||
rendered_data = JSON.parse(rendered.match(/window.opener.Discourse.authenticationComplete\((.*)\)/)[1])
|
||||
|
||||
rendered_data["username"].should eq("username")
|
||||
rendered_data["auth_provider"].should eq("OpenId")
|
||||
rendered_data["awaiting_activation"].should eq(true)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe "twitter/complete.html.erb" do
|
||||
it "renders data " do
|
||||
assign(:data, {:username =>"username", :auth_provider=>"Twitter", :awaiting_activation=>true})
|
||||
|
||||
render
|
||||
|
||||
rendered_data = JSON.parse(rendered.match(/window.opener.Discourse.authenticationComplete\((.*)\)/)[1])
|
||||
|
||||
rendered_data["username"].should eq("username")
|
||||
rendered_data["auth_provider"].should eq("Twitter")
|
||||
rendered_data["awaiting_activation"].should eq(true)
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe "user_open_ids/complete.html.erb" do
|
||||
it "renders data " do
|
||||
assign(:data, {:username =>"username", :auth_provider=>"OpenId", :awaiting_activation=>true})
|
||||
|
||||
render
|
||||
|
||||
rendered_data = JSON.parse(rendered.match(/window.opener.Discourse.authenticationComplete\((.*)\)/)[1])
|
||||
|
||||
rendered_data["username"].should eq("username")
|
||||
rendered_data["auth_provider"].should eq("OpenId")
|
||||
rendered_data["awaiting_activation"].should eq(true)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user