Forwarding methods to private methods is deprecated and produces a
warning after Ruby 2.4.
see: https://bugs.ruby-lang.org/issues/12782
To fix this issue I'm mocking patching webrat making RailsAdatper#response
method public since Webrat::Session is delegating functions to it.
Before setting this option, our test suite was giving the following warning:
```
DEPRECATION WARNING: Leaving `ActiveRecord::ConnectionAdapters::SQLite3Adapter.represent_boolean_as_integer`
set to false is deprecated. SQLite databases have used 't' and 'f' to serialize
boolean values and must have old data converted to 1 and 0 (its native boolean
serialization) before setting this flag to true. Conversion can be accomplished
by setting up a rake task which runs
ExampleModel.where("boolean_column = 't'").update_all(boolean_column: 1)
ExampleModel.where("boolean_column = 'f'").update_all(boolean_column: 0)
for all models and all boolean columns, after which the flag must be set to
true by adding the following to your application.rb file:
Rails.application.config.active_record.sqlite3.represent_boolean_as_integer = true
(called from <top (required)> at $PATH/devise/test/rails_app/app/active_record/user.rb:5)
```
After configuring `represent_boolean_as_integer = true` as specified
above, we don't have this warning anymore.
More info:
https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html#method-c-represent_boolean_as_integer
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.
If `Confirmable#confirmation_sent_at` is equal to `0.days.ago`, then
`confirmation_period_valid?` will be deemed valid even if the setting is
configured to disable this outright. To prevent this error, we explicitly
check the configuration setting to be `0.days.ago`.
After merging https://github.com/plataformatec/devise/pull/4797, I
noticed that we had no specs for the scenarios where this method was
adding the errors to the resource. This commit adds tests to cover those
cases.
If called with a hash that has a `default` / `default_proc`
configured, `Devise::ParameterFilter` can add in missing keys
it was due to attempt to sanitise the values for.
This patch prevents this from happening, whilst also clarifying
the filtering intent of `ParamaterFilter`.
(This can also occur if NilClass has been augmented with definitions
for `strip` or `downcase`.)
Fixes#3431.
With this fix, we will try latest changes in Rails 5.2 together with standard auto-generated secret_key_base in development as a fallback.
If no specified key found, auto-generated value will be used instead.
This permits users to easily customize where the ip address
should be resolved. When fronting the application with a webserver or
load balancer, the ip address may be the server and not be the user.
E.g. consider the IP address is passed as the header: "X-Forwarded-For".
```ruby
class User
devise :trackable
protected
def extract_ip_from(request)
request.headers["X-Forwarded-For"]
end
end
```
When supporting Rails 5.2 credentials on
https://github.com/plataformatec/devise/pull/4712, we ended up breaking
apps that were upgraded to Rails 5.2 and weren't using `credentials`
to store their `secret_key_base`. See
https://github.com/plataformatec/devise/issues/4807 for more context.
To fix it, we're now checking whether the key is present before using it.
Since there weren't any automated test for this - the conditionals were
in a Rails engine initializer - I've extracted it to a new class so that
we are able to test it easily.
Fixes#4807
In Rails 4, for unauthenticated controller tests which trigger the
failure app, ensure that the simulated failure response includes a
content_type (broken in bb44d42).
This works in Rails5, which parses the content-type header on-demand,
but not in Rails4 which requires setting the response's content_type
explicitly.
Fixes#4783.
The test uses `as_json` instead of `to_json` because `to_json` does `#dup` on `options` before it reaches `#serializable_hash` and the test would pass without the fix.
* Fix missing validations on Signup
This commit fixes issue
https://github.com/plataformatec/devise/issues/4673
This removes `validate: false` from saving a record when `Trackable` is
in use.
* Add test case
* Add mongoid model
Otherwise we'd be mistakenly displaying the original email in the
message (which is the same we're sending the message to).
Also tweak the messaging a bit in this case, to show that the email "is
being changed" (the change hasn't taken effect yet).
Related to #4455.
Related to issue #4397
This hotfix adds a string coercion to new_password paramenters when
trying to reset an user's password.
Before that, when a user submitted a password recovery form with the
new_password and new_password_confirmation params as nil, Devise would
sign in the user with a success notice but without actually changing the
password.
This better indicates what the setting is for, and when it's supposed to
be triggered.
We might eventually deprecate the existing password_change on in favor
of password_changed.