adds omniauth basic authentication process with Twitter, including an intermediate step to ask the user for her email if not provided by the OAuth provider - Twitter, for instance
This commit is contained in:
@@ -13,6 +13,8 @@ class ApplicationController < ActionController::Base
|
||||
# For APIs, you may want to use :null_session instead.
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
before_action :ensure_signup_complete
|
||||
|
||||
rescue_from CanCan::AccessDenied do |exception|
|
||||
redirect_to main_app.root_url, alert: exception.message
|
||||
end
|
||||
@@ -40,4 +42,13 @@ class ApplicationController < ActionController::Base
|
||||
def set_debate_votes(debates)
|
||||
@voted_values = current_user ? current_user.debate_votes(debates) : {}
|
||||
end
|
||||
|
||||
def ensure_signup_complete
|
||||
# Ensure we don't go into an infinite loop
|
||||
return if action_name.in? %w(finish_signup do_finish_signup)
|
||||
|
||||
if user_signed_in? && !current_user.email_provided?
|
||||
redirect_to finish_signup_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
30
app/controllers/users/omniauth_callbacks_controller.rb
Normal file
30
app/controllers/users/omniauth_callbacks_controller.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
def self.provides_callback_for(provider)
|
||||
class_eval %Q{
|
||||
def #{provider}
|
||||
@user = User.find_for_oauth(env["omniauth.auth"], current_user)
|
||||
|
||||
if @user.persisted?
|
||||
sign_in_and_redirect @user, event: :authentication
|
||||
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
|
||||
else
|
||||
session["devise.#{provider}_data"] = env["omniauth.auth"]
|
||||
redirect_to new_user_registration_url
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# [:twitter, :facebook, :google_oauth2].each do |provider|
|
||||
[:twitter].each do |provider|
|
||||
provides_callback_for provider
|
||||
end
|
||||
|
||||
def after_sign_in_path_for(resource)
|
||||
if resource.email_provided?
|
||||
super(resource)
|
||||
else
|
||||
finish_signup_path
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,5 @@
|
||||
class Users::RegistrationsController < Devise::RegistrationsController
|
||||
prepend_before_filter :authenticate_scope!, only: [:edit, :update, :destroy, :finish_signup, :do_finish_signup]
|
||||
|
||||
def create
|
||||
build_resource(sign_up_params)
|
||||
@@ -9,6 +10,20 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
||||
end
|
||||
end
|
||||
|
||||
def finish_signup
|
||||
end
|
||||
|
||||
def do_finish_signup
|
||||
if current_user.update(sign_up_params)
|
||||
current_user.skip_reconfirmation!
|
||||
sign_in(current_user, bypass: true)
|
||||
redirect_to root_url, notice: I18n.t('devise.registrations.updated')
|
||||
else
|
||||
@show_errors = true
|
||||
render :finish_signup
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sign_up_params
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
class User < ActiveRecord::Base
|
||||
include ActsAsParanoidAliases
|
||||
|
||||
OMNIAUTH_EMAIL_PREFIX = 'omniauth@participacion'
|
||||
OMNIAUTH_EMAIL_REGEX = /\A#{OMNIAUTH_EMAIL_PREFIX}/
|
||||
|
||||
apply_simple_captcha
|
||||
devise :database_authenticatable, :registerable, :confirmable,
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
|
||||
|
||||
acts_as_voter
|
||||
acts_as_paranoid column: :hidden_at
|
||||
@@ -11,9 +15,11 @@ class User < ActiveRecord::Base
|
||||
has_one :moderator
|
||||
has_one :organization
|
||||
has_many :inappropiate_flags
|
||||
has_many :identities, dependent: :destroy
|
||||
|
||||
validates :username, presence: true, unless: :organization?
|
||||
validates :username, presence: true, unless: :organization?
|
||||
validates :official_level, inclusion: {in: 0..5}
|
||||
validates_format_of :email, without: OMNIAUTH_EMAIL_REGEX, on: :update
|
||||
|
||||
validates_associated :organization, message: false
|
||||
|
||||
@@ -25,6 +31,47 @@ class User < ActiveRecord::Base
|
||||
scope :organizations, -> { joins(:organization) }
|
||||
scope :officials, -> { where("official_level > 0") }
|
||||
|
||||
def self.find_for_oauth(auth, signed_in_resource = nil)
|
||||
# Get the identity and user if they exist
|
||||
identity = Identity.find_for_oauth(auth)
|
||||
|
||||
# If a signed_in_resource is provided it always overrides the existing user
|
||||
# to prevent the identity being locked with accidentally created accounts.
|
||||
# Note that this may leave zombie accounts (with no associated identity) which
|
||||
# can be cleaned up at a later date.
|
||||
user = signed_in_resource ? signed_in_resource : identity.user
|
||||
|
||||
# Create the user if needed
|
||||
if user.nil?
|
||||
|
||||
# Get the existing user by email if the provider gives us a verified email.
|
||||
# If no verified email was provided we assign a temporary email and ask the
|
||||
# user to verify it on the next step via RegistrationsController.finish_signup
|
||||
email_is_verified = auth.info.email && (auth.info.verified || auth.info.verified_email)
|
||||
email = auth.info.email if email_is_verified
|
||||
user = User.where(email: email).first if email
|
||||
|
||||
# Create the user if it's a new registration
|
||||
if user.nil?
|
||||
user = User.new(
|
||||
username: auth.info.nickname || auth.extra.raw_info.name.parameterize('-') || auth.uid,
|
||||
email: email ? email : "#{OMNIAUTH_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com",
|
||||
password: Devise.friendly_token[0,20]
|
||||
)
|
||||
user.skip_confirmation!
|
||||
user.save!
|
||||
end
|
||||
end
|
||||
|
||||
# Associate the identity with the user if needed
|
||||
if identity.user != user
|
||||
identity.user = user
|
||||
identity.save!
|
||||
end
|
||||
|
||||
user
|
||||
end
|
||||
|
||||
def name
|
||||
organization? ? organization.name : username
|
||||
end
|
||||
@@ -67,4 +114,8 @@ class User < ActiveRecord::Base
|
||||
e.present? ? where(email: e) : none
|
||||
end
|
||||
|
||||
def email_provided?
|
||||
!!(email && email !~ OMNIAUTH_EMAIL_REGEX) ||
|
||||
!!(unconfirmed_email && unconfirmed_email !~ OMNIAUTH_EMAIL_REGEX)
|
||||
end
|
||||
end
|
||||
|
||||
5
app/views/devise/_omniauth_form.html.erb
Normal file
5
app/views/devise/_omniauth_form.html.erb
Normal file
@@ -0,0 +1,5 @@
|
||||
<br/>
|
||||
|
||||
<%= link_to t("omniauth.twitter.sign_in"), user_omniauth_authorize_path(:twitter), class: 'button radius expand' %>
|
||||
|
||||
<hr/>
|
||||
@@ -7,11 +7,11 @@
|
||||
<%= link_to(t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete) %>
|
||||
</li>
|
||||
<% else %>
|
||||
<li>
|
||||
<%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button radius small") %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button radius small") %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
@@ -3,6 +3,8 @@
|
||||
<div class="panel">
|
||||
<h2><%= t("devise_views.sessions.new.title") %></h2>
|
||||
|
||||
<%= render 'devise/omniauth_form' %>
|
||||
|
||||
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
|
||||
13
app/views/users/registrations/finish_signup.html.erb
Normal file
13
app/views/users/registrations/finish_signup.html.erb
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="auth row">
|
||||
<div class="small-12 medium-8 large-5 column small-centered">
|
||||
<div class="panel">
|
||||
<h1><%= t('omniauth.finish_signup.title') %></h1>
|
||||
|
||||
<%= form_for current_user, as: :user, url: do_finish_signup_path, html: { role: 'form'} do |f| %>
|
||||
<%= render 'shared/errors', resource: current_user %>
|
||||
<%= f.email_field :email, placeholder: t("devise_views.users.registrations.new.email_label"), value: nil %>
|
||||
<%= f.submit t("devise_views.users.registrations.new.submit"), class: 'button radius' %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2,6 +2,9 @@
|
||||
<div class="small-12 medium-8 large-5 column small-centered">
|
||||
<div class="panel">
|
||||
<h2><%= t("devise_views.users.registrations.new.title") %></h2>
|
||||
|
||||
<%= render 'devise/omniauth_form' %>
|
||||
|
||||
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
||||
<%= render 'shared/errors', resource: resource %>
|
||||
|
||||
|
||||
@@ -239,6 +239,7 @@ Devise.setup do |config|
|
||||
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
||||
# up on your models and hooks.
|
||||
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
|
||||
config.omniauth :twitter, Rails.application.secrets.twitter_key, Rails.application.secrets.twitter_secret
|
||||
|
||||
# ==> Warden configuration
|
||||
# If you want to use other strategies, that are not supported by Devise, or
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
provider :developer unless Rails.env.production?
|
||||
provider :twitter, Rails.application.secrets.twitter_key, Rails.application.secrets.twitter_secret
|
||||
end
|
||||
@@ -148,3 +148,9 @@ en:
|
||||
all: "You are not authorized to %{action} %{subject}."
|
||||
welcome:
|
||||
last_debates: Last debates
|
||||
omniauth:
|
||||
finish_signup:
|
||||
title: Add Email
|
||||
twitter:
|
||||
sign_in: Sign in with Twitter
|
||||
or: or
|
||||
|
||||
@@ -148,3 +148,9 @@ es:
|
||||
all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}."
|
||||
welcome:
|
||||
last_debates: Últimos debates
|
||||
omniauth:
|
||||
finish_signup:
|
||||
title: Añade tu email
|
||||
twitter:
|
||||
sign_in: Inicia sessión con Twitter
|
||||
or: o
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
Rails.application.routes.draw do
|
||||
devise_for :users, controllers: { registrations: 'users/registrations' }
|
||||
devise_for :users, controllers: {
|
||||
registrations: 'users/registrations',
|
||||
omniauth_callbacks: 'users/omniauth_callbacks'
|
||||
}
|
||||
devise_for :organizations, class_name: 'User',
|
||||
controllers: {
|
||||
registrations: 'organizations/registrations',
|
||||
sessions: 'devise/sessions'
|
||||
}
|
||||
sessions: 'devise/sessions',
|
||||
},
|
||||
skip: [:omniauth_callbacks]
|
||||
|
||||
devise_scope :user do
|
||||
get :finish_signup, to: 'users/registrations#finish_signup'
|
||||
patch :do_finish_signup, to: 'users/registrations#do_finish_signup'
|
||||
end
|
||||
|
||||
# The priority is based upon order of creation: first created -> highest priority.
|
||||
# See how all your routes lay out with "rake routes".
|
||||
|
||||
Reference in New Issue
Block a user