diff --git a/Gemfile.lock b/Gemfile.lock
index 9e76ebda4..800b14763 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -234,7 +234,7 @@ GEM
railties (>= 3.2)
loofah (2.0.3)
nokogiri (>= 1.5.9)
- mail (2.6.6.rc1)
+ mail (2.6.6)
mime-types (>= 1.16, < 4)
mime-types (3.1)
mime-types-data (~> 3.2015)
@@ -551,4 +551,4 @@ DEPENDENCIES
whenever
BUNDLED WITH
- 1.15.0
+ 1.15.1
diff --git a/app/models/user.rb b/app/models/user.rb
index 7d696297e..a9318aed0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -3,7 +3,8 @@ class User < ActiveRecord::Base
include Verification
devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable,
- :trackable, :validatable, :omniauthable, :async, :password_expirable, :secure_validatable
+ :trackable, :validatable, :omniauthable, :async, :password_expirable, :secure_validatable,
+ authentication_keys: [:login]
acts_as_voter
acts_as_paranoid column: :hidden_at
@@ -48,6 +49,7 @@ class User < ActiveRecord::Base
attr_accessor :skip_password_validation
attr_accessor :use_redeemable_code
+ attr_accessor :login
scope :administrators, -> { joins(:administrators) }
scope :moderators, -> { joins(:moderator) }
@@ -286,6 +288,14 @@ class User < ActiveRecord::Base
end
delegate :can?, :cannot?, to: :ability
+ # overwritting of Devise method to allow login using email OR username
+ def self.find_for_database_authentication(warden_conditions)
+ conditions = warden_conditions.dup
+ login = conditions.delete(:login)
+ where(conditions.to_hash).where(["lower(email) = ?", login.downcase]).first ||
+ where(conditions.to_hash).where(["username = ?", login]).first
+ end
+
private
def clean_document_number
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb
index 910135853..da8e74528 100644
--- a/app/views/devise/sessions/new.html.erb
+++ b/app/views/devise/sessions/new.html.erb
@@ -11,7 +11,7 @@
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
- <%= f.email_field :email, autofocus: true, placeholder: t("devise_views.sessions.new.email_label") %>
+ <%= f.text_field :login, autofocus: true, placeholder: t("devise_views.sessions.new.login_label") %>
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index c9fd00aab..d36a481ae 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -113,6 +113,7 @@ en:
description: "Description"
terms_of_service: "Terms of service"
user:
+ login: "Email or username"
email: "Email"
username: "Username"
password_confirmation: "Password confirmation"
diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml
index 7b4fbebeb..f42577ef2 100644
--- a/config/locales/activerecord.es.yml
+++ b/config/locales/activerecord.es.yml
@@ -108,6 +108,7 @@ es:
description: "Descripción"
terms_of_service: "Términos de servicio"
user:
+ login: Email o nombre de usuario
email: "Correo electrónico"
username: "Nombre de usuario"
password_confirmation: "Confirmación de contraseña"
diff --git a/config/locales/devise_views.en.yml b/config/locales/devise_views.en.yml
index bcd1f1a77..4110fb60e 100755
--- a/config/locales/devise_views.en.yml
+++ b/config/locales/devise_views.en.yml
@@ -68,7 +68,7 @@ en:
title: Forgotten password?
sessions:
new:
- email_label: Email
+ login_label: Email or username
password_label: Password
remember_me: Remember me
submit: Enter
diff --git a/config/locales/devise_views.es.yml b/config/locales/devise_views.es.yml
index be8aff97b..184454654 100644
--- a/config/locales/devise_views.es.yml
+++ b/config/locales/devise_views.es.yml
@@ -68,7 +68,7 @@ es:
title: "¿Has olvidado tu contraseña?"
sessions:
new:
- email_label: Email
+ login_label: Email o nombre de usuario
password_label: Contraseña
remember_me: Recordarme
submit: Entrar
diff --git a/spec/features/account_spec.rb b/spec/features/account_spec.rb
index ef24226f1..1ed0a4a01 100644
--- a/spec/features/account_spec.rb
+++ b/spec/features/account_spec.rb
@@ -138,6 +138,6 @@ feature 'Account' do
login_through_form_as(@user)
- expect(page).to have_content "Invalid email or password"
+ expect(page).to have_content "Invalid login or password"
end
end
diff --git a/spec/features/moderation/users_spec.rb b/spec/features/moderation/users_spec.rb
index 053d29590..e34b4383e 100644
--- a/spec/features/moderation/users_spec.rb
+++ b/spec/features/moderation/users_spec.rb
@@ -42,11 +42,11 @@ feature 'Moderate users' do
visit root_path
click_link 'Sign in'
- fill_in 'user_email', with: citizen.email
+ fill_in 'user_login', with: citizen.email
fill_in 'user_password', with: citizen.password
click_button 'Enter'
- expect(page).to have_content 'Invalid email or password'
+ expect(page).to have_content 'Invalid login or password'
expect(current_path).to eq(new_user_session_path)
end
diff --git a/spec/features/users_auth_spec.rb b/spec/features/users_auth_spec.rb
index e978e7bd2..0e3d7b5e5 100644
--- a/spec/features/users_auth_spec.rb
+++ b/spec/features/users_auth_spec.rb
@@ -3,43 +3,102 @@ require 'rails_helper'
feature 'Users' do
context 'Regular authentication' do
- scenario 'Sign up' do
- visit '/'
- click_link 'Register'
+ context 'Sign up' do
- fill_in 'user_username', with: 'Manuela Carmena'
- fill_in 'user_email', with: 'manuela@consul.dev'
- fill_in 'user_password', with: 'judgementday'
- fill_in 'user_password_confirmation', with: 'judgementday'
- check 'user_terms_of_service'
+ scenario 'Success' do
+ visit '/'
+ click_link 'Register'
- click_button 'Register'
+ fill_in 'user_username', with: 'Manuela Carmena'
+ fill_in 'user_email', with: 'manuela@consul.dev'
+ fill_in 'user_password', with: 'judgementday'
+ fill_in 'user_password_confirmation', with: 'judgementday'
+ check 'user_terms_of_service'
- expect(page).to have_content "You have been sent a message containing a verification link. Please click on this link to activate your account."
+ click_button 'Register'
- confirm_email
+ expect(page).to have_content "You have been sent a message containing a verification link. Please click on this link to activate your account."
+
+ confirm_email
+
+ expect(page).to have_content "Your account has been confirmed."
+ end
+
+ scenario 'Errors on sign up' do
+ visit '/'
+ click_link 'Register'
+ click_button 'Register'
+
+ expect(page).to have_content error_message
+ end
- expect(page).to have_content "Your account has been confirmed."
end
- scenario 'Errors on sign up' do
- visit '/'
- click_link 'Register'
- click_button 'Register'
+ context 'Sign in' do
- expect(page).to have_content error_message
- end
+ scenario 'sign in with email' do
+ create(:user, email: 'manuela@consul.dev', password: 'judgementday')
- scenario 'Sign in' do
- create(:user, email: 'manuela@consul.dev', password: 'judgementday')
+ visit '/'
+ click_link 'Sign in'
+ fill_in 'user_login', with: 'manuela@consul.dev'
+ fill_in 'user_password', with: 'judgementday'
+ click_button 'Enter'
- visit '/'
- click_link 'Sign in'
- fill_in 'user_email', with: 'manuela@consul.dev'
- fill_in 'user_password', with: 'judgementday'
- click_button 'Enter'
+ expect(page).to have_content 'You have been signed in successfully.'
+ end
- expect(page).to have_content 'You have been signed in successfully.'
+ scenario 'Sign in with username' do
+ create(:user, username: '👻👽👾🤖', email: 'ash@nostromo.dev', password: 'xenomorph')
+
+ visit '/'
+ click_link 'Sign in'
+ fill_in 'user_login', with: '👻👽👾🤖'
+ fill_in 'user_password', with: 'xenomorph'
+ click_button 'Enter'
+
+ expect(page).to have_content 'You have been signed in successfully.'
+ end
+
+ scenario 'Avoid username-email collisions' do
+ u1 = create(:user, username: 'Spidey', email: 'peter@nyc.dev', password: 'greatpower')
+ u2 = create(:user, username: 'peter@nyc.dev', email: 'venom@nyc.dev', password: 'symbiote')
+
+ visit '/'
+ click_link 'Sign in'
+ fill_in 'user_login', with: 'peter@nyc.dev'
+ fill_in 'user_password', with: 'greatpower'
+ click_button 'Enter'
+
+ expect(page).to have_content 'You have been signed in successfully.'
+
+ visit account_path
+
+ expect(page).to have_link 'My activity', href: user_path(u1)
+
+ visit '/'
+ click_link 'Sign out'
+
+ expect(page).to have_content 'You have been signed out successfully.'
+
+ click_link 'Sign in'
+ fill_in 'user_login', with: 'peter@nyc.dev'
+ fill_in 'user_password', with: 'symbiote'
+ click_button 'Enter'
+
+ expect(page).to_not have_content 'You have been signed in successfully.'
+ expect(page).to have_content 'Invalid login or password.'
+
+ fill_in 'user_login', with: 'venom@nyc.dev'
+ fill_in 'user_password', with: 'symbiote'
+ click_button 'Enter'
+
+ expect(page).to have_content 'You have been signed in successfully.'
+
+ visit account_path
+
+ expect(page).to have_link 'My activity', href: user_path(u2)
+ end
end
end
diff --git a/spec/features/welcome_spec.rb b/spec/features/welcome_spec.rb
index 73cd65f5c..ce06befcc 100644
--- a/spec/features/welcome_spec.rb
+++ b/spec/features/welcome_spec.rb
@@ -18,7 +18,7 @@ feature "Welcome screen" do
visit email_path(email_verification_token: encrypted)
- fill_in 'user_email', with: user.email
+ fill_in 'user_login', with: user.email
fill_in 'user_password', with: user.password
click_button 'Enter'
diff --git a/spec/support/common_actions.rb b/spec/support/common_actions.rb
index e0fdfe425..327943931 100644
--- a/spec/support/common_actions.rb
+++ b/spec/support/common_actions.rb
@@ -18,7 +18,7 @@ module CommonActions
visit root_path
click_link 'Sign in'
- fill_in 'user_email', with: user.email
+ fill_in 'user_login', with: user.email
fill_in 'user_password', with: user.password
click_button 'Enter'