Merge pull request #253 from differentreality/final_openid
Authenticate via openid
This commit is contained in:
commit
0c698bac10
24 changed files with 412 additions and 15 deletions
5
Gemfile
5
Gemfile
|
|
@ -14,6 +14,11 @@ gem 'paper_trail'
|
||||||
|
|
||||||
# Use devise as authentification framework
|
# Use devise as authentification framework
|
||||||
gem 'devise'
|
gem 'devise'
|
||||||
|
# Use omniauth to support openID authentication
|
||||||
|
gem 'omniauth'
|
||||||
|
gem 'omniauth-facebook'
|
||||||
|
gem 'omniauth-openid'
|
||||||
|
gem 'omniauth-google-oauth2'
|
||||||
|
|
||||||
# Use cancan as authorization framework
|
# Use cancan as authorization framework
|
||||||
gem 'cancan'
|
gem 'cancan'
|
||||||
|
|
|
||||||
36
Gemfile.lock
36
Gemfile.lock
|
|
@ -103,6 +103,8 @@ GEM
|
||||||
factory_girl_rails (4.4.1)
|
factory_girl_rails (4.4.1)
|
||||||
factory_girl (~> 4.4.0)
|
factory_girl (~> 4.4.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
|
faraday (0.9.0)
|
||||||
|
multipart-post (>= 1.2, < 3)
|
||||||
ffi (1.9.3)
|
ffi (1.9.3)
|
||||||
formatador (0.2.4)
|
formatador (0.2.4)
|
||||||
formtastic (2.3.0.rc3)
|
formtastic (2.3.0.rc3)
|
||||||
|
|
@ -126,6 +128,7 @@ GEM
|
||||||
activesupport (>= 4.0.1)
|
activesupport (>= 4.0.1)
|
||||||
haml (>= 3.1, < 5.0)
|
haml (>= 3.1, < 5.0)
|
||||||
railties (>= 4.0.1)
|
railties (>= 4.0.1)
|
||||||
|
hashie (2.1.1)
|
||||||
hike (1.2.3)
|
hike (1.2.3)
|
||||||
hoptoad_notifier (2.4.11)
|
hoptoad_notifier (2.4.11)
|
||||||
activesupport
|
activesupport
|
||||||
|
|
@ -143,6 +146,7 @@ GEM
|
||||||
jquery-ui-rails (4.2.1)
|
jquery-ui-rails (4.2.1)
|
||||||
railties (>= 3.2.16)
|
railties (>= 3.2.16)
|
||||||
json (1.8.1)
|
json (1.8.1)
|
||||||
|
jwt (1.0.0)
|
||||||
launchy (2.4.2)
|
launchy (2.4.2)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
letter_opener (1.2.0)
|
letter_opener (1.2.0)
|
||||||
|
|
@ -162,10 +166,34 @@ GEM
|
||||||
mini_portile (0.6.0)
|
mini_portile (0.6.0)
|
||||||
minitest (5.3.3)
|
minitest (5.3.3)
|
||||||
multi_json (1.9.2)
|
multi_json (1.9.2)
|
||||||
|
multi_xml (0.5.5)
|
||||||
|
multipart-post (2.0.0)
|
||||||
mysql2 (0.3.16)
|
mysql2 (0.3.16)
|
||||||
nio4r (1.0.0)
|
nio4r (1.0.0)
|
||||||
nokogiri (1.6.2.1)
|
nokogiri (1.6.2.1)
|
||||||
mini_portile (= 0.6.0)
|
mini_portile (= 0.6.0)
|
||||||
|
oauth2 (0.9.4)
|
||||||
|
faraday (>= 0.8, < 0.10)
|
||||||
|
jwt (~> 1.0)
|
||||||
|
multi_json (~> 1.3)
|
||||||
|
multi_xml (~> 0.5)
|
||||||
|
rack (~> 1.2)
|
||||||
|
omniauth (1.2.1)
|
||||||
|
hashie (>= 1.2, < 3)
|
||||||
|
rack (~> 1.0)
|
||||||
|
omniauth-facebook (1.6.0)
|
||||||
|
omniauth-oauth2 (~> 1.1)
|
||||||
|
omniauth-google-oauth2 (0.2.4)
|
||||||
|
omniauth (~> 1.0)
|
||||||
|
omniauth-oauth2 (~> 1.1)
|
||||||
|
omniauth-oauth2 (1.1.2)
|
||||||
|
faraday (>= 0.8, < 0.10)
|
||||||
|
multi_json (~> 1.3)
|
||||||
|
oauth2 (~> 0.9.3)
|
||||||
|
omniauth (~> 1.2)
|
||||||
|
omniauth-openid (1.0.1)
|
||||||
|
omniauth (~> 1.0)
|
||||||
|
rack-openid (~> 1.3.1)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
paper_trail (3.0.1)
|
paper_trail (3.0.1)
|
||||||
activerecord (>= 3.0, < 5.0)
|
activerecord (>= 3.0, < 5.0)
|
||||||
|
|
@ -196,6 +224,9 @@ GEM
|
||||||
quiet_assets (1.0.2)
|
quiet_assets (1.0.2)
|
||||||
railties (>= 3.1, < 5.0)
|
railties (>= 3.1, < 5.0)
|
||||||
rack (1.5.2)
|
rack (1.5.2)
|
||||||
|
rack-openid (1.3.1)
|
||||||
|
rack (>= 1.1.0)
|
||||||
|
ruby-openid (>= 2.1.8)
|
||||||
rack-test (0.6.2)
|
rack-test (0.6.2)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.1.0)
|
rails (4.1.0)
|
||||||
|
|
@ -259,6 +290,7 @@ GEM
|
||||||
powerpack (~> 0.0.6)
|
powerpack (~> 0.0.6)
|
||||||
rainbow (>= 1.99.1, < 3.0)
|
rainbow (>= 1.99.1, < 3.0)
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
|
ruby-openid (2.5.0)
|
||||||
ruby-progressbar (1.5.1)
|
ruby-progressbar (1.5.1)
|
||||||
rubyzip (1.0.0)
|
rubyzip (1.0.0)
|
||||||
sass (3.2.19)
|
sass (3.2.19)
|
||||||
|
|
@ -346,6 +378,10 @@ DEPENDENCIES
|
||||||
jquery-ui-rails
|
jquery-ui-rails
|
||||||
letter_opener
|
letter_opener
|
||||||
mysql2
|
mysql2
|
||||||
|
omniauth
|
||||||
|
omniauth-facebook
|
||||||
|
omniauth-google-oauth2
|
||||||
|
omniauth-openid
|
||||||
paper_trail
|
paper_trail
|
||||||
paperclip
|
paperclip
|
||||||
prawn_rails
|
prawn_rails
|
||||||
|
|
|
||||||
BIN
app/assets/images/facebook.png
Normal file
BIN
app/assets/images/facebook.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/assets/images/google.png
Normal file
BIN
app/assets/images/google.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/assets/images/novell.png
Normal file
BIN
app/assets/images/novell.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 413 B |
|
|
@ -1,6 +1,10 @@
|
||||||
class RegistrationsController < Devise::RegistrationsController
|
class RegistrationsController < Devise::RegistrationsController
|
||||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@openids = Openid.where(user_id: current_user.id).order(:provider)
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@user = User.find(current_user.id)
|
@user = User.find(current_user.id)
|
||||||
email_changed = false
|
email_changed = false
|
||||||
|
|
|
||||||
34
app/controllers/users/omniauth_callbacks_controller.rb
Normal file
34
app/controllers/users/omniauth_callbacks_controller.rb
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
module Users
|
||||||
|
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||||
|
skip_before_filter :verify_authenticity_token
|
||||||
|
|
||||||
|
[:novell, :google, :facebook, :twitter].each do |provider|
|
||||||
|
define_method(provider) { handle(provider) }
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def handle(provider)
|
||||||
|
auth_hash = request.env['omniauth.auth']
|
||||||
|
openid = Openid.find_for_oauth(auth_hash) # Get or create openid
|
||||||
|
# If openid exists and is associated with a user, sign in with associated user,
|
||||||
|
# even if the email of the associated user and the email of the provided openid are different
|
||||||
|
unless user = openid.user
|
||||||
|
user = User.find_for_auth(auth_hash, current_user) # Get or create users
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
user.save!
|
||||||
|
if openid.user != user
|
||||||
|
openid.user = user
|
||||||
|
end
|
||||||
|
openid.save!
|
||||||
|
|
||||||
|
sign_in user
|
||||||
|
redirect_to root_path, notice: user.email + " signed in successfully with #{provider}"
|
||||||
|
rescue Exception => e
|
||||||
|
redirect_back_or_to new_user_registration_path, alert: 'Failed' + e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -37,4 +37,4 @@ class DatatableSupporters < Datatable
|
||||||
def columns
|
def columns
|
||||||
["name", "email", "name", "name", "name"]
|
["name", "email", "name", "name", "name"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
20
app/models/openid.rb
Normal file
20
app/models/openid.rb
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
class Openid < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
validates :provider, :uid, presence: true
|
||||||
|
|
||||||
|
# Searches for openid based on provider and uid.
|
||||||
|
# Returns found openid or a new openid.
|
||||||
|
# ====Returns
|
||||||
|
# * Openid::ActiveRecord_Relation -> openid
|
||||||
|
def self.find_for_oauth(auth)
|
||||||
|
openid = Openid.where(provider: auth.provider, uid: auth.uid).first_or_initialize
|
||||||
|
|
||||||
|
if openid.new_record?
|
||||||
|
openid.email = auth.info.email
|
||||||
|
if existing_openid = Openid.where(email: openid.email).first
|
||||||
|
openid.user_id = existing_openid.user_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
openid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -4,13 +4,15 @@ class User < ActiveRecord::Base
|
||||||
# :token_authenticatable, :confirmable,
|
# :token_authenticatable, :confirmable,
|
||||||
# :lockable, :timeoutable and :omniauthable
|
# :lockable, :timeoutable and :omniauthable
|
||||||
devise :database_authenticatable, :registerable,
|
devise :database_authenticatable, :registerable,
|
||||||
:recoverable, :rememberable, :trackable, :validatable,
|
:recoverable, :rememberable, :trackable, :validatable, :confirmable,
|
||||||
:confirmable
|
:omniauthable, omniauth_providers: [:novell, :google, :facebook]
|
||||||
|
|
||||||
has_and_belongs_to_many :roles
|
has_and_belongs_to_many :roles
|
||||||
has_one :person, :inverse_of => :user
|
has_one :person, :inverse_of => :user
|
||||||
|
has_many :openids
|
||||||
|
|
||||||
attr_accessible :email, :password, :password_confirmation, :remember_me, :role_id, :role_ids, :person_attributes
|
attr_accessible :email, :password, :password_confirmation, :remember_me, :role_id, :role_ids,
|
||||||
|
:person_attributes
|
||||||
accepts_nested_attributes_for :person
|
accepts_nested_attributes_for :person
|
||||||
accepts_nested_attributes_for :roles
|
accepts_nested_attributes_for :roles
|
||||||
|
|
||||||
|
|
@ -19,6 +21,25 @@ class User < ActiveRecord::Base
|
||||||
|
|
||||||
delegate :last_name, :first_name, :public_name, to: :person
|
delegate :last_name, :first_name, :public_name, to: :person
|
||||||
|
|
||||||
|
# Searches for user based on email. Returns found user or new user.
|
||||||
|
# ====Returns
|
||||||
|
# * +User::ActiveRecord_Relation+ -> user
|
||||||
|
def self.find_for_auth(auth, current_user = nil)
|
||||||
|
user = current_user
|
||||||
|
|
||||||
|
if user.nil? # No current user available, user is not already logged in
|
||||||
|
user = User.where(email: auth.info.email).first_or_initialize
|
||||||
|
end
|
||||||
|
|
||||||
|
if user.new_record?
|
||||||
|
user.email = auth.info.email
|
||||||
|
user.password = Devise.friendly_token[0, 20]
|
||||||
|
user.skip_confirmation!
|
||||||
|
end
|
||||||
|
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
def role?(role)
|
def role?(role)
|
||||||
Rails.logger.debug("Checking role in user")
|
Rails.logger.debug("Checking role in user")
|
||||||
!!roles.find_by_name(role.to_s.downcase.camelize)
|
!!roles.find_by_name(role.to_s.downcase.camelize)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,18 @@
|
||||||
%br
|
%br
|
||||||
%br
|
%br
|
||||||
= render :partial => 'devise/registrations/volunteerperson', :locals => {:p => p}
|
= render :partial => 'devise/registrations/volunteerperson', :locals => {:p => p}
|
||||||
|
= f.inputs :name => 'OpenID' do
|
||||||
|
%h4
|
||||||
|
Currently using the following openIDs:
|
||||||
|
- @openids.each do |openid|
|
||||||
|
= openid.provider
|
||||||
|
= openid.email
|
||||||
|
%br
|
||||||
|
%h4
|
||||||
|
To add an openID to your account using a different email address, sign in with your
|
||||||
|
openID while logged in to OSEM
|
||||||
|
= render 'devise/shared/openid'
|
||||||
|
|
||||||
= f.inputs :name => "Account" do
|
= f.inputs :name => "Account" do
|
||||||
= f.input :email, :required => false
|
= f.input :email, :required => false
|
||||||
= f.input :password, :hint => "(Leave blank if you don't want to change it)", :input_html => {:autocomplete => "off"}
|
= f.input :password, :hint => "(Leave blank if you don't want to change it)", :input_html => {:autocomplete => "off"}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,17 @@
|
||||||
%h1.text-center Sign Up
|
%h1.text-center Sign Up
|
||||||
.col-md-5.col-md-offset-1
|
.col-md-5.col-md-offset-1
|
||||||
.well
|
.well
|
||||||
= semantic_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
|
= semantic_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
|
||||||
= f.input :email
|
= f.input :email
|
||||||
= f.input :password
|
= f.input :password
|
||||||
= f.input :password_confirmation
|
= f.input :password_confirmation
|
||||||
= f.action :submit, :as => :button, :label => "Sign Up", :button_html => {:class => "btn btn-primary"}
|
= f.action :submit, as: :button, label: 'Sign Up', button_html: {class: 'btn btn-primary'}
|
||||||
.col-md-3.col-md-offset-2
|
%br
|
||||||
|
%br
|
||||||
|
%h4 Already have an account?
|
||||||
|
= render 'devise/shared/links'
|
||||||
|
.col-md-4
|
||||||
.well
|
.well
|
||||||
%h4
|
%h4 Or use your openID
|
||||||
Already have an account?
|
|
||||||
= render "devise/shared/links"
|
= render 'devise/shared/openid'
|
||||||
|
|
|
||||||
21
app/views/devise/sessions/new.html.haml
Normal file
21
app/views/devise/sessions/new.html.haml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
.row
|
||||||
|
.page-header
|
||||||
|
%h2.text-center Sign In
|
||||||
|
.col-md-5.col-md-offset-1
|
||||||
|
.well
|
||||||
|
= semantic_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
|
||||||
|
= f.input :email
|
||||||
|
= f.input :password
|
||||||
|
- if devise_mapping.rememberable?
|
||||||
|
= f.check_box :remember_me
|
||||||
|
= f.label 'Remember me'
|
||||||
|
%br
|
||||||
|
= f.action :submit, as: :button, label: 'Sign In', button_html: {class: 'btn btn-primary'}
|
||||||
|
%br
|
||||||
|
%br
|
||||||
|
= render "devise/shared/links"
|
||||||
|
|
||||||
|
.col-md-4
|
||||||
|
.well
|
||||||
|
%h4 Or use your openID
|
||||||
|
= render 'devise/shared/openid'
|
||||||
19
app/views/devise/shared/_links.html.haml
Normal file
19
app/views/devise/shared/_links.html.haml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
- if controller_name != 'sessions'
|
||||||
|
= link_to "Sign in", new_user_session_path
|
||||||
|
%br
|
||||||
|
|
||||||
|
- if devise_mapping.registerable? && controller_name != 'registrations'
|
||||||
|
= link_to "Sign up", new_registration_path(resource_name)
|
||||||
|
%br
|
||||||
|
|
||||||
|
- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
|
||||||
|
= link_to "Forgot your password?", new_password_path(resource_name)
|
||||||
|
%br
|
||||||
|
|
||||||
|
- if devise_mapping.confirmable? && controller_name != 'confirmations'
|
||||||
|
= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name)
|
||||||
|
%br
|
||||||
|
|
||||||
|
- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks'
|
||||||
|
= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name)
|
||||||
|
%br
|
||||||
4
app/views/devise/shared/_openid.html.haml
Normal file
4
app/views/devise/shared/_openid.html.haml
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
- if devise_mapping.omniauthable?
|
||||||
|
- resource_class.omniauth_providers.each do |provider|
|
||||||
|
= link_to image_tag("#{provider}.png", size: '32x32') + provider , omniauth_authorize_path(resource_name, provider)
|
||||||
|
%br
|
||||||
|
|
@ -51,5 +51,6 @@
|
||||||
%button.btn.btn-block Sign in
|
%button.btn.btn-block Sign in
|
||||||
%br
|
%br
|
||||||
= link_to "Forgot your password?", new_password_path('user')
|
= link_to "Forgot your password?", new_password_path('user')
|
||||||
|
= link_to 'Sign in with openID', new_user_session_path
|
||||||
%li.hidden-lg
|
%li.hidden-lg
|
||||||
= link_to('Sign In', new_user_session_path)
|
= link_to('Sign In', new_user_session_path)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,21 @@
|
||||||
# Use this hook to configure devise mailer, warden hooks and so forth.
|
# Use this hook to configure devise mailer, warden hooks and so forth.
|
||||||
# Many of these configuration options can be set straight in your model.
|
# Many of these configuration options can be set straight in your model.
|
||||||
|
|
||||||
Devise.setup do |config|
|
Devise.setup do |config|
|
||||||
# ==> Secret key, generate one with `rake secret`
|
# ==> Secret key, generate one with `rake secret`
|
||||||
config.secret_key = Rails.application.secrets.devise_secret_key
|
config.secret_key = Rails.application.secrets.devise_secret_key
|
||||||
|
|
||||||
|
# ==> openIDs configuration
|
||||||
|
# Define the available openID providers that can be used to log in
|
||||||
|
# Pass each provider to User model in :omniauth_providers (for open_id providers use their name)
|
||||||
|
# Include provider in users/omniauth_callbacks_controller.rb
|
||||||
|
|
||||||
|
config.omniauth :open_id, name: 'novell', identifier: 'http://www.opensuse.org/openid/user'
|
||||||
|
config.omniauth :google_oauth2, Rails.application.secrets.google_key, Rails.application.secrets.google_secret, {
|
||||||
|
name: 'google',
|
||||||
|
scope: 'email' }
|
||||||
|
config.omniauth :facebook, Rails.application.secrets.facebook_key, Rails.application.secrets.facebook_secret
|
||||||
|
|
||||||
# ==> Mailer Configuration
|
# ==> Mailer Configuration
|
||||||
# Configure the e-mail address which will be shown in Devise::Mailer,
|
# Configure the e-mail address which will be shown in Devise::Mailer,
|
||||||
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
|
# note that it will be overwritten if you use your own mailer class with default "from" parameter.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ Osem::Application.routes.draw do
|
||||||
|
|
||||||
get 'conference/show'
|
get 'conference/show'
|
||||||
|
|
||||||
devise_for :users, controllers: { registrations: :registrations }, path: 'accounts'
|
devise_for :users, controllers: { registrations: :registrations,
|
||||||
|
omniauth_callbacks: 'users/omniauth_callbacks' },
|
||||||
|
path: 'accounts'
|
||||||
|
|
||||||
namespace :admin do
|
namespace :admin do
|
||||||
resources :users
|
resources :users
|
||||||
|
|
|
||||||
12
db/migrate/20140603092041_create_openids.rb
Normal file
12
db/migrate/20140603092041_create_openids.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
class CreateOpenids < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :openids do |t|
|
||||||
|
t.string :provider
|
||||||
|
t.string :email
|
||||||
|
t.string :uid
|
||||||
|
t.integer :user_id
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
15
db/schema.rb
15
db/schema.rb
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20140617145048) do
|
ActiveRecord::Schema.define(version: 20140618062623) do
|
||||||
|
|
||||||
create_table "answers", force: true do |t|
|
create_table "answers", force: true do |t|
|
||||||
t.string "title"
|
t.string "title"
|
||||||
|
|
@ -82,11 +82,11 @@ ActiveRecord::Schema.define(version: 20140617145048) do
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.text "registration_description"
|
t.text "registration_description"
|
||||||
t.text "ticket_description"
|
t.text "ticket_description"
|
||||||
|
t.text "sponsor_description"
|
||||||
|
t.string "sponsor_email"
|
||||||
t.string "twitter_url"
|
t.string "twitter_url"
|
||||||
t.string "facebook_url"
|
t.string "facebook_url"
|
||||||
t.string "google_url"
|
t.string "google_url"
|
||||||
t.text "sponsor_description"
|
|
||||||
t.string "sponsor_email"
|
|
||||||
t.text "lodging_description"
|
t.text "lodging_description"
|
||||||
t.boolean "include_registrations_in_splash", default: false
|
t.boolean "include_registrations_in_splash", default: false
|
||||||
t.boolean "include_sponsors_in_splash", default: false
|
t.boolean "include_sponsors_in_splash", default: false
|
||||||
|
|
@ -213,6 +213,15 @@ ActiveRecord::Schema.define(version: 20140617145048) do
|
||||||
t.string "website_link"
|
t.string "website_link"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "openids", force: true do |t|
|
||||||
|
t.string "provider"
|
||||||
|
t.string "email"
|
||||||
|
t.string "uid"
|
||||||
|
t.integer "user_id"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "people", force: true do |t|
|
create_table "people", force: true do |t|
|
||||||
t.string "guid", null: false
|
t.string "guid", null: false
|
||||||
t.string "first_name", default: ""
|
t.string "first_name", default: ""
|
||||||
|
|
|
||||||
108
spec/features/omniauth_spec.rb
Normal file
108
spec/features/omniauth_spec.rb
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature Openid do
|
||||||
|
let!(:participant_role) { create(:participant_role) }
|
||||||
|
let!(:admin_role) { create(:admin_role) }
|
||||||
|
|
||||||
|
describe 'sign in with openid' do
|
||||||
|
|
||||||
|
it 'has option to log in with Google account' do
|
||||||
|
visit '/accounts/sign_in'
|
||||||
|
expect(page.has_content?('Or use your openID')).to be true
|
||||||
|
expect(page.has_content?('google')).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'signs in *new* user with Google account' do
|
||||||
|
expected_count_openid = Openid.count + 1
|
||||||
|
expected_count_user = User.count + 1
|
||||||
|
visit '/accounts/sign_in'
|
||||||
|
|
||||||
|
mock_auth_new_user
|
||||||
|
click_link 'google'
|
||||||
|
expect(flash).to eq('test-1@gmail.com signed in successfully with google')
|
||||||
|
expect(Openid.count).to eq(expected_count_openid)
|
||||||
|
expect(User.count).to eq(expected_count_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'signs in an existing user' do
|
||||||
|
create(:participant, email: 'test-participant-1@google.com')
|
||||||
|
expected_count_openid = Openid.count + 1
|
||||||
|
expected_count_user = User.count
|
||||||
|
visit '/accounts/sign_in'
|
||||||
|
|
||||||
|
mock_auth_existing_user_participant
|
||||||
|
click_link 'google'
|
||||||
|
expect(flash).to eq('test-participant-1@google.com signed in successfully with google')
|
||||||
|
expect(Openid.count).to eq(expected_count_openid)
|
||||||
|
expect(User.count).to eq(expected_count_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can handle authentication error' do
|
||||||
|
OmniAuth.config.mock_auth[:google] = :invalid_credentials
|
||||||
|
visit '/accounts/sign_in'
|
||||||
|
expect(page.has_content?('Or use your openID')).to be true
|
||||||
|
click_link 'google'
|
||||||
|
expect(flash).to eq("Could not authenticate you from Google because \"Invalid credentials\".")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'adds openid to existing user' do
|
||||||
|
# Sign in user
|
||||||
|
user = create(:participant, email: 'test-participant-1@google.com')
|
||||||
|
sign_in user
|
||||||
|
|
||||||
|
# Add openID to current user
|
||||||
|
expected_count_openid = Openid.count + 1
|
||||||
|
expected_count_user = User.count
|
||||||
|
visit '/accounts/edit'
|
||||||
|
|
||||||
|
mock_auth_new_user
|
||||||
|
click_link 'google'
|
||||||
|
expect(flash).to eq('test-participant-1@google.com signed in successfully with google')
|
||||||
|
expect(Openid.count).to eq(expected_count_openid)
|
||||||
|
expect(User.count).to eq(expected_count_user)
|
||||||
|
expect(Openid.where(email: 'test-1@gmail.com').first.nil?).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'signs in with openID using the same email as another associated openid' do
|
||||||
|
# Sign in user
|
||||||
|
create(:participant, email: 'test-participant-1@google.com')
|
||||||
|
expected_count_openid = Openid.count + 1
|
||||||
|
expected_count_user = User.count
|
||||||
|
visit '/accounts/sign_in'
|
||||||
|
|
||||||
|
mock_auth_existing_user_participant
|
||||||
|
click_link 'google'
|
||||||
|
expect(flash).to eq('test-participant-1@google.com signed in successfully with google')
|
||||||
|
expect(Openid.count).to eq(expected_count_openid)
|
||||||
|
expect(User.count).to eq(expected_count_user)
|
||||||
|
|
||||||
|
# Add openID to current user with email test-1@gmail.com
|
||||||
|
expected_count_openid = Openid.count + 1
|
||||||
|
expected_count_user = User.count
|
||||||
|
visit '/accounts/edit'
|
||||||
|
|
||||||
|
mock_auth_new_user
|
||||||
|
click_link 'google'
|
||||||
|
expect(flash).to eq('test-participant-1@google.com signed in successfully with google')
|
||||||
|
expect(Openid.count).to eq(expected_count_openid)
|
||||||
|
expect(User.count).to eq(expected_count_user)
|
||||||
|
expect(Openid.where(email: 'test-participant-1@google.com').first.nil?).to eq(false)
|
||||||
|
expect(Openid.where(email: 'test-1@gmail.com').first.nil?).to eq(false)
|
||||||
|
|
||||||
|
# Sign in with different openID using same email (test-1@gmail.com)
|
||||||
|
sign_out
|
||||||
|
expected_count_openid = Openid.count + 1
|
||||||
|
expected_count_user = User.count
|
||||||
|
|
||||||
|
visit '/accounts/sign_in'
|
||||||
|
mock_auth_new_user_fb
|
||||||
|
click_link 'facebook'
|
||||||
|
expect(flash).to eq('test-participant-1@google.com signed in successfully with facebook')
|
||||||
|
expect(Openid.count).to eq(expected_count_openid)
|
||||||
|
expect(User.count).to eq(expected_count_user)
|
||||||
|
last_openid = Openid.last
|
||||||
|
expect(last_openid.uid).to eq('facebook-test-uid-1')
|
||||||
|
expect(last_openid.email).to eq('test-1@gmail.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -53,6 +53,9 @@ RSpec.configure do |config|
|
||||||
# Includes support/login_macros for feature tests
|
# Includes support/login_macros for feature tests
|
||||||
config.include LoginMacros, type: :feature
|
config.include LoginMacros, type: :feature
|
||||||
|
|
||||||
|
# Includes omniauth macro
|
||||||
|
config.include(OmniauthMacros)
|
||||||
|
|
||||||
# Includes support/flash for feature tests
|
# Includes support/flash for feature tests
|
||||||
config.include Flash, type: :feature
|
config.include Flash, type: :feature
|
||||||
|
|
||||||
|
|
@ -63,3 +66,5 @@ RSpec.configure do |config|
|
||||||
c.syntax = :expect
|
c.syntax = :expect
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
OmniAuth.config.test_mode = true
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ module LoginMacros
|
||||||
|
|
||||||
fill_in 'user_email', with: user.email
|
fill_in 'user_email', with: user.email
|
||||||
fill_in 'user_password', with: user.password
|
fill_in 'user_password', with: user.password
|
||||||
find(:xpath, "//div[@id='content']//input[@name='commit']").click
|
find(:xpath, "//div[@id='content']//button[@type='submit']").click
|
||||||
|
|
||||||
expect(page.has_content?('Signed in successfully')).to be true
|
expect(page.has_content?('Signed in successfully')).to be true
|
||||||
end
|
end
|
||||||
|
|
|
||||||
68
spec/support/omniauth_macros.rb
Normal file
68
spec/support/omniauth_macros.rb
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
module OmniauthMacros
|
||||||
|
# The mock_auth configuration allows you to set per-provider (or default)
|
||||||
|
# authentication hashes to return during integration testing.
|
||||||
|
|
||||||
|
def mock_auth_new_user
|
||||||
|
OmniAuth.config.mock_auth[:google] =
|
||||||
|
OmniAuth::AuthHash.new(
|
||||||
|
provider: 'google',
|
||||||
|
uid: 'google-test-uid-1',
|
||||||
|
info: {
|
||||||
|
email: 'test-1@gmail.com'
|
||||||
|
},
|
||||||
|
credentials: {
|
||||||
|
token: 'mock_token',
|
||||||
|
secret: 'mock_secret'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mock_auth_new_user_fb
|
||||||
|
OmniAuth.config.mock_auth[:facebook] =
|
||||||
|
OmniAuth::AuthHash.new(
|
||||||
|
provider: 'google',
|
||||||
|
uid: 'facebook-test-uid-1',
|
||||||
|
info: {
|
||||||
|
email: 'test-1@gmail.com'
|
||||||
|
},
|
||||||
|
credentials: {
|
||||||
|
token: 'mock_token',
|
||||||
|
secret: 'mock_secret'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mock_auth_existing_user_participant
|
||||||
|
# The mock_auth configuration allows you to set per-provider (or default)
|
||||||
|
# authentication hashes to return during integration testing.
|
||||||
|
OmniAuth.config.mock_auth[:google] =
|
||||||
|
OmniAuth::AuthHash.new(
|
||||||
|
provider: 'google',
|
||||||
|
uid: 'google-test-uid-participant-1',
|
||||||
|
info: {
|
||||||
|
email: 'test-participant-1@google.com'
|
||||||
|
},
|
||||||
|
credentials: {
|
||||||
|
token: 'mock_token',
|
||||||
|
secret: 'mock_secret'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def mock_auth_existing_user_admin
|
||||||
|
# The mock_auth configuration allows you to set per-provider (or default)
|
||||||
|
# authentication hashes to return during integration testing.
|
||||||
|
OmniAuth.config.mock_auth[:google] =
|
||||||
|
OmniAuth::AuthHash.new(
|
||||||
|
provider: 'google',
|
||||||
|
uid: 'google-test-uid-admin-1',
|
||||||
|
info: {
|
||||||
|
email: 'test-admin-1@google.com'
|
||||||
|
},
|
||||||
|
credentials: {
|
||||||
|
token: 'mock_token',
|
||||||
|
secret: 'mock_secret'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Add table
Add a link
Reference in a new issue