Implements username authentication

It's now possible to login with either username or email
That's necessary to be backward compatible for iChain login
This commit is contained in:
chrisbr 2014-11-03 15:25:33 +01:00
parent aeb23ba914
commit 15c6ed127f
8 changed files with 44 additions and 18 deletions

View file

@ -68,11 +68,11 @@ class RegistrationsController < Devise::RegistrationsController
devise_parameter_sanitizer.for(:account_update) do |u|
u.
permit(:email, :password, :password_confirmation, :current_password, :name, :biography,
:nickname, :affiliation)
:nickname, :affiliation, :username)
end
devise_parameter_sanitizer.for(:sign_up) do |u|
u.
permit(:email, :password, :password_confirmation, :name)
permit(:email, :password, :password_confirmation, :name, :username)
end
end
end

View file

@ -17,7 +17,9 @@ class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation, :remember_me, :role_id, :role_ids,
:name, :email_public, :biography, :nickname, :affiliation, :is_admin,
:tshirt, :mobile, :volunteer_experience, :languages
:tshirt, :mobile, :volunteer_experience, :languages, :username, :login
attr_accessor :login
has_many :event_users, dependent: :destroy
has_many :events, -> { uniq }, through: :event_users
@ -31,6 +33,11 @@ class User < ActiveRecord::Base
validates :name, presence: true
validates :username,
:uniqueness => {
:case_sensitive => false
}
# Returns the ticket purchased ticket
# ====Returns
# * +TicketUser::ActiveRecord_Relation+ -> user
@ -38,6 +45,15 @@ class User < ActiveRecord::Base
ticket_purchases.where(ticket_id: id).first
end
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
else
where(conditions).first
end
end
# Searches for user based on email. Returns found user or new user.
# ====Returns
# * +User::ActiveRecord_Relation+ -> user

View file

@ -27,6 +27,7 @@
= render 'devise/shared/openid'
= f.inputs name: 'Account' do
= f.input :username, required: false, input_html: {autocomplete: "off"}
= f.input :email, required: false, input_html: {autocomplete: "off"}
= f.input :password, hint: "(Leave blank if you don't want to change it)", input_html: {autocomplete: 'off'}
= f.input :password_confirmation, input_html: {autocomplete: 'off'}

View file

@ -6,6 +6,7 @@
Sign Up
.panel-body
= semantic_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
= f.input :username, required: true
= f.input :email
= f.input :name, required: true
= f.input :password

View file

@ -6,7 +6,7 @@
Sign In
.panel-body
= semantic_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
= f.input :email
= f.input :login
= f.input :password
- if devise_mapping.rememberable?
%p.text-right.small

View file

@ -38,7 +38,7 @@ Devise.setup do |config|
# session. If you need permissions, you should implement that in a before filter.
# You can also supply a hash where the value is a boolean determining whether
# or not authentication should be aborted when the value is not present.
# config.authentication_keys = [ :email ]
config.authentication_keys = [ :login ]
# Configure parameters from the request object used for authentication. Each entry
# given should be a request method and it will automatically be passed to the

View file

@ -0,0 +1,6 @@
class AddUsernameToUsers < ActiveRecord::Migration
def change
add_column :users, :username, :string
add_index :users, :username, unique: true
end
end

View file

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20140825093132) do
ActiveRecord::Schema.define(version: 20141103132913) do
create_table "ahoy_events", force: true do |t|
t.uuid "visit_id"
@ -84,13 +84,13 @@ ActiveRecord::Schema.define(version: 20140825093132) do
end
create_table "conferences", force: true do |t|
t.string "guid", null: false
t.string "title", null: false
t.string "short_title", null: false
t.string "timezone", null: false
t.string "guid", null: false
t.string "title", null: false
t.string "short_title", null: false
t.string "timezone", null: false
t.string "html_export_path"
t.date "start_date", null: false
t.date "end_date", null: false
t.date "start_date", null: false
t.date "end_date", null: false
t.integer "venue_id"
t.datetime "created_at"
t.datetime "updated_at"
@ -98,11 +98,11 @@ ActiveRecord::Schema.define(version: 20140825093132) do
t.string "logo_content_type"
t.integer "logo_file_size"
t.datetime "logo_updated_at"
t.boolean "use_dietary_choices", default: false
t.boolean "use_dietary_choices", default: false
t.integer "revision"
t.boolean "use_vpositions", default: false
t.boolean "use_vdays", default: false
t.boolean "use_difficulty_levels", default: false
t.boolean "use_vpositions", default: false
t.boolean "use_vdays", default: false
t.boolean "use_difficulty_levels", default: false
t.boolean "use_volunteers"
t.string "color"
t.string "sponsor_email"
@ -504,11 +504,13 @@ ActiveRecord::Schema.define(version: 20140825093132) do
t.string "languages"
t.text "volunteer_experience"
t.boolean "is_admin", default: false
t.string "username"
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
add_index "users", ["username"], name: "index_users_on_username", unique: true
create_table "vchoices", force: true do |t|
t.integer "vday_id"
@ -525,8 +527,8 @@ ActiveRecord::Schema.define(version: 20140825093132) do
create_table "venues", force: true do |t|
t.string "guid"
t.text "name", limit: 255
t.text "address", limit: 255
t.text "name", limit: 255
t.text "address", limit: 255
t.string "website"
t.text "description"
t.string "offline_map_url"