mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 15:48:43 -05:00
use omniauth-openid to replace google id
This commit is contained in:
parent
6e74b4fb0c
commit
be3d036084
6 changed files with 65 additions and 162 deletions
3
Gemfile
3
Gemfile
|
@ -27,6 +27,8 @@ gem 'koala', require: false
|
||||||
gem 'multi_json'
|
gem 'multi_json'
|
||||||
gem 'mustache'
|
gem 'mustache'
|
||||||
gem 'nokogiri'
|
gem 'nokogiri'
|
||||||
|
gem "omniauth"
|
||||||
|
gem "omniauth-openid"
|
||||||
gem 'oauth', require: false
|
gem 'oauth', require: false
|
||||||
gem 'oj'
|
gem 'oj'
|
||||||
gem 'pbkdf2'
|
gem 'pbkdf2'
|
||||||
|
@ -37,7 +39,6 @@ gem 'redis'
|
||||||
gem 'redis-rails'
|
gem 'redis-rails'
|
||||||
gem 'rest-client'
|
gem 'rest-client'
|
||||||
gem 'rinku'
|
gem 'rinku'
|
||||||
gem 'ruby-openid', require: 'openid'
|
|
||||||
gem 'sanitize'
|
gem 'sanitize'
|
||||||
gem 'sass'
|
gem 'sass'
|
||||||
gem 'seed-fu'
|
gem 'seed-fu'
|
||||||
|
|
13
Gemfile.lock
13
Gemfile.lock
|
@ -174,6 +174,7 @@ GEM
|
||||||
spork (>= 0.8.4)
|
spork (>= 0.8.4)
|
||||||
haml (3.1.7)
|
haml (3.1.7)
|
||||||
has_ip_address (0.0.1)
|
has_ip_address (0.0.1)
|
||||||
|
hashie (1.2.0)
|
||||||
hike (1.2.1)
|
hike (1.2.1)
|
||||||
hiredis (0.4.5)
|
hiredis (0.4.5)
|
||||||
hpricot (0.8.6)
|
hpricot (0.8.6)
|
||||||
|
@ -220,6 +221,12 @@ GEM
|
||||||
nokogiri (1.5.6)
|
nokogiri (1.5.6)
|
||||||
oauth (0.4.7)
|
oauth (0.4.7)
|
||||||
oj (2.0.3)
|
oj (2.0.3)
|
||||||
|
omniauth (1.1.1)
|
||||||
|
hashie (~> 1.2)
|
||||||
|
rack
|
||||||
|
omniauth-openid (1.0.1)
|
||||||
|
omniauth (~> 1.0)
|
||||||
|
rack-openid (~> 1.3.1)
|
||||||
pbkdf2 (0.1.0)
|
pbkdf2 (0.1.0)
|
||||||
pg (0.14.1)
|
pg (0.14.1)
|
||||||
polyglot (0.3.3)
|
polyglot (0.3.3)
|
||||||
|
@ -233,6 +240,9 @@ GEM
|
||||||
rack (1.4.5)
|
rack (1.4.5)
|
||||||
rack-cache (1.2)
|
rack-cache (1.2)
|
||||||
rack (>= 0.4)
|
rack (>= 0.4)
|
||||||
|
rack-openid (1.3.1)
|
||||||
|
rack (>= 1.1.0)
|
||||||
|
ruby-openid (>= 2.1.8)
|
||||||
rack-protection (1.3.2)
|
rack-protection (1.3.2)
|
||||||
rack
|
rack
|
||||||
rack-ssl (1.3.3)
|
rack-ssl (1.3.3)
|
||||||
|
@ -406,6 +416,8 @@ DEPENDENCIES
|
||||||
nokogiri
|
nokogiri
|
||||||
oauth
|
oauth
|
||||||
oj
|
oj
|
||||||
|
omniauth
|
||||||
|
omniauth-openid
|
||||||
pbkdf2
|
pbkdf2
|
||||||
pg
|
pg
|
||||||
pry-rails
|
pry-rails
|
||||||
|
@ -420,7 +432,6 @@ DEPENDENCIES
|
||||||
rest-client
|
rest-client
|
||||||
rinku
|
rinku
|
||||||
rspec-rails
|
rspec-rails
|
||||||
ruby-openid
|
|
||||||
sanitize
|
sanitize
|
||||||
sass
|
sass
|
||||||
sass-rails
|
sass-rails
|
||||||
|
|
|
@ -60,9 +60,9 @@ window.Discourse.LoginView = window.Discourse.ModalBodyView.extend Discourse.Pre
|
||||||
top = @get('lastY') - 200
|
top = @get('lastY') - 200
|
||||||
if(provider == "yahoo")
|
if(provider == "yahoo")
|
||||||
@set("authenticate", '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
|
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')
|
@set("authenticate", 'google')
|
||||||
|
|
||||||
authenticationComplete: (options)->
|
authenticationComplete: (options)->
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
require 'openid'
|
|
||||||
require 'openid/extensions/sreg'
|
|
||||||
require 'openid/extensions/ax'
|
|
||||||
require 'openid/store/filesystem'
|
|
||||||
|
|
||||||
require_dependency 'email'
|
require_dependency 'email'
|
||||||
|
|
||||||
|
|
||||||
class UserOpenIdsController < ApplicationController
|
class UserOpenIdsController < ApplicationController
|
||||||
layout false
|
layout false
|
||||||
|
|
||||||
|
@ -15,16 +9,6 @@ class UserOpenIdsController < ApplicationController
|
||||||
# must be done, cause we may trigger a POST
|
# must be done, cause we may trigger a POST
|
||||||
skip_before_filter :verify_authenticity_token, :only => :complete
|
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
|
def destroy
|
||||||
@open_id = UserOpenId.find(params[:id])
|
@open_id = UserOpenId.find(params[:id])
|
||||||
if @open_id.user.id == current_user.id
|
if @open_id.user.id == current_user.id
|
||||||
|
@ -37,156 +21,52 @@ class UserOpenIdsController < ApplicationController
|
||||||
@open_id = UserOpenId.new
|
@open_id = UserOpenId.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def complete
|
||||||
url = params[:user_open_id]
|
auth_token = env["omniauth.auth"]
|
||||||
|
create_or_sign_on_user(auth_token)
|
||||||
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
|
end
|
||||||
|
|
||||||
def complete
|
def create_or_sign_on_user(auth_token)
|
||||||
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
|
data = auth_token[:info]
|
||||||
when OpenID::Consumer::SUCCESS
|
identity_url = auth_token[:extra][:identity_url]
|
||||||
data = {}
|
|
||||||
if params[:did_sreg]
|
|
||||||
data = get_sreg_response(open_id_response)
|
|
||||||
end
|
|
||||||
|
|
||||||
if params[:did_ax]
|
email = data[:email]
|
||||||
info = get_ax_response(open_id_response)
|
|
||||||
data.merge!(info)
|
|
||||||
end
|
|
||||||
|
|
||||||
trusted = open_id_response.endpoint.server_url =~ /^https:\/\/www.google.com\// ||
|
user_open_id = UserOpenId.find_by_url(identity_url)
|
||||||
open_id_response.endpoint.server_url =~ /^https:\/\/me.yahoo.com\//
|
|
||||||
|
|
||||||
email = data[:email]
|
if user_open_id.blank? && user = User.find_by_email(email)
|
||||||
user_open_id = UserOpenId.where(url: open_id_response.display_identifier).first
|
# we trust so do an email lookup
|
||||||
|
user_open_id = UserOpenId.create(url: identity_url , user_id: user.id, email: email, active: true)
|
||||||
|
end
|
||||||
|
|
||||||
if trusted && user_open_id.nil? && user = User.where(email: email).first
|
authenticated = user_open_id # if authed before
|
||||||
# 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 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
|
|
||||||
|
|
||||||
|
# If we have to approve users
|
||||||
|
if SiteSetting.must_approve_users? and !user.approved?
|
||||||
|
@data = {awaiting_approval: true}
|
||||||
else
|
else
|
||||||
@data = {
|
log_on_user(user)
|
||||||
email: email,
|
@data = {authenticated: true}
|
||||||
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
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
# note there are lots of failure reasons, we treat them all as failures
|
@data = {
|
||||||
logger.warn("Verification #{open_id_response.display_identifier || "" }"\
|
email: email,
|
||||||
" failed: #{open_id_response.status.to_s}" )
|
name: User.suggest_name(email),
|
||||||
logger.warn(open_id_response.message)
|
username: User.suggest_username(email),
|
||||||
flash[:error] = "Sorry, I seem to be having trouble confirming your open id account, please try again!"
|
email_valid: true ,
|
||||||
render :text => "Apologies, something went wrong ... try again soon"
|
auth_provider: data[:provider]
|
||||||
|
}
|
||||||
|
session[:authentication] = {
|
||||||
|
email: @data[:email],
|
||||||
|
email_valid: @data[:email_valid],
|
||||||
|
openid_url: identity_url
|
||||||
|
}
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
15
config/initializers/omniauth.rb
Normal file
15
config/initializers/omniauth.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require 'openid/store/filesystem'
|
||||||
|
require 'openssl'
|
||||||
|
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::Filesystem.new('/tmp'), :name => 'google', :identifier => 'https://www.google.com/accounts/o8/id', :require => 'omniauth-openid'
|
||||||
|
provider :open_id, :store => OpenID::Store::Filesystem.new('/tmp'), :name => 'yahoo', :identifier => 'https://me.yahoo.com', :require => 'omniauth-openid'
|
||||||
|
|
||||||
|
end
|
|
@ -111,12 +111,8 @@ Discourse::Application.routes.draw do
|
||||||
|
|
||||||
resources :notifications
|
resources :notifications
|
||||||
resources :categories
|
resources :categories
|
||||||
resources :user_open_ids do
|
|
||||||
collection do
|
match '/auth/:provider/callback', to: 'user_open_ids#complete'
|
||||||
get 'frame'
|
|
||||||
get 'complete'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
get 'twitter/frame' => 'twitter#frame'
|
get 'twitter/frame' => 'twitter#frame'
|
||||||
get 'twitter/complete' => 'twitter#complete'
|
get 'twitter/complete' => 'twitter#complete'
|
||||||
|
|
Loading…
Reference in a new issue