Skip to content

Commit

Permalink
Make PasswordsController#create case-insensitive
Browse files Browse the repository at this point in the history
* Centralize email normalization logic in `User.normalize_email`.
* Implement `User.find_by_normalized_email`.
  • Loading branch information
agraves authored and Dan Croak committed Feb 22, 2013
1 parent 2999c25 commit 028a1cd
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 6 deletions.
2 changes: 1 addition & 1 deletion app/controllers/clearance/passwords_controller.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def find_user_by_id_and_confirmation_token
end end


def find_user_for_create def find_user_for_create
Clearance.configuration.user_model.find_by_email params[:password][:email] Clearance.configuration.user_model.find_by_normalized_email params[:password][:email]
end end


def find_user_for_edit def find_user_for_edit
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/3.0.20.gemfile.lock
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,5 @@
PATH PATH
remote: /Users/jferris/Source/clearance remote: /Users/croaky/dev/clearance
specs: specs:
clearance (1.0.0.rc4) clearance (1.0.0.rc4)
bcrypt-ruby bcrypt-ruby
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/3.1.11.gemfile.lock
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,5 @@
PATH PATH
remote: /Users/jferris/Source/clearance remote: /Users/croaky/dev/clearance
specs: specs:
clearance (1.0.0.rc4) clearance (1.0.0.rc4)
bcrypt-ruby bcrypt-ruby
Expand Down
2 changes: 1 addition & 1 deletion gemfiles/3.2.12.gemfile.lock
Original file line number Original file line Diff line number Diff line change
@@ -1,5 +1,5 @@
PATH PATH
remote: /Users/jferris/Source/clearance remote: /Users/croaky/dev/clearance
specs: specs:
clearance (1.0.0.rc4) clearance (1.0.0.rc4)
bcrypt-ruby bcrypt-ruby
Expand Down
12 changes: 10 additions & 2 deletions lib/clearance/user.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@ module User


module ClassMethods module ClassMethods
def authenticate(email, password) def authenticate(email, password)
if user = find_by_email(email.to_s.downcase) if user = find_by_normalized_email(email)
if user.authenticated? password if user.authenticated? password
return user return user
end end
end end
end end

def find_by_normalized_email(email)
find_by_email normalize_email(email)
end

def normalize_email(email)
email.to_s.downcase.gsub(/\s+/, "")
end
end end


module Validations module Validations
Expand Down Expand Up @@ -70,7 +78,7 @@ def update_password(new_password)
private private


def normalize_email def normalize_email
self.email = email.to_s.downcase.gsub(/\s+/, "") self.email = self.class.normalize_email(email)
end end


def email_optional? def email_optional?
Expand Down
14 changes: 14 additions & 0 deletions spec/controllers/passwords_controller_spec.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@
it { should respond_with(:success) } it { should respond_with(:success) }
end end


describe 'with correct email address capitalized differently' do
before do
ActionMailer::Base.deliveries.clear
post :create, :password => { :email => @user.email.upcase }
end

it 'should generate a token for the change your password email' do
@user.reload.confirmation_token.should_not be_nil
end

it { should have_sent_email.with_subject(/change your password/i) }
it { should respond_with(:success) }
end

describe 'with incorrect email address' do describe 'with incorrect email address' do
before do before do
email = 'user1@example.com' email = 'user1@example.com'
Expand Down
16 changes: 16 additions & 0 deletions spec/models/user_spec.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@
should_not be should_not be
@user.should_not be_authenticated('bad password') @user.should_not be_authenticated('bad password')
end end

it 'is retrieved via a case-insensitive search' do
(Clearance.configuration.user_model.find_by_normalized_email(@user.email.upcase)).
should be
@user
end
end end


describe 'when resetting authentication with reset_remember_token!' do describe 'when resetting authentication with reset_remember_token!' do
Expand Down Expand Up @@ -175,6 +181,16 @@ def password_optional?
end end
end end


describe 'email address normalization' do
let(:email) { 'Jo hn.Do e @exa mp le.c om' }

it 'downcases the address and strips spaces' do
(Clearance.configuration.user_model.normalize_email(email)).
should be
'john.doe@example.com'
end
end

describe 'the password setter on a User' do describe 'the password setter on a User' do
let(:password) { 'a-password' } let(:password) { 'a-password' }
before { subject.send(:password=, password) } before { subject.send(:password=, password) }
Expand Down

0 comments on commit 028a1cd

Please sign in to comment.