This week we released the first release candidate version of Devise that is fully compatible with Rails 4, and we’re bumping its version to 3.0. This version completely drops support for Rails 3.1 and Ruby 1.8.7, only keeping compatibility with both Rails 3.2 and Rails 4, running with Ruby 1.9.3 and 2.0.
This rc version took some time to get ready, we’ve been running a rails4 branch for some time already and one of the reasons was because of the changes required to make it compatible with the new strong parameters API from Rails 4. We are aware that some people have been using this branch since Rails 4.0 beta1 with success, and we’re now inviting you to try 3.0 rc with the recent release of Rails 4.0 rc1.
Together with the 3.0 beta version, we’ve released Devise 2.2.4 with a few enhancements and bug fixes, make sure to check the changelog to see the new goodies. All changes are also included in the rc version.
Simple Form has been running a 3.0 rc version for a couple months already, fully compatible with Rails 4 as well, and today we are releasing its release candidate version. In Simple Form master we just dropped support to the 3.x Rails series, focusing our work on Rails 4 compatibility from now on, due to a series of improvements in Rails 4 regarding form helpers – but don’t worry, we will be keeping a v2.1 branch with Rails 3.2 compatibility for a while.
We have some cool plans to improve the wrappers API even further, but that’s subject for another blog post .
Responders has been around for quite some time already and we use it in most of our projects, so today we’re celebrating its 1.0 release candidate version, specially to support Rails 4.
Show For just got a new stable release, v0.2.6, with all the enhancements and bug fixes that were in master, plus a v0.3.0 rc version that adds Rails 4 support.
Mail Form also got a new 1.5 rc release with Rails 4.0 compatibility. Nothing else has changed from the current 1.4 version.
Has Scope is getting a new 0.6 rc version with Rails 4.0 compatibility, including a couple of fixes that were already present in master.
All these new releases are officially dropping support to Rails 3.0 and 3.1, and Ruby 1.8.7. We’ll keep compatibility with Rails 3.2 and 4.0 from now on, all of them on the same branches except for Simple Form which has different branches for each Rails version.
We’ve got new hot releases for you to try out with Rails 4, please give them a try and let us know if you find any issue or have any feedback.
We’d also like to specially thank everyone involved in helping us getting these projects up and running in Rails 4, without you folks that’d have never been possible.
We are very glad to announce the logos for two of our favorite Rails open source projects…
We would like to congratulate our designer, Bruna Kochi, who was able to capture the essence of each project in their logos. We will write about their design process soon!
Those projects have been in the Rails community for almost 4 years and it was about time for them to have their own visual identity! We would like to thank all contributors and users who have helped those projects to be more robust, flexible and popular!
I’d like to announce that Devise v2.2.3, v2.1.3, v2.0.5 and v1.5.4 have been released with a security patch. Upgrade immediately unless you are using PostgreSQL or SQLite3. Users of all other databases (including NoSQL ones) require immediate upgrade.
Using a specially crafted request, an attacker could trick the database type conversion code to return incorrect records. For some token values this could allow an attacker to bypass the proper checks and gain control of other accounts.
In case you are using a Devise series older than the ones listed above, recommendations are provided below back to v1.2 series. Regardless, an upgrade to more recent versions is advised.
We checked all Devise versions released in the previous two years and recommendations follows as below.
v1.5, v2.0, v2.1 and v2.2 series
You can upgrade to any of v2.2.3, v2.1.3, v2.0.5 and v1.5.4. In case an upgrade is not feasible, please add the following patch to
config/initializers/devise_patch.rb inside your Rails application:
Devise::ParamFilter.class_eval do def param_requires_string_conversion?(_value); true; end end
Please add the following patch to
config/initializers/devise_patch.rb inside your Rails application:
Devise::Models::Authenticatable::ClassMethods.class_eval do def auth_param_requires_string_conversion?(value); true; end end
Please upgrade to more recent versions.
v1.2 and v1.3 series
Not affected by this vulnerability. Please upgrade to more recent versions.
When upgrading to any of v2.2.3, v2.1.3, v2.0.5 and v1.5.4, some people may be relying on some wrong behaviour to filter data retrieved on authentication. For example, one may have writen in his model:
def find_for_authentication(conditions) conditions[:active] = true super end
The code above may no longer work and needs to be rewriten as:
def find_for_authentication(conditions) find_first_by_auth_conditions(conditions, active: true) end
Thank you notes
We would like to thank joernchen of Phenoelit for disclosing this vulnerability and working with us on a patch.
After 4 months of our last major version release, we’re releasing Devise 2.1.0, which includes several bug fixes, some new features and the removal of features deprecated on Devise 2.0. If you’re eager to do the update, please check Devise’s wiki page about Upgrading from 2.0 to 2.1. You can also check the changelog or the commits between 2.0.4 and 2.1.0.
Encrytable is now a gem
As it was only used for old encryption algorithms like sha1 or md5, we have extracted encryptable module to a separated ruby gem. So, if you’re using the encryptable module, you should only require it on your Gemfile and you’re good to go!
To allow a developer to cherry-pick which features they want to add to their models, Devise splits its behaviors into modules. One of the consequences of such splitting is that you don’t know if the persistence layer provides all fields required by the behavior. For example, the database authenticatable module requires a
encrypted_password field. If the field does not exist, you will end up getting an error during a request. Usually those fields are automatically added to the migration when you call the devise generator, but if you decide to include a module after, you can easily forget to add the new fields.
That said, in order to provide faster feedback, Devise now has a method that checks if a given class is missing any of the required fields and raises an error if so. You can call this method as follow (in case your Devise class is
We’ve implemented this feature in an agnostic way, to not depend on a specific ORM, but only to verify if the instance responds to the required fields. So even if your ORM does everything through
method_missing, you should be able to use this method (we’re relying that you also have implemented a working
respond_to?, which is strongly recommendeded when using
check_fields! is called, Devise will detect the included modules in the given class and, if there is a missing attribute, it will raise a
Devise::Models::MissingAttribute exception with a message telling you all required fields that doesn’t exist. You can easily use that method with your favorite test framework:
And then you will be able to check if your migrations have added the correct fields to your database.
A message to module maintainers
If you’re a maintainer of a Devise module, you should add a method to each of your modules called
self.required_fields(klass) that returns an array of required fields. If the method is absent, you will get a deprecation warning.
UPDATE: Fixed a class name and corrected a grammar error.
We have just released Devise 2.0. This version is not a big refactoring, nor contains stellar features, it is simply another step towards a very mature authentication library.
Over the years, we have learned from our own experience and from your feedback, how to better use Devise. We’ve made changes to improve security and also to make the library more flexible. All those changes were backwards compatible, forcing us to maintain different branches of logic in the same source code to accomodate those different scenarios. Devise 2.0 simply deprecates those old scenarios so we can clean up the code.
When you migrate to 2.0, you should get some warnings. The amount of warnings will depend on when you started using Devise. For recent applications, it should take 2 minutes to update (basically fixing up migrations and the locale file), older applications should be up to speed in 15-30 minutes. We have created a page with instructions to upgrade, be sure to read it for a smoother experience.
Finally, Devise 2.0 also includes:
- Support to the reconfirmable feature. When on, if the user changes his e-mail, he needs to confirm the new e-mail address before the e-mail is finally updated;
- We got rid of
t.database_authenticatableand friends in migrations in favor of explicit code;
- Better support to engines. For example, we now support
config.parent_controllerwhich you can set to something different from
ApplicationController. There is a good sample engine here;
- Rails 3.2 support. The previous Devise version (v1.5) runs fine but with a few deprecation warnings, v2.0 gets rid of them;
Thanks everyone that contributed to this awesome release and, if you have any issues, please let us know in the issues tracker. Here to a better future!
We, Rails developers, have always worried about improving the performance of our test suites. Today I would like to share three quick tips we employ in our projects that can drastically speed up your test suite.
1. Reduce Devise.stretches
Add the following to your spec/test helper:
Devise.stretches = 1
Explanation: Devise uses bcrypt-ruby by default to encrypt your password. Bcrypt is one of the best choices for such job because, different from other hash libraries like MD5, SHA1, SHA2, it was designed to be slow. So if someone steals your database it will take a long time for them to crack each password in it.
That said, it is expected that Devise will also be slow during tests as many tests are generating and comparing passwords. For this reason, a very easy way to improve your test suite performance is to reduce the value in
Devise.stretches, which represents the cost taken while generating a password with bcrypt. This will make your passwords less secure, but that is ok as long as it applies only to the test environment.
Latest Devise versions already set stretches to one on test environments in your initializer, but if you have an older application, this will yield a nice improvement!
2. Increase your log level
Add the following to your spec/test helper:
Rails.logger.level = 4
Explanation: Rails by default logs everything that is happening in your test environment to “log/test.log”. By increasing the logger level, you will be able to reduce the IO during your tests. The only downside of this approach is that, if a test is failing, you won’t have anything logged. In such cases, just comment the configuration option above and run your tests again.
3. Use shared connection with transactional fixtures
class ActiveRecord::Base mattr_accessor :shared_connection @@shared_connection = nil def self.connection @@shared_connection || retrieve_connection end end # Forces all threads to share the same connection. This works on # Capybara because it starts the web server in a thread. ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
Explanation: A long time ago, when Rails was still in 1.x branch, a new configuration option called
use_transactional_fixtures was added to Rails. This feature is very simple: before each test Active Record will issue a begin transaction statement and issue a rollback after the test is executed. This is awesome because Active Record will ensure that no data will be left in our database by simply using transactions, which is really, really fast.
use_transactional_fixtures and use Database Cleaner to clean up their database after each test. However, this affects your test suite performance badly.
The patch above, however, provides a very simple solution to both problems. It forces Active Record to share the same connection between all threads. This is not a problem in your test suite because when the test thread is running, there is no request in the server thread. When the server thread is running, the test thread is waiting for a response from the server. So it is unlikely that both will use the connection at the same time. Therefore, with the patch above, you no longer need to use Database Cleaner (unless you are using another database like Mongo) and, more importantly, you must turn
use_transactional_fixtures back to true, which will create a transaction wrapping both your test and server data, providing a great boost in your test suite performance.
Finally, if any part of your code is using threads to access the database and you need to test it, you can just set
ActiveRecord::Base.shared_connection = nil during that specific test and everything should work great!
That’s it! I hope you have enjoyed those tips and, if they helped you boost your test suite performance, please let us know in the comments the time your test suite took to run before and after those changes! Also, please share any tips you may have as well!