From 4c7081c2e3bc6f4462337ed401306a4b71709556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 24 Nov 2009 18:02:36 -0200 Subject: [PATCH] More Datamapper compatibility. --- lib/devise/models/authenticatable.rb | 11 ++++++++--- lib/devise/models/confirmable.rb | 2 +- lib/devise/models/recoverable.rb | 2 +- lib/devise/models/rememberable.rb | 2 +- lib/devise/orm/data_mapper.rb | 9 +++++++++ test/integration/confirmable_test.rb | 3 ++- test/models/confirmable_test.rb | 2 +- test/models/recoverable_test.rb | 5 +++++ test/rails_app/app/models/user.rb | 1 + 9 files changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/devise/models/authenticatable.rb b/lib/devise/models/authenticatable.rb index 64692e20..a37043ca 100644 --- a/lib/devise/models/authenticatable.rb +++ b/lib/devise/models/authenticatable.rb @@ -104,16 +104,21 @@ module Devise end # Contains the logic used in authentication. Overwritten by other devise modules. - # def valid_for_authentication(resource, attributes) resource if resource.valid_password?(attributes[:password]) end + # Do not rely on find_or_initialize_by_attribute since they do not work on most ORMs. + def find_or_initialize_by(attribute, value) + conditions = { attribute => value } + record = find(:first, :conditions => conditions) unless value.blank? + record || new.tap { |r| r.send(:"#{attribute}=", value) } + end + # Attempt to find a user by it's email. If not user is found, returns a # new user with an email not found error. def find_or_initialize_with_error_by_email(email) - attributes = { :email => email } - record = find(:first, :conditions => attributes) || new(attributes) + record = find_or_initialize_by(:email, email) record.errors.add(:email, :not_found, :default => 'not found') if record.new_record? record end diff --git a/lib/devise/models/confirmable.rb b/lib/devise/models/confirmable.rb index 99c4262c..dde508a3 100644 --- a/lib/devise/models/confirmable.rb +++ b/lib/devise/models/confirmable.rb @@ -138,7 +138,7 @@ module Devise # If the user is already confirmed, create an error for the user # Options must have the confirmation_token def confirm!(attributes={}) - confirmable = find_or_initialize_by_confirmation_token(attributes[:confirmation_token]) + confirmable = find_or_initialize_by(:confirmation_token, attributes[:confirmation_token]) if confirmable.new_record? confirmable.errors.add(:confirmation_token, :invalid) else diff --git a/lib/devise/models/recoverable.rb b/lib/devise/models/recoverable.rb index 5be2f55e..97f9326d 100644 --- a/lib/devise/models/recoverable.rb +++ b/lib/devise/models/recoverable.rb @@ -75,7 +75,7 @@ module Devise # containing an error in reset_password_token attribute. # Attributes must contain reset_password_token, password and confirmation def reset_password!(attributes={}) - recoverable = find_or_initialize_by_reset_password_token(attributes[:reset_password_token]) + recoverable = find_or_initialize_by(:reset_password_token, attributes[:reset_password_token]) if recoverable.new_record? recoverable.errors.add(:reset_password_token, :invalid) else diff --git a/lib/devise/models/rememberable.rb b/lib/devise/models/rememberable.rb index 65babd67..7b2ea6ca 100644 --- a/lib/devise/models/rememberable.rb +++ b/lib/devise/models/rememberable.rb @@ -82,7 +82,7 @@ module Devise # Recreate the user based on the stored cookie def serialize_from_cookie(cookie) rememberable_id, remember_token = cookie.split('::') - rememberable = find_by_id(rememberable_id) if rememberable_id + rememberable = find(:first, :conditions => { :id => rememberable_id }) if rememberable_id rememberable if rememberable.try(:valid_remember_token?, remember_token) end diff --git a/lib/devise/orm/data_mapper.rb b/lib/devise/orm/data_mapper.rb index 65dd08b2..19a8404c 100644 --- a/lib/devise/orm/data_mapper.rb +++ b/lib/devise/orm/data_mapper.rb @@ -39,6 +39,15 @@ module Devise end end + # In Datamapper, we need to call save! if we don't want to execute callbacks. + def save(flag=nil) + if flag == false + save! + else + super() + end + end + # Tell how to apply schema methods. This automatically maps :limit to # :length and :null to :nullable. def apply_schema(name, type, options={}) diff --git a/test/integration/confirmable_test.rb b/test/integration/confirmable_test.rb index f9070296..3e5004d2 100644 --- a/test/integration/confirmable_test.rb +++ b/test/integration/confirmable_test.rb @@ -43,7 +43,8 @@ class ConfirmationTest < ActionController::IntegrationTest end test 'user already confirmed user should not be able to confirm the account again' do - user = create_user + user = create_user(:confirm => false) + user.update_attribute(:confirmed_at, Time.now) visit_user_confirmation_with_token(user.confirmation_token) assert_template 'confirmations/new' diff --git a/test/models/confirmable_test.rb b/test/models/confirmable_test.rb index 723d855e..71762ad1 100644 --- a/test/models/confirmable_test.rb +++ b/test/models/confirmable_test.rb @@ -81,7 +81,7 @@ class ConfirmableTest < ActiveSupport::TestCase test 'should generate errors for a user email if user is already confirmed' do user = create_user - user.confirm! + user.update_attribute(:confirmed_at, Time.now) confirmed_user = User.confirm!(:confirmation_token => user.confirmation_token) assert confirmed_user.confirmed? assert confirmed_user.errors[:email] diff --git a/test/models/recoverable_test.rb b/test/models/recoverable_test.rb index d9c5808d..ff20e7d2 100644 --- a/test/models/recoverable_test.rb +++ b/test/models/recoverable_test.rb @@ -109,6 +109,8 @@ class RecoverableTest < ActiveSupport::TestCase test 'should find a user to reset it\'s password based on reset_password_token' do user = create_user + user.send :generate_reset_password_token! + reset_password_user = User.reset_password!(:reset_password_token => user.reset_password_token) assert_not_nil reset_password_user assert_equal reset_password_user, user @@ -129,12 +131,15 @@ class RecoverableTest < ActiveSupport::TestCase test 'should reset successfully user password given the new password and confirmation' do user = create_user old_password = user.password + user.send :generate_reset_password_token! + reset_password_user = User.reset_password!( :reset_password_token => user.reset_password_token, :password => 'new_password', :password_confirmation => 'new_password' ) user.reload + assert_not user.valid_password?(old_password) assert user.valid_password?('new_password') end diff --git a/test/rails_app/app/models/user.rb b/test/rails_app/app/models/user.rb index 86841020..781fa145 100644 --- a/test/rails_app/app/models/user.rb +++ b/test/rails_app/app/models/user.rb @@ -1,3 +1,4 @@ class User < ActiveRecord::Base devise :all + attr_accessible :username, :email, :password, :password_confirmation end