diff --git a/Gemfile b/Gemfile
index b5cb28aa4..a49401596 100644
--- a/Gemfile
+++ b/Gemfile
@@ -41,7 +41,9 @@ gem 'lesstile', '~> 1.1.0'
gem 'formtastic'
gem 'will_paginate', '~> 3.0.2'
gem 'exception_notification', '~> 2.5.2'
-gem 'open_id_authentication'
+gem 'omniauth'
+gem 'omniauth-google-oauth2'
+gem 'omniauth-openid'
# Bundle gems for the local environment. Make sure to
# put test-only gems in this group so their generators
diff --git a/Gemfile.lock b/Gemfile.lock
index cd7a1a7b3..f870fb3ee 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -59,15 +59,19 @@ GEM
actionmailer (>= 3.0.4)
factory_girl (4.2.0)
activesupport (>= 3.0.0)
+ faraday (0.9.1)
+ multipart-post (>= 1.2, < 3)
formtastic (2.2.1)
actionpack (>= 3.0)
gherkin (2.12.0)
multi_json (~> 1.3)
+ hashie (3.4.1)
hike (1.2.3)
i18n (0.6.4)
jquery-rails (3.0.4)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
+ jwt (1.4.1)
launchy (2.3.0)
addressable (~> 2.3)
lesstile (1.1.0)
@@ -78,9 +82,29 @@ GEM
minitest (4.7.5)
multi_json (1.7.7)
multi_test (0.0.2)
+ multi_xml (0.5.5)
+ multipart-post (2.0.0)
nokogiri (1.5.10)
- open_id_authentication (1.1.0)
- rack-openid (~> 1.3)
+ oauth2 (1.0.0)
+ faraday (>= 0.8, < 0.10)
+ jwt (~> 1.0)
+ multi_json (~> 1.3)
+ multi_xml (~> 0.5)
+ rack (~> 1.2)
+ omniauth (1.2.2)
+ hashie (>= 1.2, < 4)
+ rack (~> 1.0)
+ omniauth-google-oauth2 (0.2.6)
+ omniauth (> 1.0)
+ omniauth-oauth2 (~> 1.1)
+ omniauth-oauth2 (1.2.0)
+ faraday (>= 0.8, < 0.10)
+ multi_json (~> 1.3)
+ oauth2 (~> 1.0)
+ omniauth (~> 1.2)
+ omniauth-openid (1.0.1)
+ omniauth (~> 1.0)
+ rack-openid (~> 1.3.1)
polyglot (0.3.3)
rack (1.5.2)
rack-openid (1.3.1)
@@ -167,7 +191,9 @@ DEPENDENCIES
jruby-openssl
lesstile (~> 1.1.0)
nokogiri (~> 1.5.0)
- open_id_authentication
+ omniauth
+ omniauth-google-oauth2
+ omniauth-openid
rack-openid
rails (~> 4.0.0)
rspec
diff --git a/app/assets/javascripts/common.js b/app/assets/javascripts/common.js
index 785d014ec..1f7b1037e 100644
--- a/app/assets/javascripts/common.js
+++ b/app/assets/javascripts/common.js
@@ -24,4 +24,5 @@ jQuery.ajaxSetup({
// jQuery extensions
jQuery.prototype.any = function(callback) {
return (this.filter(callback).length > 0)
-}
\ No newline at end of file
+}
+
diff --git a/app/controllers/admin/sessions_controller.rb b/app/controllers/admin/sessions_controller.rb
index ac58701fa..e8b923d1b 100644
--- a/app/controllers/admin/sessions_controller.rb
+++ b/app/controllers/admin/sessions_controller.rb
@@ -1,40 +1,42 @@
class Admin::SessionsController < ApplicationController
skip_before_filter :verify_authenticity_token, :only => :create
- before_filter :verify_authenticity_token_unless_openid, :only => :create
+ before_filter :verify_authenticity_token_unless_using_open_id, :only => :create
layout 'login'
def show
- if using_open_id?
- create
- else
- redirect_to :action => 'new'
- end
+ redirect_to :action => 'new'
end
def new
+ flash.now[:error] = params[:message] if params[:message] # OmniAuth error message.
end
def create
- return successful_login if allow_login_bypass? && params[:bypass_login]
-
- if params[:openid_url].blank? && !request.env[Rack::OpenID::RESPONSE]
- flash.now[:error] = "You must provide an OpenID URL"
- render :action => 'new'
- else
- authenticate_with_open_id(params[:openid_url]) do |result, identity_url|
- if result.successful?
- if enki_config.author_open_ids.include?(URI.parse(identity_url))
- return successful_login
- else
- flash.now[:error] = "You are not authorized"
- end
+ return successful_login if allow_login_bypass? && params[:bypass_login] == '1'
+
+ if request.env['omniauth.auth'].present?
+ case request.env['omniauth.auth'][:provider]
+ when OMNIAUTH_GOOGLE_OAUTH2_STRATEGY
+ if enki_config.author_google_oauth2_email == request.env['omniauth.auth'][:info][:email]
+ save_auth_details(request.env['omniauth.auth'])
+ return successful_login
+ else
+ return show_not_authorized
+ end
+ when OMNIAUTH_OPEN_ID_ADMIN_STRATEGY
+ if enki_config.author_open_ids.include?(URI.parse(request.env['omniauth.auth'][:uid]))
+ save_auth_details(request.env['omniauth.auth'])
+ return successful_login
else
- flash.now[:error] = result.message
+ return show_not_authorized
end
- render :action => 'new'
+ else
+ raise ArgumentError, "The value returned from request.env['omniauth.auth'][:provider] is unknown."
end
end
+
+ show_not_authorized
end
def destroy
@@ -44,6 +46,21 @@ def destroy
protected
+ def show_not_authorized
+ flash.now[:error] = 'You are not authorized'
+ render :action => 'new'
+ end
+
+ def save_auth_details(auth_response)
+ OmniAuthDetails.create(
+ :provider => auth_response[:provider],
+ :uid => auth_response[:uid],
+ :info => auth_response[:info],
+ :credentials => auth_response[:credentials],
+ :extra => auth_response[:extra]
+ )
+ end
+
def successful_login
session[:logged_in] = true
redirect_to(admin_root_path)
@@ -53,9 +70,20 @@ def allow_login_bypass?
%w(development test).include?(Rails.env)
end
- def verify_authenticity_token_unless_openid
+ def verify_authenticity_token_unless_using_open_id
verify_authenticity_token unless using_open_id?
end
+ def using_open_id?
+ if request.env['omniauth.auth'].present?
+ if request.env['omniauth.auth'][:provider] == OMNIAUTH_GOOGLE_OAUTH2_STRATEGY ||
+ request.env['omniauth.auth'][:provider] == OMNIAUTH_OPEN_ID_ADMIN_STRATEGY
+ return true
+ end
+ end
+
+ return false
+ end
+
helper_method :allow_login_bypass?
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 150bcfbbc..168ddd9a9 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -1,10 +1,27 @@
class ApplicationController < ActionController::Base
protect_from_forgery
+ OMNIAUTH_GOOGLE_OAUTH2_STRATEGY = 'google_oauth2'
+ OMNIAUTH_OPEN_ID_ADMIN_STRATEGY = 'open_id_admin'
+ OMNIAUTH_OPEN_ID_COMMENT_STRATEGY = 'open_id_comment'
+
protected
def enki_config
@@enki_config = Enki::Config.default
end
+
+ # Used for OmniAuth routing.
+ def auth_path(provider, query_string_params = '')
+ path = "/auth/#{provider.to_s}"
+
+ if !query_string_params.blank?
+ return path + "?#{query_string_params}"
+ end
+
+ path
+ end
+
helper_method :enki_config
+ helper_method :auth_path
end
diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb
index 7638ae2ad..c0ffeea0f 100644
--- a/app/controllers/comments_controller.rb
+++ b/app/controllers/comments_controller.rb
@@ -1,12 +1,8 @@
class CommentsController < ApplicationController
skip_before_filter :verify_authenticity_token, :only => :create
- before_filter :verify_authenticity_token_unless_openid, :only => :create
+ before_filter :verify_authenticity_token_unless_using_openid, :only => :create
include UrlHelper
- OPEN_ID_ERRORS = {
- :missing => "Sorry, the OpenID server couldn't be found",
- :canceled => "OpenID verification was canceled",
- :failed => "Sorry, the OpenID verification failed" }
before_filter :find_post, :except => [:new]
@@ -26,53 +22,44 @@ def new
# TODO: Spec OpenID with cucumber and rack-my-id
def create
- @comment = Comment.new((session[:pending_comment] || comment_params || {}).
- reject {|key, value| !Comment.protected_attribute?(key) })
+ @comment = Comment.new((session[:pending_comment] || comment_params || {}).
+ reject { |key, value| !Comment.protected_attribute?(key) })
+
@comment.post = @post
- session[:pending_comment] = nil
-
- if @comment.requires_openid_authentication?
- session[:pending_comment] = comment_params
- authenticate_with_open_id(@comment.author,
- :optional => [:nickname, :fullname, :email]
- ) do |result, identity_url, registration|
- if result.status == :successful
- @comment.post = @post
-
- @comment.author_url = @comment.author
- @comment.author = (
- registration["fullname"] ||
- registration["nickname"] ||
- @comment.author_url
- ).to_s
- @comment.author_email = (
- registration["email"] ||
- @comment.author_url
- ).to_s
-
- @comment.openid_error = ""
- session[:pending_comment] = nil
- else
- @comment.openid_error = OPEN_ID_ERRORS[ result.status ]
- end
- end
- else
+ if !@comment.requires_openid_authentication?
@comment.blank_openid_fields
- end
-
- # #authenticate_with_open_id may have already provided a response
- unless response.headers[Rack::OpenID::AUTHENTICATE_HEADER]
- if @comment.save
- redirect_to post_path(@post)
- else
- render :template => 'posts/show'
+ save_comment_or_show_error
+ else
+ if request.env['omniauth.auth'].nil? && params[:message].blank? # Begin auth.
+ session[:pending_comment] = comment_params
+ session[:post_id] = @post.id
+ redirect_to auth_path(:open_id_comment, "openid_url=#{@comment.author}")
+ elsif !request.env['omniauth.auth'].nil? # Process success response.
+ @comment.author_url = request.env['omniauth.auth'][:uid]
+ @comment.author = request.env['omniauth.auth'][:info][:name]
+ @comment.author_email = request.env['omniauth.auth'][:info][:email] || ''
+ @comment.openid_error = ''
+ save_comment_or_show_error
+ else # Process error response.
+ @comment.openid_error = params[:message]
+ save_comment_or_show_error
end
end
end
private
+ def save_comment_or_show_error
+ if @comment.save
+ session[:pending_comment] = nil
+ session[:post_id] = nil
+ redirect_to post_path(@post)
+ else
+ render :template => 'posts/show'
+ end
+ end
+
def comment_params
params.require(:comment).permit(:author, :body)
end
@@ -83,9 +70,21 @@ def find_post
@post = Post.find_by_permalink(*[:year, :month, :day, :slug].map {|x|
params[x]
})
+
+ rescue ActiveRecord::RecordNotFound
+ @post = Post.find(session[:post_id])
end
- def verify_authenticity_token_unless_openid
+ def verify_authenticity_token_unless_using_openid
verify_authenticity_token unless using_open_id?
end
+
+ def using_open_id?
+ if !request.env['omniauth.auth'].nil? &&
+ request.env['omniauth.auth'][:provider] == OMNIAUTH_OPEN_ID_COMMENT_STRATEGY
+ return true
+ end
+
+ return false
+ end
end
diff --git a/app/models/omni_auth_details.rb b/app/models/omni_auth_details.rb
new file mode 100644
index 000000000..edd599f87
--- /dev/null
+++ b/app/models/omni_auth_details.rb
@@ -0,0 +1,5 @@
+class OmniAuthDetails < ActiveRecord::Base
+ serialize :info, Hash
+ serialize :credentials, Hash
+ serialize :extra, Hash
+end
diff --git a/app/views/admin/sessions/new.html.erb b/app/views/admin/sessions/new.html.erb
index 192889a3e..cf3dac98a 100644
--- a/app/views/admin/sessions/new.html.erb
+++ b/app/views/admin/sessions/new.html.erb
@@ -1,10 +1,16 @@
<%= link_to(enki_config[:title], '/') %>
<% if flash[:error] %>
<%= flash[:error] %>
<% end %>
-<%= form_tag(admin_session_path) do -%>
-
Stop! Who are you?
-
<%= text_field_tag 'openid_url' %>
- <% if allow_login_bypass? -%>
-
<%= check_box_tag 'bypass_login' %>
- <% end -%>
-
<%= submit_tag("Login with OpenID") %>
+
Stop! Who are you?
+<% if allow_login_bypass? -%>
+ <%= form_tag(admin_session_path) do -%>
+ <%= hidden_field_tag 'bypass_login', '1' -%>
+
<%= submit_tag('Bypass credentials check') %>
+ <%- end %>
+<%- end %>
+<%= form_tag(auth_path(:google_oauth2)) do -%>
+
<%= submit_tag('Login with Google OpenID Connect') %>
+<% end -%>
+<%= form_tag(auth_path(:open_id_admin)) do -%>
+
<%= text_field_tag 'openid_url', nil, placeholder: 'Enter your OpenID URL' %>
+
<%= submit_tag('Login with OpenID') %>
<% end -%>
diff --git a/app/views/layouts/login.html.erb b/app/views/layouts/login.html.erb
index 6f8e07e27..d806dd573 100644
--- a/app/views/layouts/login.html.erb
+++ b/app/views/layouts/login.html.erb
@@ -4,6 +4,16 @@
<%= enki_config[:title] %> - Admin Login
<%= stylesheet_link_tag 'login' %>
+ <%= javascript_tag do -%>
+ // Why is this code here? After a failed OpenID login, second and subsequent tries will cause Rails to throw an
+ // ActionDispatch::Cookies::CookieOverflow exception when hitting the /auth/open_id_admin path (this path is
+ // dynamically set by OmniAuth) due to the large amount of stuff passed in from the query string. So let's
+ // automagically say goodbye to the query string, no one needs it here anyway.
+ // to the query string.
+ if (window.location.href.indexOf('/auth/open_id_admin/callback?') > -1) {
+ window.history.pushState(null, 'Look ma! No query string!', '/auth/open_id_admin/callback');
+ }
+ <% end -%>
diff --git a/config/.gitignore b/config/.gitignore
index a13db8249..4f61f48c4 100644
--- a/config/.gitignore
+++ b/config/.gitignore
@@ -1,2 +1,3 @@
database.yml
defensio.yml
+google_oauth2.yml
diff --git a/config/application.rb b/config/application.rb
index 7aea381a9..beb545878 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -6,6 +6,19 @@
Bundler.require(:default, Rails.env)
end
+# Make google_oauth2.yml values available as ENV values (used with the google_oauth2 OmniAuth strategy).
+# If deploying to Heroku, you will need to set the two required ENV values manually for Heroku, for example:
+# heroku config:set GOOGLE_CLIENT_ID=my_client_id
+# heroku config:set GOOGLE_CLIENT_SECRET=my_client_secret
+if File.exists?(File.expand_path('../google_oauth2.yml', __FILE__))
+ config = YAML.load(File.read(File.expand_path('../google_oauth2.yml', __FILE__)))
+ config.merge! config.fetch(Rails.env, {})
+
+ config.each do |key, value|
+ ENV[key] ||= value.to_s unless value.kind_of? Hash
+ end
+end
+
# This configures the base path of routes for the main application.
# For example, set to '/blog' to run at http://example.com/blog
# It must appear before the Application class body. Initializers run too late.
diff --git a/config/enki.yml b/config/enki.yml
index cbd1f3ae6..12f42c31c 100644
--- a/config/enki.yml
+++ b/config/enki.yml
@@ -3,14 +3,22 @@
title: My Enki Blog
url: http://enkiblog.com
author:
- name: Don Alias # For copyright notice and ATOM feeds
- email: don@enkiblog.com # Exception emails will go here, and it is used in ATOM feeds
- open_id: # These are used to login to the admin area
+ name: Don Alias # For copyright notice and ATOM feeds
+ email: don@enkiblog.com # Exception emails will go here, and it is used in ATOM feeds
+
+ # If you want to use the google_oauth2 (Google OpenID Connect) OmniAuth strategy to login to the admin area,
+ # google_oauth2_email should match the email of your OpenID Connect identity
+ google_oauth2_email: "you@your-openid-connect-domain.com"
+
+ # If you want to use OpenID (which is distinct from OpenID Connect) to login to the admin area, open_id should contain
+ # your OpenID URL(s)
+ open_id:
- http://enkiblog.com
- http://secondaryopenid.com
# Delete the following section if your site will not be acting as an OpenID delegate (http://wiki.openid.net/Delegation)
# If you're deploying with mongrel, make sure you read http://rhnh.net/2008/04/13/nginx-openid-delegation-and-yadis
+# Note that OpenID Connect does not support delegation
open_id_delegation:
server: http://www.myopenid.com/server
delegate: http://username.myopenid.com
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
new file mode 100644
index 000000000..c70339434
--- /dev/null
+++ b/config/initializers/omniauth.rb
@@ -0,0 +1,17 @@
+require 'omniauth-openid'
+require 'openid/store/filesystem'
+
+OmniAuth.config.logger = Rails.logger
+
+# Uncomment this if you want OmniAuth error responses to work as in production.
+#OmniAuth.config.on_failure = Proc.new { |env|
+# OmniAuth::FailureEndpoint.new(env).redirect_to_failure
+#}
+
+Rails.application.config.middleware.use OmniAuth::Builder do
+ provider :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET'], {
+ :scope => 'openid,email'
+ }
+ provider :open_id, :name => 'open_id_admin', :store => OpenID::Store::Filesystem.new('/tmp')
+ provider :open_id, :name => 'open_id_comment', :store => OpenID::Store::Filesystem.new('/tmp')
+end
diff --git a/config/routes.rb b/config/routes.rb
index 4293446eb..7738b3d0d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -30,5 +30,16 @@
get '(:tag)', :as => :posts, :tag => /(?:[A-Za-z0-9_ \.-]|%20)+?/, :format => /html|atom/
end
+ # OmniAuth routes.
+ post '/auth/open_id_comment/callback', :to => 'comments#create'
+ match '/auth/failure' => 'comments#create',
+ :constraints => lambda { |request|
+ request.query_parameters[:strategy] == ApplicationController::OMNIAUTH_OPEN_ID_COMMENT_STRATEGY
+ }, :via => [:get]
+ post '/auth/open_id_admin/callback', :to => 'admin/sessions#create'
+ match '/auth/:provider/callback', :to => 'admin/sessions#create', :via => [:get, :post]
+ get '/auth/failure/comments/new', :to => 'comments#new'
+ get '/auth/failure', :to => 'admin/sessions#new'
+
root :to => 'posts#index'
end
diff --git a/db/migrate/20150412102635_create_omni_auth_details.rb b/db/migrate/20150412102635_create_omni_auth_details.rb
new file mode 100644
index 000000000..d84e68890
--- /dev/null
+++ b/db/migrate/20150412102635_create_omni_auth_details.rb
@@ -0,0 +1,13 @@
+class CreateOmniAuthDetails < ActiveRecord::Migration
+ def change
+ create_table :omni_auth_details do |t|
+ t.string :provider, :null => false
+ t.string :uid, :null => false
+ t.text :info, :null => false
+ t.text :credentials
+ t.text :extra
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20150414113518_drop_open_id_authentication_tables.rb b/db/migrate/20150414113518_drop_open_id_authentication_tables.rb
new file mode 100644
index 000000000..55ce5a5cb
--- /dev/null
+++ b/db/migrate/20150414113518_drop_open_id_authentication_tables.rb
@@ -0,0 +1,15 @@
+class DropOpenIdAuthenticationTables < ActiveRecord::Migration
+ def up
+ if ActiveRecord::Base.connection.table_exists? 'open_id_authentication_associations'
+ drop_table 'open_id_authentication_associations'
+ end
+
+ if ActiveRecord::Base.connection.table_exists? 'open_id_authentication_nonces'
+ drop_table 'open_id_authentication_nonces'
+ end
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 272b7a678..b21724153 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20110709024316) do
+ActiveRecord::Schema.define(version: 20150414113518) do
create_table "comments", force: true do |t|
t.integer "post_id", null: false
@@ -27,19 +27,14 @@
add_index "comments", ["created_at"], name: "index_comments_on_created_at"
add_index "comments", ["post_id"], name: "index_comments_on_post_id"
- create_table "open_id_authentication_associations", force: true do |t|
- t.integer "issued"
- t.integer "lifetime"
- t.string "handle"
- t.string "assoc_type"
- t.binary "server_url"
- t.binary "secret"
- end
-
- create_table "open_id_authentication_nonces", force: true do |t|
- t.integer "timestamp", null: false
- t.string "server_url"
- t.string "salt", null: false
+ create_table "omni_auth_details", force: true do |t|
+ t.string "provider"
+ t.string "uid"
+ t.text "info"
+ t.text "credentials"
+ t.text "extra"
+ t.datetime "created_at"
+ t.datetime "updated_at"
end
create_table "pages", force: true do |t|
diff --git a/lib/enki/config.rb b/lib/enki/config.rb
index 826131527..4e160483a 100644
--- a/lib/enki/config.rb
+++ b/lib/enki/config.rb
@@ -16,6 +16,10 @@ def author_open_ids
[self[:author, :open_id]].flatten.map {|uri| URI.parse(uri)}
end
+ def author_google_oauth2_email
+ [self[:author, :google_oauth2_email]]
+ end
+
def self.default
Enki::Config.new(default_location)
end
diff --git a/spec/controllers/admin/sessions_controller_spec.rb b/spec/controllers/admin/sessions_controller_spec.rb
index df18b5e3b..777597c2b 100644
--- a/spec/controllers/admin/sessions_controller_spec.rb
+++ b/spec/controllers/admin/sessions_controller_spec.rb
@@ -73,73 +73,86 @@
@controller.instance_eval { flash.extend(DisableFlashSweeping) }
end
- def stub_open_id_authenticate(url, status_code, return_value)
- status = double("Result", :successful? => status_code == :successful, :message => '')
+ #def stub_enki_config(url, status_code, return_value)
+ # status = double("Result", :successful? => status_code == :successful, :message => '')
+ # @controller.stub(:enki_config).and_return(double("enki_config", :author_open_ids => [
+ # "http://enkiblog.com",
+ # "http://secondaryopenid.com"
+ # ].collect {|uri| URI.parse(uri)}
+ # ))
+ # @controller.should_receive(:authenticate_with_open_id).with(url).and_yield(status,url).and_return(return_value)
+ #end
+ def stub_auth_response(auth_response)
+ request.env["omniauth.auth"] = auth_response
+ end
+ def stub_enki_config
@controller.stub(:enki_config).and_return(double("enki_config", :author_open_ids => [
"http://enkiblog.com",
"http://secondaryopenid.com"
- ].collect {|uri| URI.parse(uri)}
+ ].collect {|uri| URI.parse(uri)},
+ :author_google_oauth2_email => "you@your-openid-connect-domain.com"
))
- @controller.should_receive(:authenticate_with_open_id).with(url).and_yield(status,url).and_return(return_value)
end
describe "with invalid URL http://evilman.com and OpenID authentication succeeding" do
before do
- stub_open_id_authenticate("http://evilman.com", :successful, false)
- post :create, :openid_url => "http://evilman.com"
+ stub_enki_config
+ stub_auth_response({ :provider => ApplicationController::OMNIAUTH_OPEN_ID_ADMIN_STRATEGY,
+ :uid => "http://evilman.com" })
+
+ post :create
end
it_should_behave_like "not logged in"
end
describe "with valid URL http://enkiblog.com and OpenID authentication succeeding" do
before do
- stub_open_id_authenticate("http://enkiblog.com", :successful, false)
- post :create, :openid_url => "http://enkiblog.com"
+ stub_enki_config
+ stub_auth_response({ :provider => ApplicationController::OMNIAUTH_OPEN_ID_ADMIN_STRATEGY,
+ :uid => "http://enkiblog.com" })
+
+ post :create
end
it_should_behave_like "logged in and redirected to /admin"
end
describe "with valid secondary URL http://secondaryopenid.com and OpenID authentication succeeding" do
before do
- stub_open_id_authenticate("http://secondaryopenid.com", :successful, false)
- post :create, :openid_url => "http://secondaryopenid.com"
+ stub_enki_config
+ stub_auth_response({ :provider => ApplicationController::OMNIAUTH_OPEN_ID_ADMIN_STRATEGY,
+ :uid => "http://secondaryopenid.com" })
+
+ post :create
end
it_should_behave_like "logged in and redirected to /admin"
end
- describe "with valid URL http://enkiblog.com and OpenID authentication returning 'failed'" do
- before do
- stub_open_id_authenticate("http://enkiblog.com", :failed, true)
- post :create, :openid_url => "http://enkiblog.com"
- end
- it_should_behave_like "not logged in"
- end
- describe "with valid URL http://enkiblog.com and OpenID authentication returning 'missing'" do
+ describe "with invalid email notyou@someotherdomain.com and Google OpenID Connect authentication succeeding" do
before do
- stub_open_id_authenticate("http://enkiblog.com", :missing, true)
- post :create, :openid_url => "http://enkiblog.com"
- end
- it_should_behave_like "not logged in"
- end
- describe "with valid URL http://enkiblog.com and OpenID authentication returning 'canceled'" do
- before do
- stub_open_id_authenticate("http://enkiblog.com", :canceled, true)
- post :create, :openid_url => "http://enkiblog.com"
+ stub_enki_config
+ stub_auth_response({ :provider => ApplicationController::OMNIAUTH_GOOGLE_OAUTH2_STRATEGY,
+ :info => { :email => "notyou@someotherdomain.com" } })
+
+ post :create
end
it_should_behave_like "not logged in"
end
- describe "with no URL" do
+ describe "with valid email you@your-openid-connect-domain.com and Google OpenID Connect authentication succeeding" do
before do
- post :create, :openid_url => ""
+ stub_enki_config
+ stub_auth_response({ :provider => ApplicationController::OMNIAUTH_GOOGLE_OAUTH2_STRATEGY,
+ :info => { :email => "you@your-openid-connect-domain.com" } })
+
+ post :create
end
- it_should_behave_like "not logged in"
+ it_should_behave_like "logged in and redirected to /admin"
end
describe "with bypass login selected" do
before do
- post :create, :openid_url => "", :bypass_login => "1"
+ post :create, :bypass_login => "1"
end
it_should_behave_like "logged in and redirected to /admin"
end
describe "with bypass login selected but login bypassing disabled" do
before do
@controller.stub(:allow_login_bypass?).and_return(false)
- post :create, :openid_url => "", :bypass_login => "1"
+ post :create, :bypass_login => "1"
end
it_should_behave_like "not logged in"
end
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
new file mode 100644
index 000000000..c6516c843
--- /dev/null
+++ b/spec/controllers/application_controller_spec.rb
@@ -0,0 +1,13 @@
+require File.dirname(__FILE__) + '/../spec_helper'
+
+describe ApplicationController do
+ describe '#auth_path' do
+ it 'should return the expected path' do
+ subject.send(:auth_path, 'an_omniauth_provider_name').should eq('/auth/an_omniauth_provider_name')
+ end
+ it 'should return the expected path plus query string' do
+ subject.send(:auth_path, 'an_omniauth_provider_name', 'key=value').should
+ eq('/auth/an_omniauth_provider_name?key=value')
+ end
+ end
+end
diff --git a/spec/views/admin/sessions/new.html_spec.rb b/spec/views/admin/sessions/new.html_spec.rb
index 7f9478a12..2c15e2b22 100644
--- a/spec/views/admin/sessions/new.html_spec.rb
+++ b/spec/views/admin/sessions/new.html_spec.rb
@@ -8,6 +8,7 @@
it "renders" do
view.stub(:enki_config).and_return(Enki::Config.default)
view.stub(:allow_login_bypass?).and_return(true)
+ view.stub(:auth_path).and_return('/auth/omniauth_path')
render :template => '/admin/sessions/new', :formats => [:html]
end
end