Skip to content

Instantly share code, notes, and snippets.

@zernel
Created August 24, 2012 01:45
Show Gist options
  • Select an option

  • Save zernel/3444613 to your computer and use it in GitHub Desktop.

Select an option

Save zernel/3444613 to your computer and use it in GitHub Desktop.

Revisions

  1. zernel revised this gist Aug 24, 2012. 2 changed files with 15 additions and 1 deletion.
    2 changes: 1 addition & 1 deletion registrations_controller.rb
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@ def update
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)

    if resource.update_without_password(resource_params)
    if resource.update_without_current_password(resource_params)
    if is_navigational_format?
    flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
    :update_needs_confirmation : :updated
    14 changes: 14 additions & 0 deletions user.rb
    Original file line number Diff line number Diff line change
    @@ -15,4 +15,18 @@ def bind_service(response)
    uid = response["uid"]
    authorizations.create(:provider => provider , :uid => uid )
    end

    def update_without_current_password(params, *options)
    params.delete(:current_password)

    if params[:password].blank?
    params.delete(:password)
    params.delete(:password_confirmation) if params[:password_confirmation].blank?
    end

    result = update_attributes(params, *options)

    clean_up_passwords
    result
    end
    end
  2. zernel revised this gist Aug 24, 2012. 2 changed files with 28 additions and 1 deletion.
    2 changes: 1 addition & 1 deletion omniauth_callbacks.rb
    Original file line number Diff line number Diff line change
    @@ -12,7 +12,7 @@ module OmniauthCallbacks
    user.authorizations << Authorization.new(:provider => provider, :uid => uid )
    user
    else
    user = User.new(email: data["email"], password: Devise.friendly_token[0, 20], username: data['nickname'] || data['name'])
    user = User.new(email: data["email"], username: data['nickname'] || data['name'])

    if user.save(:validate => false)
    user.authorizations << Authorization.new(:provider => provider, :uid => uid )
    27 changes: 27 additions & 0 deletions registrations_controller.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    class Users::RegistrationsController < Devise::RegistrationsController
    def update
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)

    if resource.update_without_password(resource_params)
    if is_navigational_format?
    flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
    :update_needs_confirmation : :updated
    set_flash_message :notice, flash_key
    end
    sign_in resource_name, resource, :bypass => true
    respond_with resource, :location => after_update_path_for(resource)
    else
    clean_up_passwords resource
    respond_with resource
    end
    end

    protected

    def update_needs_confirmation?(resource, previous)
    resource.respond_to?(:pending_reconfirmation?) &&
    resource.pending_reconfirmation? &&
    previous != resource.unconfirmed_email
    end
    end
  3. zernel revised this gist Aug 24, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion devise.rb
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@

    ...

    # Thest oauth key and secret are use for localhost. Please replace them if necessary
    # These oauth key and secret are use for localhost. Please replace them if necessary
    config.omniauth :github, 'a55eb780a5a66bc2fabe', 'b531490bdcc4fcbb3e05bdca2e75e60b8ad9ba12'
    config.omniauth :facebook, "283956394958478", "fdfedf11fba5c4e77e87a748aad36cc9"
    config.omniauth :google_oauth2, '950211539633-6sh58gmv2mc39jn8m6b6uo9i5po6qkjh.apps.googleusercontent.com', 'pvDaViwlfKROcMTxhauo76Gu'
  4. zernel created this gist Aug 24, 2012.
    7 changes: 7 additions & 0 deletions Gemfile
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    gem 'devise'

    gem 'omniauth'
    gem 'omniauth-github'
    gem "omniauth-twitter"
    gem "omniauth-facebook"
    gem "omniauth-google-oauth2"
    11 changes: 11 additions & 0 deletions XXXX_create_authorizations.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    class CreateAuthorizations < ActiveRecord::Migration
    def change
    create_table :authorizations do |t|
    t.string :provider
    t.integer :user_id
    t.string :uid

    t.timestamps
    end
    end
    end
    5 changes: 5 additions & 0 deletions authorization.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    class Authorization < ActiveRecord::Base
    attr_accessible :provider, :uid, :user_id

    belongs_to :user, :inverse_of => :authorizations
    end
    10 changes: 10 additions & 0 deletions devise.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    Devise.setup do |config|

    ...

    # Thest oauth key and secret are use for localhost. Please replace them if necessary
    config.omniauth :github, 'a55eb780a5a66bc2fabe', 'b531490bdcc4fcbb3e05bdca2e75e60b8ad9ba12'
    config.omniauth :facebook, "283956394958478", "fdfedf11fba5c4e77e87a748aad36cc9"
    config.omniauth :google_oauth2, '950211539633-6sh58gmv2mc39jn8m6b6uo9i5po6qkjh.apps.googleusercontent.com', 'pvDaViwlfKROcMTxhauo76Gu'
    #config.omniauth :twitter, "xfOsUPR6WPYzs3EXBbrag", "jxWQdnKr0KnzteXZHbVaE2JtbE6PzuKjOs9PnkeEag"
    end
    28 changes: 28 additions & 0 deletions omniauth_callbacks.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    # encoding: utf-8
    class User
    module OmniauthCallbacks
    ["github","google_oauth2","twitter","facebook"].each do |provider|
    define_method "find_or_create_for_#{provider}" do |response|
    uid = response["uid"]
    data = response["info"]

    if user = Authorization.where("provider" => provider , "uid" => uid).first.try(:user)
    user
    elsif user = User.find_by_email(data["email"])
    user.authorizations << Authorization.new(:provider => provider, :uid => uid )
    user
    else
    user = User.new(email: data["email"], password: Devise.friendly_token[0, 20], username: data['nickname'] || data['name'])

    if user.save(:validate => false)
    user.authorizations << Authorization.new(:provider => provider, :uid => uid )
    return user
    else
    Rails.logger.warn("User.create_from_hash 失败,#{user.errors.inspect}")
    return nil
    end
    end
    end
    end
    end
    end
    32 changes: 32 additions & 0 deletions omniauth_callbacks_controller.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,32 @@
    # encoding: utf-8
    class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
    def self.provides_callback_for(*providers)
    providers.each do |provider|
    class_eval %Q{
    def #{provider}
    if not current_user.blank?
    current_user.bind_service(env["omniauth.auth"])#Add an auth to existing
    redirect_to edit_user_registration_path, :notice => "成功绑定了 #{provider} 帐号。"
    else
    @user = User.find_or_create_for_#{provider}(env["omniauth.auth"])
    if @user.persisted?
    flash[:notice] = "Signed in with #{provider.to_s.titleize} successfully."
    sign_in_and_redirect @user, :event => :authentication, :notice => "登陆成功。"
    else
    redirect_to new_user_registration_url
    end
    end
    end
    }
    end
    end

    provides_callback_for :github, :twitter, :google_oauth2, :facebook

    # This is solution for existing accout want bind Google login but current_user is always nil
    # https://github.com/intridea/omniauth/issues/185
    def handle_unverified_request
    true
    end
    end
    1 change: 1 addition & 0 deletions routes.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks" }
    2 changes: 2 additions & 0 deletions shell
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    rails g model Authorization provider:string user_id:integer uid:string
    rake db:migrate
    18 changes: 18 additions & 0 deletions user.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,18 @@
    class User < ActiveRecord::Base
    extend OmniauthCallbacks

    has_many :authorizations, :dependent => :destroy

    ...

    devise :database_authenticatable, :registerable,
    :recoverable, :rememberable, :trackable, :validatable, :omniauthable

    ...

    def bind_service(response)
    provider = response["provider"]
    uid = response["uid"]
    authorizations.create(:provider => provider , :uid => uid )
    end
    end