As a de-facto standard, we all using Devise for login in our Rails application and will use the Lockable module to lock users after a particular number of failed attempts.
From Devise’s source code and the configuration option
config.maximum_attempts = 20
One possible way is to monkey-patch the Devise code that you linked to, where
attempts_exceeded? is defined. Here’s a guess at what needs to be overridden:
module Devise::Models::Lockable # assumes that the User model has a `superadmin` relation # that has a `maximum_attempts` attribute def attempts_exceeded? self.failed_attempts >= self.superadmin.maximum_attempts end def last_attempt? self.failed_attempts == self.superadmin.maximum_attempts - 1 end end
This should work, but it would mean that whenever you update Devise, there is a risk of related code breaking, with unknown consequences. So you would have to review the changes to Devise before every update. And if you are discouraged from updating Devise because of this, that may eventually cause security problems if you are too slow to update to a version of Devise with a fixed security problem. So beware of those possible problems.
A safer way that requires more work up-front is to lock the user manually from your own code. The documentation for
Devise::Models::Lockable mentions a public method
lock_access! that locks the user when you call it. You can set the global
config.maximum_attempts to some really high value such as 25. Then, in some callback on the model (I’m not sure which callback), call a method
lock_access_based_on_superadmin_limit! that calls
lock_access! if necessary according to your custom rules. The following definition is adapted from part of Devise’s
class User # … def lock_access_based_on_superadmin_limit! if failed_attempts >= superadmin.maximum_attempts lock_access! unless access_locked? end end end