diff --git a/CHANGELOG.md b/CHANGELOG.md index a84d5a2196..d8b9490dc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### Future + + * Remove `orm_adapter` dependency. Devise now implements its own ORM-specific finders in `Devise::Orm`. [#5823](https://github.com/heartcombo/devise/pull/5823) + ### Unreleased * enhancements diff --git a/Gemfile.lock b/Gemfile.lock index bdf09fcccb..a4d960b06c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,7 +13,6 @@ PATH specs: devise (5.0.1) bcrypt (~> 3.0) - orm_adapter (~> 0.1) railties (>= 7.0) responders warden (~> 1.2.3) @@ -187,7 +186,6 @@ GEM rack-openid (~> 1.4) ruby-openid (~> 2.1, >= 2.1.8) version_gem (~> 1.1, >= 1.1.8) - orm_adapter (0.5.0) ostruct (0.6.3) pp (0.6.3) prettyprint diff --git a/app/controllers/devise/registrations_controller.rb b/app/controllers/devise/registrations_controller.rb index 79e2b0e81c..00fb06749a 100644 --- a/app/controllers/devise/registrations_controller.rb +++ b/app/controllers/devise/registrations_controller.rb @@ -44,7 +44,7 @@ def edit # We need to use a copy of the resource because we don't want to change # the current user in place. def update - self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key) + self.resource = resource_class.devise_find!(send(:"current_#{resource_name}").to_key) prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email) resource_updated = update_resource(resource, account_update_params) diff --git a/devise.gemspec b/devise.gemspec index 1caa6aeb39..bcdad24ff8 100644 --- a/devise.gemspec +++ b/devise.gemspec @@ -28,7 +28,6 @@ Gem::Specification.new do |s| s.required_ruby_version = '>= 2.7.0' s.add_dependency("warden", "~> 1.2.3") - s.add_dependency("orm_adapter", "~> 0.1") s.add_dependency("bcrypt", "~> 3.0") s.add_dependency("railties", ">= 7.0") s.add_dependency("responders") diff --git a/lib/devise.rb b/lib/devise.rb index 8e0c85e77d..b46342d35b 100644 --- a/lib/devise.rb +++ b/lib/devise.rb @@ -3,7 +3,6 @@ require 'rails' require 'active_support/core_ext/numeric/time' require 'active_support/dependencies' -require 'orm_adapter' require 'set' require 'securerandom' require 'responders' diff --git a/lib/devise/models/authenticatable.rb b/lib/devise/models/authenticatable.rb index df964537ea..fdeea649c5 100644 --- a/lib/devise/models/authenticatable.rb +++ b/lib/devise/models/authenticatable.rb @@ -227,7 +227,7 @@ def serialize_into_session(record) end def serialize_from_session(key, salt) - record = to_adapter.get(key) + record = devise_find(key) record if record && record.authenticatable_salt == salt end @@ -265,7 +265,7 @@ def find_for_authentication(tainted_conditions) end def find_first_by_auth_conditions(tainted_conditions, opts = {}) - to_adapter.find_first(devise_parameter_filter.filter(tainted_conditions).merge(opts)) + devise_find_by(devise_parameter_filter.filter(tainted_conditions).merge(opts)) end # Find or initialize a record setting an error if it can't be found. diff --git a/lib/devise/models/recoverable.rb b/lib/devise/models/recoverable.rb index b17c42aae6..c04f1d7e62 100644 --- a/lib/devise/models/recoverable.rb +++ b/lib/devise/models/recoverable.rb @@ -113,7 +113,7 @@ module ClassMethods # If a user is not found, return nil def with_reset_password_token(token) reset_password_token = Devise.token_generator.digest(self, :reset_password_token, token) - to_adapter.find_first(reset_password_token: reset_password_token) + devise_find_by(reset_password_token: reset_password_token) end # Attempt to find a user by its email. If a record is found, send new diff --git a/lib/devise/models/rememberable.rb b/lib/devise/models/rememberable.rb index a66979ad59..e9e3052a81 100644 --- a/lib/devise/models/rememberable.rb +++ b/lib/devise/models/rememberable.rb @@ -139,7 +139,7 @@ def serialize_into_cookie(record) def serialize_from_cookie(*args) id, token, generated_at = *args - record = to_adapter.get(id) + record = devise_find(id) record if record && record.remember_me?(token, generated_at) end @@ -147,7 +147,7 @@ def serialize_from_cookie(*args) def remember_token #:nodoc: loop do token = Devise.friendly_token - break token unless to_adapter.find_first({ remember_token: token }) + break token unless devise_find_by(remember_token: token) end end diff --git a/lib/devise/orm.rb b/lib/devise/orm.rb index 3f3ac86db7..ca0dd848ee 100644 --- a/lib/devise/orm.rb +++ b/lib/devise/orm.rb @@ -8,13 +8,47 @@ def self.active_record?(model) def self.included(model) if Devise::Orm.active_record?(model) - model.include DirtyTrackingActiveRecordMethods + model.include ActiveRecordDirtyTracking + model.extend ActiveRecordFinders else - model.include DirtyTrackingMongoidMethods + model.include MongoidDirtyTracking + model.extend MongoidFinders end end - module DirtyTrackingActiveRecordMethods + module ActiveRecordFinders + def devise_find(id) + id = id.first if id.is_a?(Array) + find_by(id: id) + end + + def devise_find!(id) + id = id.first if id.is_a?(Array) + find(id) + end + + def devise_find_by(conditions) + find_by(conditions) + end + end + + module MongoidFinders + def devise_find(id) + id = id.first if id.is_a?(Array) + where(id: id).first + end + + def devise_find!(id) + id = id.first if id.is_a?(Array) + find(id) + end + + def devise_find_by(conditions) + where(conditions).first + end + end + + module ActiveRecordDirtyTracking def devise_email_before_last_save email_before_last_save end @@ -40,7 +74,7 @@ def devise_respond_to_and_will_save_change_to_attribute?(attribute) end end - module DirtyTrackingMongoidMethods + module MongoidDirtyTracking def devise_email_before_last_save respond_to?(:email_previously_was) ? email_previously_was : email_was end diff --git a/lib/devise/orm/active_record.rb b/lib/devise/orm/active_record.rb index 0fecf64e3f..419e03b8a9 100644 --- a/lib/devise/orm/active_record.rb +++ b/lib/devise/orm/active_record.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'orm_adapter/adapters/active_record' - ActiveSupport.on_load(:active_record) do extend Devise::Models end diff --git a/lib/devise/orm/mongoid.rb b/lib/devise/orm/mongoid.rb index 034501eff4..e10e13cd63 100644 --- a/lib/devise/orm/mongoid.rb +++ b/lib/devise/orm/mongoid.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true ActiveSupport.on_load(:mongoid) do - require 'orm_adapter/adapters/mongoid' - Mongoid::Document::ClassMethods.send :include, Devise::Models end diff --git a/lib/devise/token_generator.rb b/lib/devise/token_generator.rb index 9eb74a046a..7b573ccfd6 100644 --- a/lib/devise/token_generator.rb +++ b/lib/devise/token_generator.rb @@ -19,7 +19,7 @@ def generate(klass, column) loop do raw = Devise.friendly_token enc = OpenSSL::HMAC.hexdigest(@digest, key, raw) - break [raw, enc] unless klass.to_adapter.find_first({ column => enc }) + break [raw, enc] unless klass.devise_find_by(column => enc) end end diff --git a/test/integration/registerable_test.rb b/test/integration/registerable_test.rb index 9289ac6af1..875956f797 100644 --- a/test/integration/registerable_test.rb +++ b/test/integration/registerable_test.rb @@ -19,7 +19,7 @@ class RegistrationTest < Devise::IntegrationTest assert warden.authenticated?(:admin) assert_current_url "/admin_area/home" - admin = Admin.to_adapter.find_first(order: [:id, :desc]) + admin = Admin.order(id: :desc).first assert_equal 'new_user@test.com', admin.email end @@ -68,7 +68,7 @@ def user_sign_up assert_not warden.authenticated?(:user) - user = User.to_adapter.find_first(order: [:id, :desc]) + user = User.order(id: :desc).first assert_equal 'new_user@test.com', user.email assert_not user.confirmed? end @@ -110,7 +110,7 @@ def user_sign_up assert_contain "Email is invalid" assert_contain %r{Password confirmation doesn['’]t match Password} assert_contain "2 errors prohibited" - assert_nil User.to_adapter.find_first + assert_nil User.first assert_not warden.authenticated?(:user) end @@ -154,7 +154,7 @@ def user_sign_up assert_current_url '/' assert_contain 'Your account has been updated successfully.' - assert_equal "user.new@example.com", User.to_adapter.find_first.email + assert_equal "user.new@example.com", User.first.email end test 'a signed in user should still be able to use the website after changing their password' do @@ -216,7 +216,7 @@ def user_sign_up assert_contain 'Your account has been updated successfully.' assert warden.authenticated?(:user) - assert_equal "user.new@example.com", User.to_adapter.find_first.email + assert_equal "user.new@example.com", User.first.email end end @@ -232,7 +232,7 @@ def user_sign_up assert_contain 'user@test.com' assert_have_selector 'form input[value="user.new@example.com"]' - assert_equal "user@test.com", User.to_adapter.find_first.email + assert_equal "user@test.com", User.first.email end test 'a signed in user should be able to edit their password' do @@ -247,7 +247,7 @@ def user_sign_up assert_current_url '/' assert_contain 'Your account has been updated successfully.' - assert User.to_adapter.find_first.valid_password?('pass1234') + assert User.first.valid_password?('pass1234') end test 'a signed in user should not be able to edit their password with invalid confirmation' do @@ -260,7 +260,7 @@ def user_sign_up click_button 'Update' assert_contain %r{Password confirmation doesn['’]t match Password} - assert_not User.to_adapter.find_first.valid_password?('pas123') + assert_not User.first.valid_password?('pas123') end test 'a signed in user should see a warning about minimum password length' do @@ -276,7 +276,7 @@ def user_sign_up click_button "Cancel my account" assert_contain "Bye! Your account has been successfully cancelled. We hope to see you again soon." - assert_empty User.to_adapter.find_all + assert_empty User.all end test 'a user should be able to cancel sign up by deleting data in the session' do @@ -303,7 +303,7 @@ def user_sign_up assert_response :success assert_includes response.body, '{"admin":{' - admin = Admin.to_adapter.find_first(order: [:id, :desc]) + admin = Admin.order(id: :desc).first assert_equal 'new_user@test.com', admin.email end @@ -312,7 +312,7 @@ def user_sign_up assert_response :success assert_includes response.body, '{"user":{' - user = User.to_adapter.find_first(order: [:id, :desc]) + user = User.order(id: :desc).first assert_equal 'new_user@test.com', user.email end @@ -340,7 +340,7 @@ def user_sign_up sign_in_as_user delete user_registration_path(format: 'json') assert_response :success - assert_equal 0, User.to_adapter.find_all.size + assert_equal 0, User.all.size end end @@ -355,7 +355,7 @@ class ReconfirmableRegistrationTest < Devise::IntegrationTest assert_current_url '/admin_area/home' assert_contain 'but we need to verify your new email address' - assert_equal 'admin.new@example.com', Admin.to_adapter.find_first.unconfirmed_email + assert_equal 'admin.new@example.com', Admin.first.unconfirmed_email get edit_admin_registration_path assert_contain 'Currently waiting confirmation for: admin.new@example.com' @@ -373,7 +373,7 @@ class ReconfirmableRegistrationTest < Devise::IntegrationTest assert_current_url '/admin_area/home' assert_contain 'Your account has been updated successfully.' - assert Admin.to_adapter.find_first.valid_password?('pas123') + assert Admin.first.valid_password?('pas123') end test 'a signed in admin should not see a reconfirmation message if they did not change their email, despite having an unconfirmed email' do @@ -393,7 +393,7 @@ class ReconfirmableRegistrationTest < Devise::IntegrationTest assert_current_url '/admin_area/home' assert_contain 'Your account has been updated successfully.' - assert_equal "admin.new@example.com", Admin.to_adapter.find_first.unconfirmed_email - assert Admin.to_adapter.find_first.valid_password?('pas123') + assert_equal "admin.new@example.com", Admin.first.unconfirmed_email + assert Admin.first.valid_password?('pas123') end end diff --git a/test/models/rememberable_test.rb b/test/models/rememberable_test.rb index 8b83172120..1e83b50f27 100644 --- a/test/models/rememberable_test.rb +++ b/test/models/rememberable_test.rb @@ -21,7 +21,7 @@ def create_resource test 'remember_me should not generate a new token if valid token exists' do user = create_user user.singleton_class.send(:attr_accessor, :remember_token) - User.to_adapter.expects(:find_first).returns(nil) + User.expects(:devise_find_by).returns(nil) user.remember_me! existing_token = user.remember_token @@ -40,7 +40,7 @@ def create_resource test 'can generate remember token' do user = create_user user.singleton_class.send(:attr_accessor, :remember_token) - User.to_adapter.expects(:find_first).returns(nil) + User.expects(:devise_find_by).returns(nil) user.remember_me! assert user.remember_token end diff --git a/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb b/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb index f5327fbd7b..f39cc59d07 100644 --- a/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb +++ b/test/rails_app/app/controllers/users/omniauth_callbacks_controller.rb @@ -8,7 +8,7 @@ def facebook end def sign_in_facebook - user = User.to_adapter.find_first(email: 'user@test.com') + user = User.devise_find_by(email: 'user@test.com') user.remember_me = true sign_in user render body: ""