From 15c6ed127faa78c62c4b0ba898001ae8002a10c7 Mon Sep 17 00:00:00 2001 From: chrisbr Date: Mon, 3 Nov 2014 15:25:33 +0100 Subject: [PATCH] Implements username authentication It's now possible to login with either username or email That's necessary to be backward compatible for iChain login --- app/controllers/registrations_controller.rb | 4 +-- app/models/user.rb | 18 +++++++++++- app/views/devise/registrations/edit.html.haml | 1 + app/views/devise/registrations/new.html.haml | 1 + app/views/devise/sessions/new.html.haml | 2 +- config/initializers/devise.rb | 2 +- .../20141103132913_add_username_to_users.rb | 6 ++++ db/schema.rb | 28 ++++++++++--------- 8 files changed, 44 insertions(+), 18 deletions(-) create mode 100644 db/migrate/20141103132913_add_username_to_users.rb diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index e19a0a18..6fe533fa 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 745df91b..36d1d651 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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 diff --git a/app/views/devise/registrations/edit.html.haml b/app/views/devise/registrations/edit.html.haml index b7714d18..68b24eb4 100644 --- a/app/views/devise/registrations/edit.html.haml +++ b/app/views/devise/registrations/edit.html.haml @@ -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'} diff --git a/app/views/devise/registrations/new.html.haml b/app/views/devise/registrations/new.html.haml index 233d62f2..3d458dd6 100644 --- a/app/views/devise/registrations/new.html.haml +++ b/app/views/devise/registrations/new.html.haml @@ -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 diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml index 11f55860..8988d9f8 100644 --- a/app/views/devise/sessions/new.html.haml +++ b/app/views/devise/sessions/new.html.haml @@ -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 diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 7b9ecaa4..11738571 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -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 diff --git a/db/migrate/20141103132913_add_username_to_users.rb b/db/migrate/20141103132913_add_username_to_users.rb new file mode 100644 index 00000000..59cd8591 --- /dev/null +++ b/db/migrate/20141103132913_add_username_to_users.rb @@ -0,0 +1,6 @@ +class AddUsernameToUsers < ActiveRecord::Migration + def change + add_column :users, :username, :string + add_index :users, :username, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index d2451810..8e7f4675 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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"