Skip to content

Commit

Permalink
Allow wrapping of lockable Warden after sign-in hook
Browse files Browse the repository at this point in the history
For applications using a primary/replica multiple database setup, Rails
6's default connection switching can lead to the `Lockable` after
sign-in hook firing on `GET` requests, getting the read-only database,
and then attempting to write while zeroing out the user's failed attempts.

This change adds a customizable wrapper proc that can allow applications
to customize this behavior. For a primary/replica setup using
ActiveRecord's default connection switching, it might look like this:

```ruby
Devise.setup do |config|
  config.warden_hook_save_wrapper = Proc.new do |hook|
    ApplicationRecord.connected_to(role: :writing) do
      hook.call
    end
  end
end
```

Fix heartcombo#5264
  • Loading branch information
geoffharcourt authored and Fosco Marotto committed Feb 15, 2021
1 parent f6e8d90 commit 4009905
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 2 deletions.
3 changes: 3 additions & 0 deletions lib/devise.rb
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ module Test
mattr_accessor :sign_in_after_change_password
@@sign_in_after_change_password = true

mattr_accessor :warden_hook_save_wrapper
@@warden_hook_save_wrapper = Proc.new { |hook| hook.call }

def self.activerecord51? # :nodoc:
defined?(ActiveRecord) && ActiveRecord.gem_version >= Gem::Version.new("5.1.x")
end
Expand Down
8 changes: 6 additions & 2 deletions lib/devise/hooks/lockable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
Warden::Manager.after_set_user except: :fetch do |record, warden, options|
if record.respond_to?(:failed_attempts) && warden.authenticated?(options[:scope])
unless record.failed_attempts.to_i.zero?
record.failed_attempts = 0
record.save(validate: false)
wipe_attempts = Proc.new do
record.failed_attempts = 0
record.save(validate: false)
end

Devise.warden_hook_save_wrapper.call(wipe_attempts)
end
end
end

0 comments on commit 4009905

Please sign in to comment.