diff --git a/Gemfile.lock b/Gemfile.lock index 9a801e9e..35d71aff 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - devise (1.5.2) + devise (2.0.0.rc) bcrypt-ruby (~> 3.0) orm_adapter (~> 0.0.3) warden (~> 1.1) diff --git a/lib/devise/models/confirmable.rb b/lib/devise/models/confirmable.rb index d1d64a30..a2ab1371 100644 --- a/lib/devise/models/confirmable.rb +++ b/lib/devise/models/confirmable.rb @@ -40,15 +40,17 @@ module Devise # is already confirmed, add an error to email field. If the user is invalid # add errors def confirm! - unless_confirmed do + pending_any_confirmation do self.confirmation_token = nil self.confirmed_at = Time.now.utc - if self.class.reconfirmable + if self.class.reconfirmable && unconfirmed_email.present? @bypass_postpone = true - self.email = unconfirmed_email if unconfirmed_email.present? + self.email = unconfirmed_email self.unconfirmed_email = nil - save + + # We need to validate in such cases to enforce e-mail uniqueness + save(:validate => true) else save(:validate => false) end @@ -73,7 +75,7 @@ module Devise # Resend confirmation token. This method does not need to generate a new token. def resend_confirmation_token - unless_confirmed { send_confirmation_instructions } + pending_any_confirmation { send_confirmation_instructions } end # Overwrites active_for_authentication? for confirmation @@ -133,10 +135,9 @@ module Devise confirmation_sent_at && confirmation_sent_at.utc >= self.class.allow_unconfirmed_access_for.ago end - # Checks whether the record is confirmed or not or a new email has been added, yielding to the block - # if it's already confirmed, otherwise adds an error to email. - def unless_confirmed - unless confirmed? && !pending_reconfirmation? + # Checks whether the record requires any confirmation. + def pending_any_confirmation + if !confirmed? || pending_reconfirmation? yield else self.errors.add(:email, :already_confirmed) diff --git a/test/models/confirmable_test.rb b/test/models/confirmable_test.rb index 71fbe1c8..d0df31bb 100644 --- a/test/models/confirmable_test.rb +++ b/test/models/confirmable_test.rb @@ -238,6 +238,12 @@ class ConfirmableTest < ActiveSupport::TestCase end class ReconfirmableTest < ActiveSupport::TestCase + test 'should not worry about validations on confirm even with reconfirmable' do + admin = create_admin + admin.reset_password_token = "a" + assert admin.confirm! + end + test 'should generate confirmation token after changing email' do admin = create_admin assert admin.confirm! diff --git a/test/rails_app/lib/shared_admin.rb b/test/rails_app/lib/shared_admin.rb index 36fb5f8b..561562d7 100644 --- a/test/rails_app/lib/shared_admin.rb +++ b/test/rails_app/lib/shared_admin.rb @@ -7,6 +7,7 @@ module SharedAdmin :unlock_strategy => :time, :lock_strategy => :none, :allow_unconfirmed_access_for => 2.weeks, :reconfirmable => true + validates_length_of :reset_password_token, :minimum => 3, :allow_blank => true validates_uniqueness_of :email, :allow_blank => true, :if => :email_changed? end