Browse Source

Add Facebook login with Sorcery

The facebook key and secret defined in the sorcery config file are for
testing only and need to be changed and not committed to source when
app is ready to go live
development
Graham Kaplan 11 years ago
parent
commit
230295790b
  1. 3
      app/assets/javascripts/oauths.js.coffee
  2. 3
      app/assets/stylesheets/oauths.css.scss
  3. 32
      app/controllers/oauths_controller.rb
  4. 2
      app/helpers/oauths_helper.rb
  5. 3
      app/models/authentication.rb
  6. 6
      app/models/user.rb
  7. 2
      app/views/oauths/callback.html.haml
  8. 2
      app/views/oauths/oauth.html.haml
  9. 2
      app/views/user_sessions/new.html.haml
  10. 23
      config/initializers/sorcery.rb
  11. 4
      config/routes.rb
  12. 3
      spec/spec_helper.rb
  13. 8
      spec/support/authentication.rb
  14. 14
      test/controllers/oauths_controller_test.rb
  15. 6
      test/factories/authentications.rb
  16. 4
      test/helpers/oauths_helper_test.rb
  17. 7
      test/models/authentication_test.rb

3
app/assets/javascripts/oauths.js.coffee

@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/

3
app/assets/stylesheets/oauths.css.scss

@ -0,0 +1,3 @@
// Place all the styles related to the Oauths controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

32
app/controllers/oauths_controller.rb

@ -0,0 +1,32 @@
class OauthsController < ApplicationController
skip_before_filter :require_login
# sends the user on a trip to the provider,
# and after authorizing there back to the callback url.
def oauth
login_at(auth_params[:provider])
end
def callback
provider = auth_params[:provider]
if @user = login_from(provider)
redirect_to root_path, :notice => "Logged in with #{provider.titleize}!"
else
begin
@user = create_from(auth_params[:provider])
reset_session
auto_login(@user)
redirect_to root_path, :notice => "Signed up with #{provider.titleize}!"
rescue
redirect_to root_path, :alert => "Failed to login with #{provider.titleize}!"
end
end
end
private
def auth_params
params.permit(:code, :provider)
end
end

2
app/helpers/oauths_helper.rb

@ -0,0 +1,2 @@
module OauthsHelper
end

3
app/models/authentication.rb

@ -0,0 +1,3 @@
class Authentication < ActiveRecord::Base
belongs_to :user
end

6
app/models/user.rb

@ -1,5 +1,7 @@
class User < ActiveRecord::Base class User < ActiveRecord::Base
authenticates_with_sorcery! authenticates_with_sorcery! do |config|
config.authentications_class = Authentication
end
validates :password, presence: true, confirmation: true, length: { minimum: 3 }, unless: ("id?" || "password_confirmation?") validates :password, presence: true, confirmation: true, length: { minimum: 3 }, unless: ("id?" || "password_confirmation?")
validates :password_confirmation, presence: true, unless: ("id?" || "password?") validates :password_confirmation, presence: true, unless: ("id?" || "password?")
@ -16,5 +18,7 @@ class User < ActiveRecord::Base
has_many :user_organization_relationships has_many :user_organization_relationships
has_many :organizations, through: :user_organization_relationships has_many :organizations, through: :user_organization_relationships
has_many :authentications, :dependent => :destroy
accepts_nested_attributes_for :authentications
end end

2
app/views/oauths/callback.html.haml

@ -0,0 +1,2 @@
%h1 Oauths#callback
%p Find me in app/views/oauths/callback.html.haml

2
app/views/oauths/oauth.html.haml

@ -0,0 +1,2 @@
%h1 Oauths#oauth
%p Find me in app/views/oauths/oauth.html.haml

2
app/views/user_sessions/new.html.haml

@ -8,4 +8,6 @@
Create an Account Create an Account
%p %p
#{_ 'user.why_register', 'paragraph'} #{_ 'user.why_register', 'paragraph'}
= link_to 'Login with Facebook', auth_at_provider_path(:provider => :facebook)
= render '/users/form' = render '/users/form'

23
config/initializers/sorcery.rb

@ -71,7 +71,7 @@ Rails.application.config.sorcery.configure do |config|
# What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid] . # What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid] .
# Default: `[]` # Default: `[]`
# #
# config.external_providers = config.external_providers = [:facebook]
# You can change it by your local ca_file. i.e. '/etc/pki/tls/certs/ca-bundle.crt' # You can change it by your local ca_file. i.e. '/etc/pki/tls/certs/ca-bundle.crt'
@ -109,13 +109,14 @@ Rails.application.config.sorcery.configure do |config|
# config.twitter.secret = "" # config.twitter.secret = ""
# config.twitter.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=twitter" # config.twitter.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=twitter"
# config.twitter.user_info_mapping = {:email => "screen_name"} # config.twitter.user_info_mapping = {:email => "screen_name"}
#
# config.facebook.key = "" config.facebook.key = "726202304080642"
# config.facebook.secret = "" config.facebook.secret = "386a7b717d348af4120aeb1bb0ca3516"
# config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook" config.facebook.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=facebook"
# config.facebook.user_info_mapping = {:email => "name"} config.facebook.user_info_mapping = {:email => "email", :username => "username", :avatar => "picture/data/url"}
# config.facebook.access_permissions = ["email", "publish_stream"] config.facebook.scope = "email"
# config.facebook.display = "popup"
# config.github.key = "" # config.github.key = ""
# config.github.secret = "" # config.github.secret = ""
# config.github.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=github" # config.github.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=github"
@ -147,7 +148,7 @@ Rails.application.config.sorcery.configure do |config|
# specify username attributes, for example: [:username, :email]. # specify username attributes, for example: [:username, :email].
# Default: `[:username]` # Default: `[:username]`
# #
# user.username_attribute_names = user.username_attribute_names = [:username, :email]
# change *virtual* password attribute, the one which is used until an encrypted one is generated. # change *virtual* password attribute, the one which is used until an encrypted one is generated.
@ -214,7 +215,7 @@ Rails.application.config.sorcery.configure do |config|
# make this configuration inheritable for subclasses. Useful for ActiveRecord's STI. # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI.
# Default: `false` # Default: `false`
# #
# user.subclasses_inherit_config = user.subclasses_inherit_config = true
# -- remember_me -- # -- remember_me --
@ -411,7 +412,7 @@ Rails.application.config.sorcery.configure do |config|
# Class which holds the various external provider data for this user. # Class which holds the various external provider data for this user.
# Default: `nil` # Default: `nil`
# #
# user.authentications_class = user.authentications_class = Authentication
# User's identifier in authentications class. # User's identifier in authentications class.

4
config/routes.rb

@ -57,6 +57,10 @@ BikeBike::Application.routes.draw do
post 'logout' => 'user_sessions#destroy', :as => :logout post 'logout' => 'user_sessions#destroy', :as => :logout
get 'register' => 'users#new', :as => 'register' get 'register' => 'users#new', :as => 'register'
post "oauth/callback" => "oauths#callback"
get "oauth/callback" => "oauths#callback"
get "oauth/:provider" => "oauths#oauth", :as => :auth_at_provider
root 'pages#home' root 'pages#home'
end end

3
spec/spec_helper.rb

@ -23,6 +23,8 @@ require 'capybara/rspec'
#Capybara.ignore_hidden_elements = false # testing hidden fields #Capybara.ignore_hidden_elements = false # testing hidden fields
include Sorcery::TestHelpers::Rails
RSpec.configure do |config| RSpec.configure do |config|
# == Mock Framework # == Mock Framework
# #
@ -33,6 +35,7 @@ RSpec.configure do |config|
# config.mock_with :rr # config.mock_with :rr
# config.mock_with :rspec # config.mock_with :rspec
config.include AuthenticationForFeatureRequest, type: :feature
# Run specs in random order to surface order dependencies. If you find an # Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing # order dependency and want to debug it, you can fix the order by providing

8
spec/support/authentication.rb

@ -0,0 +1,8 @@
module AuthenticationForFeatureRequest
def login user, password = 'login'
user.update_attribute :password, password
page.driver.post sessions_url, {email: user.email, password: password}
visit root_url
end
end

14
test/controllers/oauths_controller_test.rb

@ -0,0 +1,14 @@
require 'test_helper'
class OauthsControllerTest < ActionController::TestCase
test "should get oauth" do
get :oauth
assert_response :success
end
test "should get callback" do
get :callback
assert_response :success
end
end

6
test/factories/authentications.rb

@ -0,0 +1,6 @@
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :authentication do
end
end

4
test/helpers/oauths_helper_test.rb

@ -0,0 +1,4 @@
require 'test_helper'
class OauthsHelperTest < ActionView::TestCase
end

7
test/models/authentication_test.rb

@ -0,0 +1,7 @@
require 'test_helper'
class AuthenticationTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end
Loading…
Cancel
Save