@@ -61,4 +61,4 @@ Code published under AFFERO GPL v3 (see [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt)
|
||||
|
||||
## Contributions
|
||||
|
||||
See [CONTRIBUTING_EN.md](CONTRIBUTING_EN.md)
|
||||
See [CONTRIBUTING_EN.md](CONTRIBUTING_EN.md)
|
||||
@@ -82,10 +82,9 @@ class ApplicationController < ActionController::Base
|
||||
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?
|
||||
if user_signed_in? &&
|
||||
current_user.registering_with_oauth &&
|
||||
%w(finish_signup do_finish_signup).exclude?(action_name)
|
||||
redirect_to finish_signup_path
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,31 +1,49 @@
|
||||
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
|
||||
}
|
||||
def twitter
|
||||
sign_in_with :twitter_login, :twitter
|
||||
end
|
||||
|
||||
[:twitter, :facebook, :google_oauth2].each do |provider|
|
||||
provides_callback_for provider
|
||||
def facebook
|
||||
sign_in_with :facebook_login, :facebook
|
||||
end
|
||||
|
||||
def google_oauth2
|
||||
sign_in_with :google_login, :google_oauth2
|
||||
end
|
||||
|
||||
def after_sign_in_path_for(resource)
|
||||
if resource.email_provided?
|
||||
super(resource)
|
||||
else
|
||||
if resource.registering_with_oauth
|
||||
finish_signup_path
|
||||
else
|
||||
super(resource)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sign_in_with(feature, provider)
|
||||
raise ActionController::RoutingError.new('Not Found') unless Setting["feature.#{feature}"]
|
||||
|
||||
auth = env["omniauth.auth"]
|
||||
|
||||
identity = Identity.first_or_create_from_oauth(auth)
|
||||
@user = current_user || identity.user || User.first_or_initialize_for_oauth(auth)
|
||||
|
||||
if save_user(@user)
|
||||
identity.update(user: @user)
|
||||
sign_in_and_redirect @user, event: :authentication
|
||||
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
|
||||
else
|
||||
session["devise.#{provider}_data"] = auth
|
||||
redirect_to new_user_registration_url
|
||||
end
|
||||
end
|
||||
|
||||
def save_user(user)
|
||||
@user.save ||
|
||||
@user.save_requiring_finish_signup ||
|
||||
@user.save_requiring_finish_signup_without_email
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -24,13 +24,16 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
||||
end
|
||||
|
||||
def finish_signup
|
||||
current_user.registering_with_oauth = false
|
||||
current_user.email = current_user.oauth_email if current_user.email.blank?
|
||||
current_user.validate
|
||||
end
|
||||
|
||||
def do_finish_signup
|
||||
current_user.registering_with_oauth = false
|
||||
if current_user.update(sign_up_params)
|
||||
current_user.skip_reconfirmation!
|
||||
sign_in(current_user, bypass: true)
|
||||
redirect_to root_url
|
||||
current_user.send_oauth_confirmation_instructions
|
||||
sign_in_and_redirect current_user, event: :authentication
|
||||
else
|
||||
render :finish_signup
|
||||
end
|
||||
|
||||
@@ -4,14 +4,7 @@ class Identity < ActiveRecord::Base
|
||||
validates :provider, presence: true
|
||||
validates :uid, presence: true, uniqueness: { scope: :provider }
|
||||
|
||||
def self.find_for_oauth(auth)
|
||||
def self.first_or_create_from_oauth(auth)
|
||||
where(uid: auth.uid, provider: auth.provider).first_or_create
|
||||
end
|
||||
|
||||
def update_user(new_user)
|
||||
return unless user != new_user
|
||||
|
||||
self.user = new_user
|
||||
save!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
class User < ActiveRecord::Base
|
||||
OMNIAUTH_EMAIL_PREFIX = 'omniauth@participacion'
|
||||
OMNIAUTH_EMAIL_REGEX = /\A#{OMNIAUTH_EMAIL_PREFIX}/
|
||||
|
||||
include Verification
|
||||
|
||||
@@ -31,7 +29,6 @@ class User < ActiveRecord::Base
|
||||
validate :validate_username_length
|
||||
|
||||
validates :official_level, inclusion: {in: 0..5}
|
||||
validates_format_of :email, without: OMNIAUTH_EMAIL_REGEX, on: :update
|
||||
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create
|
||||
|
||||
validates :locale, inclusion: {in: I18n.available_locales.map(&:to_s),
|
||||
@@ -52,42 +49,20 @@ class User < ActiveRecord::Base
|
||||
|
||||
before_validation :clean_document_number
|
||||
|
||||
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
|
||||
user ||= first_or_create_for_oauth(auth)
|
||||
|
||||
# Associate the identity with the user if needed
|
||||
identity.update_user(user)
|
||||
user
|
||||
end
|
||||
|
||||
# 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
|
||||
def self.first_or_create_for_oauth(auth)
|
||||
email = auth.info.email if auth.info.verified || auth.info.verified_email
|
||||
user = User.where(email: email).first if email
|
||||
def self.first_or_initialize_for_oauth(auth)
|
||||
oauth_email = auth.info.email
|
||||
oauth_email_confirmed = auth.info.verified || auth.info.verified_email
|
||||
oauth_user = User.find_by(email: oauth_email) if oauth_email_confirmed
|
||||
|
||||
# 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],
|
||||
terms_of_service: '1'
|
||||
)
|
||||
user.skip_confirmation!
|
||||
user.save!
|
||||
end
|
||||
|
||||
user
|
||||
oauth_user || User.new(
|
||||
username: auth.info.name || auth.uid,
|
||||
email: oauth_email,
|
||||
oauth_email: oauth_email,
|
||||
password: Devise.friendly_token[0,20],
|
||||
terms_of_service: '1',
|
||||
confirmed_at: oauth_email_confirmed ? DateTime.now : nil
|
||||
)
|
||||
end
|
||||
|
||||
def name
|
||||
@@ -170,11 +145,6 @@ class User < ActiveRecord::Base
|
||||
erased_at.present?
|
||||
end
|
||||
|
||||
def email_provided?
|
||||
!!(email && email !~ OMNIAUTH_EMAIL_REGEX) ||
|
||||
!!(unconfirmed_email && unconfirmed_email !~ OMNIAUTH_EMAIL_REGEX)
|
||||
end
|
||||
|
||||
def locked?
|
||||
Lock.find_or_create_by(user: self).locked?
|
||||
end
|
||||
@@ -197,11 +167,11 @@ class User < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def username_required?
|
||||
!organization? && !erased?
|
||||
!organization? && !erased? && !registering_with_oauth
|
||||
end
|
||||
|
||||
def email_required?
|
||||
!erased?
|
||||
!erased? && !registering_with_oauth
|
||||
end
|
||||
|
||||
def has_official_email?
|
||||
@@ -213,6 +183,26 @@ class User < ActiveRecord::Base
|
||||
self[:locale] ||= I18n.default_locale.to_s
|
||||
end
|
||||
|
||||
def confirmation_required?
|
||||
super && !registering_with_oauth
|
||||
end
|
||||
|
||||
def send_oauth_confirmation_instructions
|
||||
if oauth_email != email
|
||||
self.update(confirmed_at: nil)
|
||||
self.send_confirmation_instructions
|
||||
end
|
||||
self.update(oauth_email: nil) if oauth_email.present?
|
||||
end
|
||||
|
||||
def save_requiring_finish_signup
|
||||
self.update(registering_with_oauth: true)
|
||||
end
|
||||
|
||||
def save_requiring_finish_signup_without_email
|
||||
self.update(registering_with_oauth: true, email: nil)
|
||||
end
|
||||
|
||||
private
|
||||
def clean_document_number
|
||||
self.document_number = self.document_number.gsub(/[^a-z0-9]+/i, "").upcase unless self.document_number.blank?
|
||||
|
||||
@@ -1,12 +1,35 @@
|
||||
<% if current_page?(new_user_session_path) %>
|
||||
<%= link_to t("omniauth.twitter.sign_in"), user_omniauth_authorize_path(:twitter), class: "button-twitter button radius expand" %>
|
||||
<%= link_to t("omniauth.facebook.sign_in"), user_omniauth_authorize_path(:facebook), class: "button-facebook button radius expand" %>
|
||||
<%= link_to t("omniauth.google_oauth2.sign_in"), user_omniauth_authorize_path(:google_oauth2), class: "button-google button radius expand" %>
|
||||
<hr/>
|
||||
<% elsif current_page?(new_user_registration_path) %>
|
||||
<%= link_to t("omniauth.twitter.sign_up"), user_omniauth_authorize_path(:twitter), class: "button-twitter button radius expand" %>
|
||||
<%= link_to t("omniauth.facebook.sign_up"), user_omniauth_authorize_path(:facebook), class: "button-facebook button radius expand" %>
|
||||
<%= link_to t("omniauth.google_oauth2.sign_up"), user_omniauth_authorize_path(:google_oauth2), class: "button-google button radius expand" %>
|
||||
<p>Al hacer login con una red social, usted está aceptando los términos legales.</p>
|
||||
<hr/>
|
||||
<% end %>
|
||||
<% if feature?(:twitter_login) || feature?(:facebook_login) || feature?(:google_login) %>
|
||||
|
||||
<% if current_page?(new_user_session_path) %>
|
||||
|
||||
<% if feature? :twitter_login %>
|
||||
<%= link_to t("omniauth.twitter.sign_in"), user_omniauth_authorize_path(:twitter), class: "button-twitter button radius expand" %>
|
||||
<% end %>
|
||||
|
||||
<% if feature? :facebook_login %>
|
||||
<%= link_to t("omniauth.facebook.sign_in"), user_omniauth_authorize_path(:facebook), class: "button-facebook button radius expand" %>
|
||||
<% end %>
|
||||
|
||||
<% if feature? :google_login %>
|
||||
<%= link_to t("omniauth.google_oauth2.sign_in"), user_omniauth_authorize_path(:google_oauth2), class: "button-google button radius expand" %>
|
||||
<% end %>
|
||||
|
||||
<hr/>
|
||||
<% elsif current_page?(new_user_registration_path) %>
|
||||
|
||||
<% if feature? :twitter_login %>
|
||||
<%= link_to t("omniauth.twitter.sign_up"), user_omniauth_authorize_path(:twitter), class: "button-twitter button radius expand" %>
|
||||
<% end %>
|
||||
|
||||
<% if feature? :facebook_login %>
|
||||
<%= link_to t("omniauth.facebook.sign_up"), user_omniauth_authorize_path(:facebook), class: "button-facebook button radius expand" %>
|
||||
<% end %>
|
||||
|
||||
<% if feature? :google_login %>
|
||||
<%= link_to t("omniauth.google_oauth2.sign_up"), user_omniauth_authorize_path(:google_oauth2), class: "button-google button radius expand" %>
|
||||
<% end %>
|
||||
|
||||
<hr/>
|
||||
<% end %>
|
||||
|
||||
<% end %>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<% provide :title do %><%= t("devise_views.sessions.new.title") %><% end %>
|
||||
<h2><%= t("devise_views.sessions.new.title") %></h2>
|
||||
|
||||
<%# render 'devise/omniauth_form' %>
|
||||
<%= render 'devise/omniauth_form' %>
|
||||
|
||||
<p>
|
||||
<%= t("devise_views.shared.links.signup",
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
<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>
|
||||
<h2><%= t('omniauth.finish_signup.title') %></h2>
|
||||
|
||||
<%= 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>
|
||||
<%= form_for current_user, as: :user, url: do_finish_signup_path, html: { role: 'form'} do |f| %>
|
||||
<%= render 'shared/errors', resource: current_user %>
|
||||
|
||||
<% if current_user.errors.include? :username %>
|
||||
<%= f.text_field :username, placeholder: t("devise_views.users.registrations.new.username_label") %>
|
||||
<% else %>
|
||||
<%= f.hidden_field :username %>
|
||||
<% end %>
|
||||
|
||||
<% if current_user.errors.include? :email %>
|
||||
<%= f.email_field :email, placeholder: t("devise_views.users.registrations.new.email_label") %>
|
||||
<% else %>
|
||||
<%= f.hidden_field :email %>
|
||||
<% end %>
|
||||
|
||||
<%= f.submit t("devise_views.users.registrations.new.submit"), class: 'button radius expand' %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<% provide :title do %><%= t("devise_views.users.registrations.new.title") %><% end %>
|
||||
<h2><%= t("devise_views.users.registrations.new.title") %></h2>
|
||||
|
||||
<%# render 'devise/omniauth_form' %>
|
||||
<%= render 'devise/omniauth_form' %>
|
||||
|
||||
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
||||
<%= render 'shared/errors', resource: resource %>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set :deploy_to, deploysecret(:deploy_to)
|
||||
set :server_name, deploysecret(:server_name)
|
||||
set :db_server, deploysecret(:db_server)
|
||||
set :branch, :master
|
||||
set :branch, ENV['branch'] || :master
|
||||
set :ssh_options, port: deploysecret(:ssh_port)
|
||||
set :stage, :preproduction
|
||||
set :rails_env, :preproduction
|
||||
|
||||
@@ -240,7 +240,7 @@ Devise.setup do |config|
|
||||
# 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
|
||||
config.omniauth :facebook, Rails.application.secrets.facebook_key, Rails.application.secrets.facebook_secret
|
||||
config.omniauth :facebook, Rails.application.secrets.facebook_key, Rails.application.secrets.facebook_secret, scope: 'email', info_fields: 'email'
|
||||
config.omniauth :google_oauth2, Rails.application.secrets.google_oauth2_key, Rails.application.secrets.google_oauth2_secret
|
||||
|
||||
# ==> Warden configuration
|
||||
|
||||
@@ -15,7 +15,7 @@ en:
|
||||
not_found_in_database: "Invalid %{authentication_keys} or password."
|
||||
timeout: "Your session has expired. Please sign in again to continue."
|
||||
unauthenticated: "You must sign in or register to continue."
|
||||
unconfirmed: "You must confirm your account to continue."
|
||||
unconfirmed: "To continue, please click on the confirmation link that we have sent you via email"
|
||||
mailer:
|
||||
confirmation_instructions:
|
||||
subject: "Confirmation instructions"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
es:
|
||||
devise:
|
||||
confirmations:
|
||||
confirmed: "Tu cuenta ha sido confirmada."
|
||||
confirmed: "Tu cuenta ha sido confirmada. Por favor autentifícate con tu red social o tu usuario y contraseña"
|
||||
send_instructions: "Recibirás un correo electrónico en unos minutos con instrucciones sobre cómo restablecer tu contraseña."
|
||||
send_paranoid_instructions: "Si tu correo electrónico existe en nuestra base de datos recibirás un correo electrónico en unos minutos con instrucciones sobre cómo restablecer tu contraseña."
|
||||
failure:
|
||||
@@ -13,7 +13,7 @@ es:
|
||||
not_found_in_database: "%{authentication_keys} o contraseña inválidos."
|
||||
timeout: "Tu sesión ha expirado, por favor inicia sesión nuevamente para continuar."
|
||||
unauthenticated: "Necesitas iniciar sesión o registrarte para continuar."
|
||||
unconfirmed: "Debes confirmar tu cuenta para continuar."
|
||||
unconfirmed: "Para continuar, por favor pulsa en el enlace de confirmación que hemos enviado a tu cuenta de correo."
|
||||
mailer:
|
||||
confirmation_instructions:
|
||||
subject: "Instrucciones de confirmación"
|
||||
@@ -22,8 +22,8 @@ es:
|
||||
unlock_instructions:
|
||||
subject: "Instrucciones de desbloqueo"
|
||||
omniauth_callbacks:
|
||||
failure: "No se te ha podido autorizar de %{kind} debido a \"%{reason}\"."
|
||||
success: "Identificado correctamente de %{kind}."
|
||||
failure: "No se te ha podido identificar via %{kind} por el siguiente motivo: \"%{reason}\"."
|
||||
success: "Identificado correctamente via %{kind}."
|
||||
passwords:
|
||||
no_token: "No puedes acceder a esta página si no es a través de un enlace para restablecer la contraseña. Si has accedido desde el enlace para restablecer la contraseña, asegúrate de que la URL esté completa."
|
||||
send_instructions: "Recibirás un correo electrónico con instrucciones sobre cómo restablecer tu contraseña en unos minutos."
|
||||
|
||||
@@ -468,3 +468,22 @@ en:
|
||||
user_permission_verify_info: "* Only for users on Madrid Census."
|
||||
user_permission_verify_url: verify your account
|
||||
user_permission_votes: Participate on final voting
|
||||
omniauth:
|
||||
finish_signup:
|
||||
title: "Additional details"
|
||||
twitter:
|
||||
sign_in: "Sign in with Twitter"
|
||||
sign_up: "Sign up with Twitter"
|
||||
facebook:
|
||||
sign_in: "Sign in with Facebook"
|
||||
sign_up: "Sign up with Facebook"
|
||||
google_oauth2:
|
||||
sign_in: "Sign in with Google"
|
||||
sign_up: "Sign up with Google"
|
||||
legislation:
|
||||
help:
|
||||
title: "How I can comment this document?"
|
||||
text: "To comment this document you must %{sign_in} or %{sign_up}. Then select the text you want to comment and press the button with the pencil."
|
||||
text_sign_in: "login"
|
||||
text_sign_up: "sign up"
|
||||
alt: "Select the text you want to comment and press the button with the pencil."
|
||||
|
||||
@@ -468,3 +468,22 @@ es:
|
||||
user_permission_verify_info: "* Sólo usuarios empadronados en el municipio de Madrid."
|
||||
user_permission_verify_url: verifica tu cuenta
|
||||
user_permission_votes: Participar en las votaciones finales*
|
||||
omniauth:
|
||||
finish_signup:
|
||||
title: "Detalles adicionales de tu cuenta"
|
||||
twitter:
|
||||
sign_in: "Entra con Twitter"
|
||||
sign_up: "Regístrate con Twitter"
|
||||
facebook:
|
||||
sign_in: "Entra con Facebook"
|
||||
sign_up: "Regístrate con Facebook"
|
||||
google_oauth2:
|
||||
sign_in: "Entra con Google"
|
||||
sign_up: "Regístrate con Google"
|
||||
legislation:
|
||||
help:
|
||||
title: "¿Cómo puedo comentar este documento?"
|
||||
text: "Para comentar este documento debes %{sign_in} o %{sign_up}. Después selecciona el texto que quieres comentar y pulsa en el botón con el lápiz."
|
||||
text_sign_in: "iniciar sesión"
|
||||
text_sign_up: "registrarte"
|
||||
alt: "Selecciona el texto que quieres comentar y pulsa en el botón con el lápiz."
|
||||
|
||||
@@ -20,6 +20,9 @@ Setting.create(key: 'org_name', value: 'Consul')
|
||||
Setting.create(key: 'place_name', value: 'City')
|
||||
Setting.create(key: 'feature.debates', value: "true")
|
||||
Setting.create(key: 'feature.spending_proposals', value: "true")
|
||||
Setting.create(key: 'feature.twitter_login', value: "true")
|
||||
Setting.create(key: 'feature.facebook_login', value: "true")
|
||||
Setting.create(key: 'feature.google_login', value: "true")
|
||||
|
||||
puts "Creating Geozones"
|
||||
('A'..'Z').each{ |i| Geozone.create(name: "District #{i}") }
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddRegisteringWithOauthToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :registering_with_oauth, :bool, default: false
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddConfirmedOauthEmailToUser < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :confirmed_oauth_email, :string
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class RenameConfirmedOauthEmailToOauthEmail < ActiveRecord::Migration
|
||||
def change
|
||||
rename_column :users, :confirmed_oauth_email, :oauth_email
|
||||
end
|
||||
end
|
||||
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20160122153329) do
|
||||
ActiveRecord::Schema.define(version: 20160126090634) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -397,6 +397,8 @@ ActiveRecord::Schema.define(version: 20160122153329) do
|
||||
t.boolean "newsletter", default: false
|
||||
t.integer "notifications_count", default: 0
|
||||
t.string "locale"
|
||||
t.boolean "registering_with_oauth", default: false
|
||||
t.string "oauth_email"
|
||||
end
|
||||
|
||||
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
|
||||
|
||||
@@ -53,3 +53,6 @@ Setting["place_name"] = "Consul-land"
|
||||
# Feature flags
|
||||
Setting['feature.debates'] = true
|
||||
Setting['feature.spending_proposals'] = true
|
||||
Setting['feature.twitter_login'] = true
|
||||
Setting['feature.facebook_login'] = true
|
||||
Setting['feature.google_login'] = true
|
||||
|
||||
@@ -18,8 +18,7 @@ feature 'Users' do
|
||||
|
||||
expect(page).to have_content "You have been sent a message containing a verification link. Please click on this link to activate your account."
|
||||
|
||||
sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
|
||||
visit user_confirmation_path(confirmation_token: sent_token)
|
||||
confirm_email
|
||||
|
||||
expect(page).to have_content "Your account has been confirmed."
|
||||
end
|
||||
@@ -45,115 +44,192 @@ feature 'Users' do
|
||||
end
|
||||
end
|
||||
|
||||
xcontext 'OAuth authentication' do
|
||||
context 'OAuth authentication' do
|
||||
context 'Twitter' do
|
||||
background do
|
||||
#request.env["devise.mapping"] = Devise.mappings[:user]
|
||||
end
|
||||
|
||||
scenario 'Sign up, when email was provided by OAuth provider' do
|
||||
omniauth_twitter_hash = { 'provider' => 'twitter',
|
||||
'uid' => '12345',
|
||||
'info' => {
|
||||
'name' => 'manuela',
|
||||
'email' => 'manuelacarmena@example.com',
|
||||
'nickname' => 'ManuelaRocks',
|
||||
'verified' => '1'
|
||||
},
|
||||
'extra' => { 'raw_info' =>
|
||||
{ 'location' => 'Madrid',
|
||||
'name' => 'Manuela de las Carmenas'
|
||||
}
|
||||
}
|
||||
}
|
||||
let(:twitter_hash){ {provider: 'twitter', uid: '12345', info: {name: 'manuela'}} }
|
||||
let(:twitter_hash_with_email){ {provider: 'twitter', uid: '12345', info: {name: 'manuela', email: 'manuelacarmena@example.com'}} }
|
||||
let(:twitter_hash_with_verified_email){ {provider: 'twitter',
|
||||
uid: '12345',
|
||||
info: {name: 'manuela', email: 'manuelacarmena@example.com', verified: '1'}} }
|
||||
|
||||
OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
|
||||
|
||||
scenario 'Sign up when Oauth provider has a verified email' do
|
||||
OmniAuth.config.add_mock(:twitter, twitter_hash_with_verified_email)
|
||||
|
||||
visit '/'
|
||||
click_link 'Register'
|
||||
|
||||
expect do
|
||||
expect do
|
||||
expect do
|
||||
click_link 'Sign up with Twitter'
|
||||
end.not_to change { ActionMailer::Base.deliveries.size }
|
||||
end.to change { Identity.count }.by(1)
|
||||
end.to change { User.count }.by(1)
|
||||
click_link 'Sign up with Twitter'
|
||||
|
||||
expect(current_path).to eq(root_path)
|
||||
expect_to_be_signed_in
|
||||
|
||||
user = User.last
|
||||
expect(user.username).to eq('ManuelaRocks')
|
||||
expect(user.email).to eq('manuelacarmena@example.com')
|
||||
expect(user.confirmed?).to eq(true)
|
||||
click_link 'My account'
|
||||
expect(page).to have_field('account_username', with: 'manuela')
|
||||
|
||||
visit edit_user_registration_path
|
||||
expect(page).to have_field('user_email', with: 'manuelacarmena@example.com')
|
||||
end
|
||||
|
||||
scenario 'Sign up, when neither email nor nickname were provided by OAuth provider' do
|
||||
omniauth_twitter_hash = { 'provider' => 'twitter',
|
||||
'uid' => '12345',
|
||||
'info' => {
|
||||
'name' => 'manuela'
|
||||
},
|
||||
'extra' => { 'raw_info' =>
|
||||
{ 'location' => 'Madrid',
|
||||
'name' => 'Manuela de las Carmenas'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
|
||||
scenario 'Sign up when Oauth provider has an unverified email' do
|
||||
OmniAuth.config.add_mock(:twitter, twitter_hash_with_email)
|
||||
|
||||
visit '/'
|
||||
click_link 'Register'
|
||||
|
||||
expect do
|
||||
expect do
|
||||
expect do
|
||||
click_link 'Sign up with Twitter'
|
||||
end.not_to change { ActionMailer::Base.deliveries.size }
|
||||
end.to change { Identity.count }.by(1)
|
||||
end.to change { User.count }.by(1)
|
||||
click_link 'Sign up with Twitter'
|
||||
|
||||
expect(current_path).to eq(new_user_session_path)
|
||||
expect(page).to have_content "To continue, please click on the confirmation link that we have sent you via email"
|
||||
|
||||
confirm_email
|
||||
expect(page).to have_content "Your account has been confirmed"
|
||||
|
||||
visit '/'
|
||||
click_link 'Sign in'
|
||||
click_link 'Sign in with Twitter'
|
||||
expect_to_be_signed_in
|
||||
|
||||
click_link 'My account'
|
||||
expect(page).to have_field('account_username', with: 'manuela')
|
||||
|
||||
visit edit_user_registration_path
|
||||
expect(page).to have_field('user_email', with: 'manuelacarmena@example.com')
|
||||
end
|
||||
|
||||
scenario 'Sign up, when no email was provided by OAuth provider' do
|
||||
OmniAuth.config.add_mock(:twitter, twitter_hash)
|
||||
|
||||
visit '/'
|
||||
click_link 'Register'
|
||||
click_link 'Sign up with Twitter'
|
||||
|
||||
expect(current_path).to eq(finish_signup_path)
|
||||
|
||||
user = User.last
|
||||
expect(user.username).to eq('manuela-de-las-carmenas')
|
||||
expect(user.email).to eq("omniauth@participacion-12345-twitter.com")
|
||||
|
||||
fill_in 'user_email', with: 'manueladelascarmenas@example.com'
|
||||
click_button 'Register'
|
||||
|
||||
sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
|
||||
visit user_confirmation_path(confirmation_token: sent_token)
|
||||
expect(page).to have_content "To continue, please click on the confirmation link that we have sent you via email"
|
||||
|
||||
expect(page).to have_content "Your email address has been successfully confirmed"
|
||||
confirm_email
|
||||
expect(page).to have_content "Your account has been confirmed"
|
||||
|
||||
expect(user.reload.email).to eq('manueladelascarmenas@example.com')
|
||||
visit '/'
|
||||
click_link 'Sign in'
|
||||
click_link 'Sign in with Twitter'
|
||||
expect_to_be_signed_in
|
||||
|
||||
click_link 'My account'
|
||||
expect(page).to have_field('account_username', with: 'manuela')
|
||||
|
||||
visit edit_user_registration_path
|
||||
expect(page).to have_field('user_email', with: 'manueladelascarmenas@example.com')
|
||||
end
|
||||
|
||||
scenario 'Sign in, user was already signed up with OAuth' do
|
||||
user = create(:user, email: 'manuela@madrid.es', password: 'judgementday')
|
||||
identity = create(:identity, uid: '12345', provider: 'twitter', user: user)
|
||||
omniauth_twitter_hash = { 'provider' => 'twitter',
|
||||
'uid' => '12345',
|
||||
'info' => {
|
||||
'name' => 'manuela'
|
||||
}
|
||||
}
|
||||
|
||||
OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
|
||||
create(:identity, uid: '12345', provider: 'twitter', user: user)
|
||||
OmniAuth.config.add_mock(:twitter, twitter_hash)
|
||||
|
||||
visit '/'
|
||||
click_link 'Sign in'
|
||||
|
||||
expect do
|
||||
expect do
|
||||
click_link 'Sign in with Twitter'
|
||||
end.not_to change { Identity.count }
|
||||
end.not_to change { User.count }
|
||||
click_link 'Sign in with Twitter'
|
||||
|
||||
expect_to_be_signed_in
|
||||
|
||||
click_link 'My account'
|
||||
expect(page).to have_field('account_username', with: user.username)
|
||||
|
||||
visit edit_user_registration_path
|
||||
expect(page).to have_field('user_email', with: user.email)
|
||||
|
||||
end
|
||||
|
||||
scenario 'Try to register with the username of an already existing user' do
|
||||
create(:user, username: 'manuela', email: 'manuela@madrid.es', password: 'judgementday')
|
||||
OmniAuth.config.add_mock(:twitter, twitter_hash_with_verified_email)
|
||||
|
||||
visit '/'
|
||||
click_link 'Register'
|
||||
click_link 'Sign up with Twitter'
|
||||
|
||||
expect(current_path).to eq(finish_signup_path)
|
||||
|
||||
fill_in 'user_username', with: 'manuela2'
|
||||
click_button 'Register'
|
||||
|
||||
expect_to_be_signed_in
|
||||
|
||||
click_link 'My account'
|
||||
expect(page).to have_field('account_username', with: 'manuela2')
|
||||
|
||||
visit edit_user_registration_path
|
||||
expect(page).to have_field('user_email', with: 'manuelacarmena@example.com')
|
||||
end
|
||||
|
||||
scenario 'Try to register with the email of an already existing user, when no email was provided by oauth' do
|
||||
create(:user, username: 'peter', email: 'manuela@example.com')
|
||||
OmniAuth.config.add_mock(:twitter, twitter_hash)
|
||||
|
||||
visit '/'
|
||||
click_link 'Register'
|
||||
click_link 'Sign up with Twitter'
|
||||
|
||||
expect(current_path).to eq(finish_signup_path)
|
||||
|
||||
fill_in 'user_email', with: 'manuela@example.com'
|
||||
click_button 'Register'
|
||||
|
||||
expect(current_path).to eq(do_finish_signup_path)
|
||||
|
||||
fill_in 'user_email', with: 'somethingelse@example.com'
|
||||
click_button 'Register'
|
||||
|
||||
expect(page).to have_content "To continue, please click on the confirmation link that we have sent you via email"
|
||||
|
||||
confirm_email
|
||||
expect(page).to have_content "Your account has been confirmed"
|
||||
|
||||
visit '/'
|
||||
click_link 'Sign in'
|
||||
click_link 'Sign in with Twitter'
|
||||
expect_to_be_signed_in
|
||||
|
||||
click_link 'My account'
|
||||
expect(page).to have_field('account_username', with: 'manuela')
|
||||
|
||||
visit edit_user_registration_path
|
||||
expect(page).to have_field('user_email', with: 'somethingelse@example.com')
|
||||
end
|
||||
|
||||
scenario 'Try to register with the email of an already existing user, when an unconfirmed email was provided by oauth' do
|
||||
create(:user, username: 'peter', email: 'manuelacarmena@example.com')
|
||||
OmniAuth.config.add_mock(:twitter, twitter_hash_with_email)
|
||||
|
||||
visit '/'
|
||||
click_link 'Register'
|
||||
click_link 'Sign up with Twitter'
|
||||
|
||||
expect(current_path).to eq(finish_signup_path)
|
||||
|
||||
expect(page).to have_field('user_email', with: 'manuelacarmena@example.com')
|
||||
fill_in 'user_email', with: 'somethingelse@example.com'
|
||||
click_button 'Register'
|
||||
|
||||
expect(page).to have_content "To continue, please click on the confirmation link that we have sent you via email"
|
||||
|
||||
confirm_email
|
||||
expect(page).to have_content "Your account has been confirmed"
|
||||
|
||||
visit '/'
|
||||
click_link 'Sign in'
|
||||
click_link 'Sign in with Twitter'
|
||||
expect_to_be_signed_in
|
||||
|
||||
click_link 'My account'
|
||||
expect(page).to have_field('account_username', with: 'manuela')
|
||||
|
||||
visit edit_user_registration_path
|
||||
expect(page).to have_field('user_email', with: 'somethingelse@example.com')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -85,26 +85,6 @@ describe User do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'OmniAuth' do
|
||||
describe '#email_provided?' do
|
||||
it "is false if the email matchs was temporarely assigned by the OmniAuth process" do
|
||||
subject.email = 'omniauth@participacion-ABCD-twitter.com'
|
||||
expect(subject.email_provided?).to eq(false)
|
||||
end
|
||||
|
||||
it "is true if the email is not omniauth-like" do
|
||||
subject.email = 'manuelacarmena@example.com'
|
||||
expect(subject.email_provided?).to eq(true)
|
||||
end
|
||||
|
||||
it "is true if the user's real email is pending to be confirmed" do
|
||||
subject.email = 'omniauth@participacion-ABCD-twitter.com'
|
||||
subject.unconfirmed_email = 'manuelacarmena@example.com'
|
||||
expect(subject.email_provided?).to eq(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "administrator?" do
|
||||
it "is false when the user is not an admin" do
|
||||
expect(subject.administrator?).to be false
|
||||
@@ -245,23 +225,23 @@ describe User do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "has_official_email" do
|
||||
it "checks if the mail address has the officials domain" do
|
||||
# We will use empleados.madrid.es as the officials' domain
|
||||
# Subdomains are also accepted
|
||||
|
||||
Setting['email_domain_for_officials'] = 'officials.madrid.es'
|
||||
|
||||
user1 = create(:user, email: "john@officials.madrid.es", confirmed_at: Time.now)
|
||||
user2 = create(:user, email: "john@yes.officials.madrid.es", confirmed_at: Time.now)
|
||||
user3 = create(:user, email: "john@unofficials.madrid.es", confirmed_at: Time.now)
|
||||
user4 = create(:user, email: "john@example.org", confirmed_at: Time.now)
|
||||
|
||||
|
||||
expect(user1.has_official_email?).to eq(true)
|
||||
expect(user2.has_official_email?).to eq(true)
|
||||
expect(user3.has_official_email?).to eq(false)
|
||||
expect(user4.has_official_email?).to eq(false)
|
||||
|
||||
|
||||
# We reset the officials' domain setting
|
||||
Setting.find_by(key: 'email_domain_for_officials').update(value: '')
|
||||
end
|
||||
|
||||
@@ -36,12 +36,13 @@ module CommonActions
|
||||
end
|
||||
|
||||
def confirm_email
|
||||
expect(page).to have_content "A message with a confirmation link has been sent to your email address."
|
||||
body = ActionMailer::Base.deliveries.last.try(:body)
|
||||
expect(body).to be_present
|
||||
|
||||
sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
|
||||
sent_token = /.*confirmation_token=(.*)".*/.match(body.to_s)[1]
|
||||
visit user_confirmation_path(confirmation_token: sent_token)
|
||||
|
||||
expect(page).to have_content "Your email address has been successfully confirmed"
|
||||
expect(page).to have_content "Your account has been confirmed"
|
||||
end
|
||||
|
||||
def reset_password
|
||||
|
||||
Reference in New Issue
Block a user