Find file History
tegon Make `#increment_failed_attempts` concurrency safe (#4996)
As reported in #4981, the method `#increment_failed_attempts` of `Devise::Models::Lockable` was
not concurrency safe. The increment operation was being done in two steps: first the value was read from the database, and then incremented by 1. This may result in wrong values if two requests try to update the value concurrently. For example:

```
Browser1 -------> Read `failed_attempts` from DB (1) -------> Increment `failed_attempts` to 2
    Browser2 -------> Read `failed_attempts` from DB (1) -------> Increment `failed_attempts` to 2
```

In the example above, `failed_attempts` should have been set to 3, but it will be set to 2. 

This commit handles this case by calling `ActiveRecord::CounterCache.increment_counter` method, which will do both steps at once, reading the value straight from the database.

This commit also adds a `ActiveRecord::AttributeMethods::Dirty#reload` call to ensure that the application gets the updated value - i.e. that other request might have updated. 
Although this does not ensure that the value is in fact the most recent one - other request could've updated it after the `reload` call - it seems good enough for this implementation. 
Even if a request does not locks the account because it has a stale value, the next one - that updated that value - will do it. That's why we decided not to use a pessimistic lock here.

Closes #4981.
Latest commit 6270394 Dec 28, 2018
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
controllers Issue 4895: Add `after_database_authentication` callback after sign_i… Nov 22, 2018
generators Primary key type in migration template (#4426) Dec 23, 2017
helpers Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017
integration Add an option to not automatically sign in a user after changing a pa… Dec 28, 2018
mailers Use `update` instead of `update_attributes` Mar 29, 2018
models Make `#increment_failed_attempts` concurrency safe (#4996) Dec 28, 2018
omniauth Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017
orm Test on Rails 5.2.0.rc1 (#4711) Feb 22, 2018
rails_app Add an option to not automatically sign in a user after changing a pa… Dec 28, 2018
support Ensure Devise isn't performing model validations Mar 14, 2018
test Preserve content_type for unauthenticated tests Feb 26, 2018
delegator_test.rb Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017
devise_test.rb Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017
failure_app_test.rb Only flash if the request object that is loaded supports it (#4950) Nov 13, 2018
mapping_test.rb Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017
models_test.rb Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017
parameter_sanitizer_test.rb Fix error when params is not a hash May 9, 2018
rails_test.rb Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017
routes_test.rb Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017
secret_key_finder_test.rb find auto-generated secret_key_base in development (#4869) May 14, 2018
test_helper.rb Fix corner case when confirmation_sent_at is equal to 0.days.ago (#4529) Dec 4, 2018
test_models.rb Add the frozen_string_literal pragma comment to all Ruby files. (#4725) Dec 21, 2017